Estoy tratando de entender cómo se calculan los gradientes cuando se usa miinibatch SGD. Lo he implementado en el curso en línea CS231, pero solo me di cuenta de que en las capas intermedias el gradiente es básicamente la suma de todos los gradientes calculados para cada muestra (lo mismo para las implementaciones en Caffe o Tensorflow). Solo en la última capa (la pérdida) se promedian por el número de muestras. ¿Es esto correcto? Si es así, ¿significa que dado que en la última capa se promedian, al hacer backprop, todos los gradientes también se promedian automáticamente? ¡Gracias!

2
Roger Trullo 14 dic. 2016 a las 18:06

2 respuestas

La mejor respuesta

Es mejor entender primero por qué SGD funciona.

Normalmente, lo que es realmente una red neuronal, una función compuesta muy compleja de un vector de entrada x, una etiqueta y (o variable objetivo, cambia según si el problema es de clasificación o regresión) y algún vector de parámetros, w. Supongamos que estamos trabajando en la clasificación. En realidad, estamos tratando de hacer una estimación de máxima verosimilitud (en realidad, estimación MAP, ya que ciertamente vamos a usar la regularización L2 o L1, pero esto es demasiado tecnicismo por ahora) para el vector variable w. Suponiendo que las muestras son independientes; entonces tenemos la siguiente función de costo:

p(y1|w,x1)p(y2|w,x2) ... p(yN|w,xN)

Optimizar esta wrt a w es un desastre debido al hecho de que todas estas probabilidades se multiplican (esto producirá una derivada increíblemente complicada wrt w). En su lugar, usamos log probabilidades (tomar log no cambia los puntos extremos y lo dividimos por N, por lo que podemos tratar nuestro conjunto de entrenamiento como una distribución de probabilidad empírica, p (x))

J(X,Y,w)=-(1/N)(log p(y1|w,x1) + log p(y2|w,x2) + ... + log p(yN|w,xN))

Esta es la función de costo real que tenemos. Lo que realmente hace la red neuronal es modelar la función de probabilidad p (yi | w, xi). Puede ser una ResNet muy compleja de más de 1000 capas o simplemente un perceptrón simple.

Ahora, la derivada de w es simple de enunciar, ya que ahora tenemos una suma:

dJ(X,Y,w)/dw = -(1/N)(dlog p(y1|w,x1)/dw + dlog p(y2|w,x2)/dw + ... + dlog p(yN|w,xN)/dw)

Idealmente, lo anterior es el gradiente real. Pero este cálculo por lotes no es fácil de calcular. ¿Qué pasa si estamos trabajando en un conjunto de datos con 1 millón de muestras de entrenamiento? Peor aún, el conjunto de entrenamiento puede ser un flujo de muestras x, que tiene un tamaño infinito.

Aquí entra en juego la parte estocástica del SGD. Elija m muestras con m << N aleatoria y uniformemente del conjunto de entrenamiento y calcule la derivada usándolas:

 dJ(X,Y,w)/dw =(approx) dJ'/dw = -(1/m)(dlog p(y1|w,x1)/dw + dlog p(y2|w,x2)/dw + ... + dlog p(ym|w,xm)/dw)

Recuerde que teníamos una distribución de datos empírica (o real en el caso de un conjunto de entrenamiento infinito) p (x). La operación anterior de extraer m muestras de p (x) y promediarlas en realidad produce el estimador insesgado, dJ '/ dw, para la derivada real dJ (X, Y, w) / dw. Qué significa eso? Tome muchas de estas m muestras y calcule diferentes estimaciones de dJ '/ dw, promedielas también y obtendrá dJ (X, Y, w) / dw muy cerca, incluso exactamente, en el límite del muestreo infinito. Se puede demostrar que estas estimaciones de gradientes ruidosas pero no sesgadas se comportarán como el gradiente original a largo plazo. En promedio, SGD seguirá la ruta del gradiente real (pero puede atascarse en un mínimo local diferente, todo depende de la selección de la tasa de aprendizaje). El tamaño de minibatch m está directamente relacionado con el error inherente en la estimación ruidosa dJ '/ dw. Si m es grande, obtiene estimaciones de gradiente con baja varianza, puede usar tasas de aprendizaje mayores. Si m es pequeño om = 1 (aprendizaje en línea), la varianza del estimador dJ '/ dw es muy alta y debe usar tasas de aprendizaje más pequeñas, o el algoritmo puede divergir fácilmente fuera de control.

Ahora basta de teoría, tu pregunta real era

Solo en la última capa (la pérdida) se promedian por el número de muestras. ¿Es esto correcto? Si es así, ¿significa que dado que en la última capa se promedian, al hacer backprop, todos los gradientes también se promedian automáticamente? ¡Gracias!

Sí, es suficiente dividir por m en la última capa, ya que la regla de la cadena propagará el factor (1 / m) a todos los parámetros una vez que la capa más baja se multiplique por ella. No es necesario que lo haga por separado para cada parámetro, esto no será válido.

6
Ufuk Can Bicici 15 dic. 2016 a las 14:38

En la última capa se promedian y en la anterior se suman. Los gradientes sumados en capas anteriores se suman en diferentes nodos de la siguiente capa, no por los ejemplos. Este promedio se realiza solo para que el proceso de aprendizaje se comporte de manera similar cuando cambia el tamaño del lote; todo debería funcionar igual si suma todas las capas, pero disminuye la tasa de aprendizaje de manera adecuada.

2
sygi 14 dic. 2016 a las 15:13