python - network - Backpropagation con unidades lineales rectificadas
backpropagation python (1)
He escrito un código para implementar la retropropagación en una red neuronal profunda con la función de activación logística y salida de softmax.
def backprop_deep(node_values, targets, weight_matrices):
delta_nodes = node_values[-1] - targets
delta_weights = delta_nodes.T.dot(node_values[-2])
weight_updates = [delta_weights]
for i in xrange(-2, -len(weight_matrices)- 1, -1):
delta_nodes = dsigmoid(node_values[i][:,:-1]) * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
delta_weights = delta_nodes.T.dot(node_values[i-1])
weight_updates.insert(0, delta_weights)
return weight_updates
El código funciona bien, pero cuando cambié a ReLU como la función de activación, dejó de funcionar. En la rutina backprop solo cambio la derivada de la función de activación:
def backprop_relu(node_values, targets, weight_matrices):
delta_nodes = node_values[-1] - targets
delta_weights = delta_nodes.T.dot(node_values[-2])
weight_updates = [delta_weights]
for i in xrange(-2, -len(weight_matrices)- 1, -1):
delta_nodes = (node_values[i]>0)[:,:-1] * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
delta_weights = delta_nodes.T.dot(node_values[i-1])
weight_updates.insert(0, delta_weights)
return weight_updates
Sin embargo, la red ya no aprende, y los pesos rápidamente van a cero y permanecen allí. Estoy totalmente perplejo.
Aunque he determinado el origen del problema, voy a dejar esto en caso de que sea beneficioso para otra persona.
El problema fue que no ajusté la escala de los pesos iniciales cuando cambié las funciones de activación. Mientras que las redes logísticas aprenden muy bien cuando las entradas de los nodos son casi cero y la función logística es aproximadamente lineal, las redes ReLU aprenden bien para las entradas moderadamente grandes a los nodos. Por lo tanto, la inicialización de bajo peso utilizada en las redes logísticas no es necesaria y, de hecho, nociva. El comportamiento que estaba viendo era que la red ReLU ignoraba las características e intentaba aprender el sesgo del conjunto de entrenamiento exclusivamente.
Actualmente estoy usando pesos iniciales distribuidos uniformemente de -5 a .5 en el conjunto de datos MNIST, y está aprendiendo muy rápido.