A menudo leo que en el caso de los modelos de Deep Learning, la práctica habitual es aplicar mini lotes (generalmente uno pequeño, 32/64) durante varias épocas de entrenamiento. Realmente no puedo entender la razón detrás de esto.
A menos que me equivoque, el tamaño del lote es el número de instancias de entrenamiento que el modelo puede ver durante una iteración de entrenamiento; y época es un turno completo cuando el modelo ha visto cada una de las instancias de entrenamiento. Si es así, no puedo ver la ventaja de iterar sobre un subconjunto casi insignificante de las instancias de entrenamiento varias veces en contraste con la aplicación de un "lote máximo" al exponer todas las instancias de entrenamiento disponibles en cada turno al modelo (suponiendo, por supuesto, suficiente la memoria). ¿Cuál es la ventaja de este enfoque?
fuente
Respuestas:
La ventaja clave de usar minibatch en lugar del conjunto de datos completo se remonta a la idea fundamental del descenso de gradiente estocástico 1 .
En el descenso de gradiente por lotes, se calcula el gradiente en todo el conjunto de datos, promediando potencialmente una gran cantidad de información. Se necesita mucha memoria para hacer eso. Pero la desventaja real es la trayectoria del gradiente del lote que te lleva a un mal lugar (punto de silla de montar).
En SGD puro, por otro lado, actualiza sus parámetros agregando (signo menos) el gradiente calculado en una sola instancia del conjunto de datos. Como se basa en un punto de datos aleatorio, es muy ruidoso y puede ir en una dirección lejos del gradiente de lote. Sin embargo, el ruido es exactamente lo que desea en la optimización no convexa, porque lo ayuda a escapar de los puntos de silla de montar o los mínimos locales (Teorema 6 en [2]). La desventaja es que es terriblemente ineficiente y necesita recorrer todo el conjunto de datos muchas veces para encontrar una buena solución.
La metodología del minibatch es un compromiso que inyecta suficiente ruido a cada actualización de gradiente, al tiempo que logra una convergencia relativamente rápida.
1 Bottou, L. (2010). Aprendizaje automático a gran escala con descenso de gradiente estocástico. En Actas de COMPSTAT'2010 (pp. 177-186). Physica-Verlag HD.
[2] Ge, R., Huang, F., Jin, C. y Yuan, Y. (2015, junio). Escaping From Saddle Points-Online Stochastic Gradient for Tensor Decomposition. En COLT (pp. 797-842).
EDITAR:
Acabo de ver este comentario en el facebook de Yann LeCun, que ofrece una nueva perspectiva sobre esta pregunta (lo siento, no sé cómo vincular a fb).
Citó este documento que acaba de publicarse en arXiv hace unos días (abril de 2018), que vale la pena leer,
Dominic Masters, Carlo Luschi, Revisiting Small Batch Training for Deep Neural Networks , arXiv: 1804.07612v1
Del resumen,
fuente
La memoria no es realmente la razón para hacer esto, porque podría acumular sus gradientes a medida que recorre el conjunto de datos y aplicarlos al final, pero aún en SGD los aplica en cada paso.
Las razones por las cuales SGD se usa tan ampliamente son:
1) Eficiencia. Por lo general, especialmente al principio del entrenamiento, los gradientes de parámetros para diferentes subconjuntos de datos tenderán a apuntar en la misma dirección. Por lo tanto, los gradientes evaluados en 1/100 de los datos apuntarán aproximadamente en la misma dirección general que en el conjunto de datos completo, pero solo requieren 1/100 del cálculo. Dado que la convergencia en una red profunda altamente no lineal generalmente requiere miles o millones de iteraciones, sin importar cuán buenos sean sus gradientes, tiene sentido hacer muchas actualizaciones basadas en estimaciones baratas del gradiente en lugar de pocas actualizaciones basadas en buenas.
2) Optimización: las actualizaciones ruidosas pueden permitirle salir de los óptimos locales malos (aunque no tengo una fuente que muestre que esto es importante en la práctica).
3) Generalización. Parece (ver Zhang et al: Theory of Deep Learning III: Generalization Properties of SGD ) que SGD realmente ayuda a la generalización al encontrar mínimos "planos" en el conjunto de entrenamiento, que es más probable que también sean mínimos en el conjunto de prueba. Intuitivamente, podemos pensar en el SGD como una especie de embolsado : al calcular nuestros parámetros basados en muchos minibatches de datos, reforzamos las reglas que se generalizan entre los minibatches y cancelamos las reglas que no lo hacen, lo que nos hace menos propensos a sobreajustarnos. conjunto de entrenamiento.
fuente
Correcto (aunque lo llamaría "paso de actualización de peso")
Correcto
Bueno, más o menos eso. Usualmente no tienes suficiente memoria. Digamos que estamos hablando de clasificación de imágenes. ImageNet es un conjunto de datos muy popular. Durante bastante tiempo, VGG-16D fue uno de los mod.els más populares. Necesita calcular 15 245 800 flotadores (en los mapas de características) para una imagen de 224x224. Esto significa unos 61 MB por imagen. Esto es solo un límite inferior aproximado de la cantidad de memoria que necesita durante el entrenamiento para cada imagen. ImageNet contiene varios miles (¿creo que 1.2 millones?) De imágenes. Si bien es posible que tenga tanta memoria principal, ciertamente no tiene tanta memoria de GPU. He visto que la GPU acelera las cosas a aproximadamente 21x. Así que definitivamente quieres usar la GPU.
Además: el tiempo para un mini lote es mucho menor. Entonces, la pregunta es: ¿Preferiría hacer n pasos de actualización con mini lote por hora en una GPU o m pasos de actualización con lote sin GPU, donde n >> m.
fuente
Aparte de las otras respuestas, creo que vale la pena señalar que hay dos cantidades que son distintas pero que a menudo están acopladas:
Como otros han señalado, el gradiente con respecto a un minibatch es una aproximación del gradiente verdadero. Cuanto más grande sea el minibatch, mejor será la aproximación.
La compensación aquí es puramente sobre el rendimiento (memoria / ciclos).
Estas cantidades son típicamente las mismas, es decir, el tamaño del minibatch, pero en principio se pueden desacoplar.
fuente