Implementação do Backpropagation
Abordagem Geral
Na propagação direta, cada camada l recebe as saídas da camada anterior, al−1, como entradas e calcula suas próprias saídas. Portanto, o método forward() da classe Layer recebe o vetor de saídas anteriores como seu único parâmetro, enquanto o restante das informações necessárias é armazenado dentro da classe.
Na propagação reversa, cada camada l precisa apenas de dal para calcular os respectivos gradientes e retornar dal−1, então o método backward() recebe o vetor dal como parâmetro. O restante das informações necessárias já está armazenado na classe Layer.
Derivadas das Funções de Ativação
Como as derivadas das funções de ativação são necessárias para a retropropagação, funções de ativação como ReLU e sigmoide devem ser implementadas como classes em vez de funções isoladas. Essa estrutura permite definir claramente ambos os componentes:
- A própria função de ativação — implementada usando o método
__call__(), podendo ser aplicada diretamente na classeLayercomself.activation(z); - Sua derivada — implementada usando o método
derivative(), permitindo o cálculo eficiente durante a retropropagação viaself.activation.derivative(z).
Representar funções de ativação como objetos facilita o repasse para diferentes camadas e a aplicação dinâmica durante a propagação direta e reversa.
ReLu
A derivada da função de ativação ReLU é a seguinte, onde zi é um elemento do vetor de pré-ativações z:
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoid
A derivada da função de ativação sigmoid é a seguinte:
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Para ambas as funções de ativação, a operação é aplicada a todo o vetor z, assim como à sua derivada. O NumPy realiza automaticamente o cálculo elemento a elemento, ou seja, cada elemento do vetor é processado de forma independente.
Por exemplo, se o vetor z contém três elementos, a derivada é calculada como:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)O método backward()
O método backward() é responsável por calcular os gradientes utilizando as fórmulas abaixo:
a^{l-1} e zl são armazenados como os atributos inputs e outputs na classe Layer, respectivamente. A função de ativação f é armazenada como o atributo activation.
Após todos os gradientes necessários serem calculados, os pesos e biases podem ser atualizados, pois não são mais necessários para cálculos posteriores:
Wlbl=Wl−α⋅dWl=bl−α⋅dblPortanto, learning_rate (α) é outro parâmetro deste método.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
O operador * realiza multiplicação elemento a elemento, enquanto a função np.dot() executa o produto escalar no NumPy. O atributo .T transpõe um array.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Incrível!
Completion taxa melhorada para 4
Implementação do Backpropagation
Deslize para mostrar o menu
Abordagem Geral
Na propagação direta, cada camada l recebe as saídas da camada anterior, al−1, como entradas e calcula suas próprias saídas. Portanto, o método forward() da classe Layer recebe o vetor de saídas anteriores como seu único parâmetro, enquanto o restante das informações necessárias é armazenado dentro da classe.
Na propagação reversa, cada camada l precisa apenas de dal para calcular os respectivos gradientes e retornar dal−1, então o método backward() recebe o vetor dal como parâmetro. O restante das informações necessárias já está armazenado na classe Layer.
Derivadas das Funções de Ativação
Como as derivadas das funções de ativação são necessárias para a retropropagação, funções de ativação como ReLU e sigmoide devem ser implementadas como classes em vez de funções isoladas. Essa estrutura permite definir claramente ambos os componentes:
- A própria função de ativação — implementada usando o método
__call__(), podendo ser aplicada diretamente na classeLayercomself.activation(z); - Sua derivada — implementada usando o método
derivative(), permitindo o cálculo eficiente durante a retropropagação viaself.activation.derivative(z).
Representar funções de ativação como objetos facilita o repasse para diferentes camadas e a aplicação dinâmica durante a propagação direta e reversa.
ReLu
A derivada da função de ativação ReLU é a seguinte, onde zi é um elemento do vetor de pré-ativações z:
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoid
A derivada da função de ativação sigmoid é a seguinte:
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Para ambas as funções de ativação, a operação é aplicada a todo o vetor z, assim como à sua derivada. O NumPy realiza automaticamente o cálculo elemento a elemento, ou seja, cada elemento do vetor é processado de forma independente.
Por exemplo, se o vetor z contém três elementos, a derivada é calculada como:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)O método backward()
O método backward() é responsável por calcular os gradientes utilizando as fórmulas abaixo:
a^{l-1} e zl são armazenados como os atributos inputs e outputs na classe Layer, respectivamente. A função de ativação f é armazenada como o atributo activation.
Após todos os gradientes necessários serem calculados, os pesos e biases podem ser atualizados, pois não são mais necessários para cálculos posteriores:
Wlbl=Wl−α⋅dWl=bl−α⋅dblPortanto, learning_rate (α) é outro parâmetro deste método.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
O operador * realiza multiplicação elemento a elemento, enquanto a função np.dot() executa o produto escalar no NumPy. O atributo .T transpõe um array.
Obrigado pelo seu feedback!