Image: https://stats.stackexchange.com/questions/268202/backpropagation-algorithm-nn-with-rectified-linear-unit-relu-activation

ReLu — Lab

Marcos de Benedicto (Bene)
3 min readDec 23, 2024

ReLu é uma abreviação para “Rectified Linear Unit,” que é uma função de ativação amplamente utilizada em redes neurais artificiais, especialmente em aprendizado profundo. A função ReLu é definida matematicamente como:

f(x)=max⁡(0,x)

Ou seja, para um dado valor xx, a saída será 0 se xx for menor que 0, e será xx caso contrário. Isso significa que a função é linear para valores positivos de xx e “desliga” para valores negativos.

Por que usar ReLu?

ReLu oferece diversas vantagens:

  1. Simplicidade Computacional: É mais fácil de calcular do que funções como sigmoid ou tangente hiperbólica, pois não envolve operações exponenciais.
  2. Mitigação do Problema do Gradiente Desvanecido: Diferentemente de funções como sigmoid, que podem reduzir gradientes muito rapidamente, a ReLu permite que gradientes maiores passem durante a retropropagação, facilitando o aprendizado.
  3. Desempenho Melhorado: Em muitas arquiteturas de aprendizado profundo, o uso de ReLu resulta em uma convergência mais rápida e em melhores resultados.

Limitações

Apesar de suas vantagens, ReLu tem algumas limitações, como:

  • Problema de ReLu Morta: Se muitos neurônios recebem entradas negativas durante o treinamento, esses neurônios podem parar de atualizar seus pesos, ficando “mortos”.
  • Não é Diferenciável em x=0x = 0: Embora isso geralmente não seja um problema prático, pode ser uma consideração teórica.

Existem variantes da ReLu, como Leaky ReLu e Parametric ReLu, que tentam mitigar algumas dessas limitações permitindo pequenos gradientes mesmo para valores negativos.

LAB

Estrutura da Rede:

A rede possui 5 camadas: duas ocultas com ativação ReLU e uma camada de saída sem ativação. As dimensões de entrada, ocultas e saída são configuráveis. Inicialização dos Pesos e Biases:

Os pesos são inicializados aleatoriamente com distribuição normal (multiplicados por 0.1 para evitar explosões de valores). Os bias são inicializados como zeros. Forward Pass:

Calculamos as ativações camada por camada. A ReLU é aplicada nas camadas ocultas para introduzir não-linearidade. Resultado:

A saída é um array de valores (um para cada exemplo de entrada). Exemplos de Extensões: Adicionar uma função de custo e backpropagation para treinar a rede. Usar dados reais em vez de dados aleatórios. Substituir a última camada por uma ativação sigmoidal para problemas de classificação binária.

import numpy as np

# Definir a função ReLU
def relu(x):
return np.maximum(0, x)

# Definir a função de propagação para a rede neural
def forward_pass(X, weights, biases):
# Primeira camada
z1 = np.dot(X, weights['W1']) + biases['b1']
a1 = relu(z1)

# Segunda camada
z2 = np.dot(a1, weights['W2']) + biases['b2']
a2 = relu(z2)

# Camada de saída
z3 = np.dot(a2, weights['W3']) + biases['b3']
a3 = relu(z3)

#Camada de saída
z4 = np.dot(a3, weights['W4']) + biases['b4']
a4 = relu(z4)

#Camada de saída
z5 = np.dot(a4, weights['W5']) + biases['b5']
output = z5 # Sem ativação na saída para este exemplo (regressão)

return output

# Inicializar os pesos e os bias
def initialize_parameters(input_dim, hidden_dim1, hidden_dim2, hidden_dim3, hidden_dim4, output_dim):
np.random.seed(42) # Para reprodução
weights = {
'W1': np.random.randn(input_dim, hidden_dim1) * 0.1,
'W2': np.random.randn(hidden_dim1, hidden_dim2) * 0.1,
'W3': np.random.randn(hidden_dim2, hidden_dim3) * 0.1,
'W4': np.random.randn(hidden_dim3, hidden_dim4) * 0.1,
'W5': np.random.randn(hidden_dim4, output_dim) * 0.1
}
biases = {
'b1': np.zeros((1, hidden_dim1)),
'b2': np.zeros((1, hidden_dim2)),
'b3': np.zeros((1, hidden_dim3)),
'b4': np.zeros((1, hidden_dim4)),
'b5': np.zeros((1, output_dim))
}
return weights, biases

# Gerar dados de entrada
np.random.seed(0)
X = np.random.rand(10, 2) # 10 exemplos, 2 características

# Configurar a arquitetura da rede
input_dim = 2
hidden_dim1 = 7
hidden_dim2 = 5
hidden_dim3 = 3
hidden_dim4 = 4
output_dim = 1

# Inicializar os parâmetros
weights, biases = initialize_parameters(input_dim, hidden_dim1, hidden_dim2, hidden_dim3, hidden_dim4, output_dim)

# Fazer a propagação direta
output = forward_pass(X, weights, biases)

# Exibir os resultados
print("Entrada:")
print(X)
print("\nSaída da Rede Neural:")
print(output)

Mais exemplos: https://www.youtube.com/watch?v=6MmGNZsA5nI

--

--

No responses yet