El entrenamiento de una red neuronal para la regresión siempre predice la media

9

Estoy entrenando una red neuronal convolucional simple para la regresión, donde la tarea es predecir la ubicación (x, y) de un cuadro en una imagen, por ejemplo:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

La salida de la red tiene dos nodos, uno para xy otro para y. El resto de la red es una red neuronal convolucional estándar. La pérdida es un error cuadrático medio estándar entre la posición predicha de la caja y la posición de verdad del suelo. Estoy entrenando en 10000 de estas imágenes y validando en 2000.

El problema que tengo es que, incluso después de un entrenamiento significativo, la pérdida realmente no disminuye. Después de observar la salida de la red, noto que la red tiende a generar valores cercanos a cero, para ambos nodos de salida. Como tal, la predicción de la ubicación del cuadro siempre es el centro de la imagen. Hay alguna desviación en las predicciones, pero siempre alrededor de cero. A continuación se muestra la pérdida:

ingrese la descripción de la imagen aquí

He ejecutado esto durante muchas más épocas de las que se muestran en este gráfico, y la pérdida aún nunca disminuye. Curiosamente aquí, la pérdida en realidad aumenta en un punto.

Entonces, parece que la red solo está prediciendo el promedio de los datos de entrenamiento, en lugar de aprender un buen ajuste. ¿Alguna idea de por qué esto puede ser? Estoy usando a Adam como optimizador, con una tasa de aprendizaje inicial de 0.01, y relus como activaciones


Si está interesado en algo de mi código (Keras), está a continuación:

# Create the model
model = Sequential()
model.add(Convolution2D(32, 5, 5, border_mode='same', subsample=(2, 2), activation='relu', input_shape=(3, image_width, image_height)))
model.add(Convolution2D(64, 5, 5, border_mode='same', subsample=(2, 2), activation='relu'))
model.add(Convolution2D(128, 5, 5, border_mode='same', subsample=(2, 2), activation='relu'))
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(2, activation='linear'))


# Compile the model
adam = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='mean_squared_error', optimizer=adam)


# Fit the model
model.fit(images, targets, batch_size=128, nb_epoch=1000, verbose=1, callbacks=[plot_callback], validation_split=0.2, shuffle=True)
Karnivaurus
fuente
¿Son las imágenes en los mejores ejemplos de sus muestras reales? ¿Son 5 muestras separadas? Parece que no hay información en las imágenes que pueda ayudar a generalizar. Quiero decir, no necesitas una red neuronal para encontrar la ubicación x, y del cuadrado blanco, solo puedes analizar la imagen y buscar un píxel blanco. Explica un poco más sobre tu visión para este modelo. ¿Hay algún patrón temporal en el que prediga la próxima ubicación?
photox
Hola, y sí, las imágenes son 5 muestras separadas. No estoy seguro de cómo se representan para usted, pero deberían ser 5 imágenes cuadradas individuales (he cambiado un poco el diseño para ayudar ...). Sí, me doy cuenta de que no necesita una red neuronal para esta tarea, pero es solo un experimento de prueba que me ayuda a aprender cómo hacer una regresión con una red neuronal. No entiendo lo que quieres decir con que no hay información para ayudar a generalizar ... Cada par de entrenamiento consiste en una imagen cuadrada y un vector bidimensional de la ubicación (x, y) del cuadrado. Gracias :)
Karnivaurus
1
1) Su forma de entrada en la primera capa conv utiliza 3 canales (rbg), pero sus datos son en escala de grises (1 canal) 2) No necesita tantas capas y filtros conv, de hecho creo que una sola capa, y un puñado de granos pequeños estará bien.
photox
¿Estás seguro de que las imágenes corresponden a los objetivos?
user31264
1
Como dice @photox, no necesita las capas de conv. Agregar estos hace que sea más difícil para el optimizador encontrar una buena solución. Si elimina las 3 capas conv, sospecho que su "modelo" funcionará.
Pieter

Respuestas:

9

El optimizador no puede converger a una solución (sub) óptima. ¿Por qué? Su problema es demasiado fácil y / o su modelo es demasiado complejo.

Problema demasiado fácil

Como @photox ya dijo, este problema se puede resolver con una sola capa oculta. Incluso sospecho que se puede hacer sin una capa oculta. Esto se debe a que este problema es lineal separable .

