neural-network - multilayer - neural network error back propagation
Backpropagation red neuronal con RELU (5)
Estoy tratando de implementar la red neuronal con RELU.
capa de entrada -> 1 capa oculta -> relu -> capa de salida -> capa softmax
Arriba está la arquitectura de mi red neuronal. Estoy confundido acerca de la propagación hacia atrás de esta relu. Para la derivada de RELU, si x <= 0, la salida es 0. si x> 0, la salida es 1. Entonces, al calcular el gradiente, ¿eso significa que mato el gradiente decente si x <= 0?
¿Puede alguien explicar la propagación hacia atrás de mi arquitectura de red neuronal ''paso a paso''?
si x <= 0, la salida es 0. Si x> 0, la salida es 1
La función ReLU se define como: Para x> 0, la salida es x, es decir, f (x) = max (0, x)
Así que para la derivada f ''(x) es en realidad:
si x <0, la salida es 0. Si x> 0, la salida es 1.
La derivada f ''(0) no está definida. Por lo general, se establece en 0 o modifica la función de activación para que sea f (x) = max (e, x) para una pequeña e.
Generalmente: una ReLU es una unidad que utiliza la función de activación del rectificador. Eso significa que funciona exactamente como cualquier otra capa oculta, pero excepto en tanh (x), sigmoid (x) o cualquier activación que use, en su lugar usará f (x) = max (0, x).
Si ha escrito código para una red multicapa en funcionamiento con activación sigmoide, es literalmente 1 línea de cambio. Nada acerca de los cambios de propagación hacia adelante o hacia atrás de forma algorítmica. Si aún no tienes el modelo más simple funcionando, vuelve y comienza con ese primero. De lo contrario, su pregunta no es realmente sobre ReLUs, sino sobre la implementación de una NN como un todo.
Además, aquí puede encontrar una implementación en caffe framework: https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp
La línea pendiente negativa especifica si se "filtra" la parte negativa multiplicándola con el valor de la pendiente en lugar de establecerla en 0. Por supuesto, debe establecer este parámetro en cero para tener una versión clásica.
Este es un buen ejemplo, use ReLU para implementar XOR: reference, http://pytorch.org/tutorials/beginner/pytorch_with_examples.html
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
# N is batch size(sample size); D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 4, 2, 30, 1
# Create random input and output data
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# Randomly initialize weights
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 0.002
loss_col = []
for t in range(200):
# Forward pass: compute predicted y
h = x.dot(w1)
h_relu = np.maximum(h, 0) # using ReLU as activate function
y_pred = h_relu.dot(w2)
# Compute and print loss
loss = np.square(y_pred - y).sum() # loss function
loss_col.append(loss)
print(t, loss, y_pred)
# Backprop to compute gradients of w1 and w2 with respect to loss
grad_y_pred = 2.0 * (y_pred - y) # the last layer''s error
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T) # the second laye''s error
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0 # the derivate of ReLU
grad_w1 = x.T.dot(grad_h)
# Update weights
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
plt.plot(loss_col)
plt.show()
Más sobre el derivado de ReLU, puede ver aquí: http://kawahara.ca/what-is-the-derivative-of-relu/
Sí, la función original de Relu tiene el problema que usted describe. Así que más tarde hicieron un cambio a la fórmula, y lo llamaron con fugas Relu En esencia, Leaky Relu inclina la parte horizontal de la función ligeramente en una cantidad muy pequeña. para más información mira esto:
Una explicación de los métodos de activación y una versión mejorada de YouTube en YouTube.
Si tiene una capa hecha de una sola ReLU, como sugiere su arquitectura, entonces sí, mata el gradiente en 0
. Durante el entrenamiento, la ReLU devolverá 0
a su capa de salida, que devolverá 0
o 0.5
si está utilizando unidades logísticas, y el softmax las aplastará. Por lo tanto, un valor de 0
en su arquitectura actual tampoco tiene mucho sentido para la parte de propagación hacia adelante.
Vea por ejemplo this . Lo que puede hacer es usar una "ReLU con fugas", que es un valor pequeño en 0
, como 0.01
.
Sin embargo, reconsideraría esta arquitectura, no tiene mucho sentido para mí alimentar una sola ReLU en un grupo de otras unidades y luego aplicar un softmax.