Déjame ilustrar esto. Imagine una red neuronal sin capas ocultas y una función de activación lineal (también podría llamarse regresión lineal). Para calcular la ubicación x del cuadrado, cada píxel se conecta a la salida x. La primera columna de píxeles está conectada con el peso . La segunda columna está conectada con el peso . Esto continúa hasta la última columna (por ejemplo, la columna ) que está conectada con el peso . Desde2 / alto ancho n n / alto ancho alto ancho1/ /altura/ /anchura2/ /alturaanchuranortenorte/ /alturaanchuraalturaanchuralos píxeles no son cero (por ejemplo, el sesgo es igual al valor del color gris), la activación de la salida x es igual al centro del cuadrado. Por lo tanto, una función lineal puede calcular la ubicación del cuadrado.

Hay varias soluciones:

  • Elija un problema más difícil, por ejemplo, clasificación de imágenes.
  • Agregue ruido, por ejemplo, sal y pimienta o ruido blanco
  • Haga el problema más difícil, por ejemplo, al predecir la ubicación de un cuadrado rojo mientras hay muchos círculos de diferentes colores en el fondo

Modelo demasiado complejo

Su modelo tiene algunas partes que agregan mucha complejidad sin ayudar al optimizador a encontrar un óptimo óptimo.

Por ejemplo, las capas convolucionales. La primera capa tiene 32 filtros convolucionales de tamaño . ¿Qué esperas que aprendan estos filtros? En la clasificación de imágenes, estos filtros aprenden a detectar bordes, esquinas, degradados y manchas. Pero en este caso solo hay unos pocos filtros que tienen sentido. Puedo pensar en el borde de izquierda a derecha y viceversa y de arriba a abajo y viceversa. En su caso, existen aproximadamente 28 filtros que solo agregan ruido aleatorio. Eliminarlos (o solo la capa completa) hace que sea mucho más fácil para el optimizador encontrar un óptimo que funcione.5 5×5 5

Otro ejemplo es el optimizador Adam con muchos parámetros adicionales. El optimizador Adam podría funcionar bien con estos parámetros, pero ¿por qué no comenzar con un simple SGDoptimizador con valores predeterminados?

Por lo tanto, puede hacer varias optimizaciones:

  • uso LinearRegressionde scikit-learn. OK, esto no es lo que quieres, pero solo quiero ilustrar cuán excesivamente complejo es este modelo.
  • Eliminar las capas conv
  • Disminuya el tamaño de las Densecapas ocultas.
  • Use el SGDoptimizador predeterminado
  • Si está utilizando una capa oculta, debe intentar una sigmoidactivación. Puede pensar que cada uno de los nodos de la capa oculta detecta si un cuadrado está en una ubicación determinada.
  • Si todo esto no funciona, experimente un poco la tasa de aprendizaje para saber si es demasiado alta o demasiado baja.

PD

Creo que te gustará esta publicación de blog de Adit Deshpande.

Pieter
fuente
Avíseme si estas soluciones cambiaron el comportamiento de los optimizadores.
Pieter
Gracias, eso es muy útil. Estoy trabajando para probar tus sugerencias. Sin embargo, no entiendo tu primer punto. No sé por qué, si el problema es demasiado simple, entonces es más difícil de optimizar que un problema más complejo. Para una red determinada, ¿por qué un problema más simple sería más difícil de optimizar que un problema más complejo? En un problema simple, habría pensado que habría gradientes muy fuertes y un óptimo global fuerte. Sin embargo, su primer punto dice que la simplicidad del problema hace que la optimización duro, lo que sugiere que un problema más complejo ayudaría a la optimización ...
Karnivaurus
0

Parece un problema típico de sobreajuste. Sus datos no proporcionan suficiente información para obtener el mejor resultado. Eliges el NN complejo con tu tren para recordar todos los matices de los datos del tren . La pérdida nunca puede ser un cero, como está en su gráfico. Por cierto, parece que su validación tiene un error o el conjunto de validación no es bueno para la validación porque la pérdida de validación también se está volviendo cero.

Leonid Ganeline
fuente
44
La pregunta dice que la red casi siempre genera cero. Ese sería un caso de ropa interior severa , no sobreajustada. Tampoco hay una brecha entre la formación y el error de validación en la curva de aprendizaje, lo que indica que el sobreajuste no es el problema (el error no es cero, la escala es logarítmica)
user20160
0

Estoy enfrentando el mismo problema con mi conjunto de datos. Resulta que en mi caso los predictores están altamente concentrados con una variación muy pequeña. Debe verificar la varianza de sus variables de predicción y ver cómo se distribuye.Distribución de la variable que intento predecir

Sin embargo, algunas transformaciones en la variable de salida se pueden realizar para modificar o cambiar su escala. Esto podría resultar en una distribución de tipo más uniforme. Por ejemplo, en las tareas de reconocimiento de imágenes, la ecualización del histograma o la mejora del contraste a veces funcionan a favor de la toma de decisiones correcta.

Ravi Shankar
fuente
-1

En realidad estaba trabajando en un problema muy similar. Básicamente, tenía un montón de puntos sobre un fondo blanco y estaba entrenando a un NN para reconocer el punto que se colocó primero en el fondo. La forma en que encontré que funcionaba era usar una capa de neuronas completamente conectadas (es decir, una NN de 1 capa). Por ejemplo, para una imagen de 100x100, tendría 10.000 neuronas de entrada (los píxeles) conectadas directamente a 2 neuronas de salida (las coordenadas). En PyTorch, cuando convertí los valores de píxeles a un tensor, estaba normalizando mis datos automáticamente, restando la media y dividiendo por la desviación estándar. En problemas normales de aprendizaje automático, esto está bien, pero no para una imagen en la que puede haber una disparidad en la cantidad de píxeles coloreados en una imagen (es decir, la suya donde solo hay unos pocos píxeles blancos). Entonces, Normalicé manualmente dividiendo todos los valores de intensidad de píxeles por 255 (por lo que ahora están en el rango de 0-1 sin la técnica de normalización típica que intenta ajustar todos los valores de intensidad a una distribución normal). Entonces, todavía tenía problemas porque predecía la coordenada promedio de los píxeles en el conjunto de entrenamiento. Entonces, mi solución fue establecer una tasa de aprendizaje muy alta, que va en contra de casi todos los instructores y tutoriales de ML. En lugar de usar 1e-3, 1e-4, 1e-5, como dice la mayoría de la gente, estaba usando una tasa de aprendizaje de 1 o 0.1 con descenso de gradiente estocástico. Esto solucionó mis problemas y mi red finalmente aprendió a memorizar mi conjunto de entrenamiento. No se generaliza demasiado bien a un conjunto de pruebas, pero al menos funciona, lo cual es una mejor solución que la mayoría de los demás sugirió en su pregunta. ahora está en el rango de 0-1 sin la técnica de normalización típica que intenta ajustar todos los valores de intensidad a una distribución normal). Entonces, todavía tenía problemas porque predecía la coordenada promedio de los píxeles en el conjunto de entrenamiento. Entonces, mi solución fue establecer una tasa de aprendizaje muy alta, que va en contra de casi todos los instructores y tutoriales de ML. En lugar de usar 1e-3, 1e-4, 1e-5, como dice la mayoría de la gente, estaba usando una tasa de aprendizaje de 1 o 0.1 con descenso de gradiente estocástico. Esto solucionó mis problemas y mi red finalmente aprendió a memorizar mi conjunto de entrenamiento. No se generaliza demasiado bien a un conjunto de pruebas, pero al menos funciona, lo cual es una mejor solución que la mayoría de los demás sugirió en su pregunta. ahora está en el rango de 0-1 sin la técnica de normalización típica que intenta ajustar todos los valores de intensidad a una distribución normal). Entonces, todavía tenía problemas porque predecía la coordenada promedio de los píxeles en el conjunto de entrenamiento. Entonces, mi solución fue establecer una tasa de aprendizaje muy alta, que va en contra de casi todos los instructores y tutoriales de ML. En lugar de usar 1e-3, 1e-4, 1e-5, como dice la mayoría de la gente, estaba usando una tasa de aprendizaje de 1 o 0.1 con descenso de gradiente estocástico. Esto solucionó mis problemas y mi red finalmente aprendió a memorizar mi conjunto de entrenamiento. No se generaliza demasiado bien a un conjunto de pruebas, pero al menos funciona, lo cual es una mejor solución que la mayoría de los demás sugirió en su pregunta.

Beto
fuente