Regresión lineal simple en Keras

12

Después de analizar esta pregunta: Intentando emular la regresión lineal usando Keras , he intentado dar mi propio ejemplo, solo para estudiar y desarrollar mi intuición.

Descargué un conjunto de datos simple y usé una columna para predecir otra. Los datos se ven así:

datos de televisión

Ahora acabo de crear un modelo de keras simple con una sola capa lineal de un nodo y procedí a ejecutar un descenso de gradiente en ella:

from keras.layers import Input, Dense
from keras.models import Model

inputs = Input(shape=(1,))
preds = Dense(1,activation='linear')(inputs)

model = Model(inputs=inputs,outputs=preds)
sgd=keras.optimizers.SGD()
model.compile(optimizer=sgd ,loss='mse',metrics=['mse'])
model.fit(x,y, batch_size=1, epochs=30, shuffle=False)

Ejecutar el modelo así me da nanpérdidas en cada época.

Enlace al cuaderno jupyter

Así que decidí comenzar a probar cosas y solo obtengo un modelo decente si uso una tasa de aprendizaje ridículamente pequeña sgd=keras.optimizers.SGD(lr=0.0000001) :

Datos de televisión

Ahora, ¿por qué está pasando esto? ¿Tendré que ajustar manualmente la tasa de aprendizaje de esta manera para cada problema que enfrento? ¿Estoy haciendo algo mal aquí? Se supone que este es el problema más simple posible, ¿verdad?

¡Gracias!

Felipe Almeida
fuente

Respuestas:

11

Esto probablemente se deba a que no se realizó ninguna normalización . Las redes neuronales son muy sensibles a los datos no normalizados.

Alguna intuición: cuando intentamos encontrar nuestro mínimo global multidimensional (como en el modelo de descenso de gradiente estocástico), en cada iteración cada característica "atrae" a su dimensión (dirección del vector) con cierta fuerza (la longitud del vector ) Cuando los datos no se normalizan, un pequeño paso en el valor de la columna A puede causar un gran cambio en la columna B.

Su código hizo frente a eso usando su muy baja tasa de aprendizaje, que "normalizó" el efecto en cada columna, aunque causó un proceso de aprendizaje retrasado, que requirió muchas más épocas para terminar.

Agregue este código de normalización:

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
x = sc.fit_transform(x)
y = sc.fit_transform(y)

Y simplemente baje el parámetro de tasa de aprendizaje (lr), dejándolo elegir sabiamente un valor automático para usted. Tengo la misma tabla deseada que tú ahora :)

mork
fuente
Parece ordenado ... lo único que no me gusta es que necesitaré aplicar esta estandarización de manera similar para probar entradas y luego la salida que obtenga también estará en otro conjunto de unidades por completo.
Felipe Almeida
2
Así es @Felipe Almeida, el resultado de salida debe "revertirse", pero esto generalmente está integrado en las bibliotecas. Eche un vistazo a inverse_transform scikit-learn.org/stable/modules/generated/… y algunos otros métodos de preprocesamiento scikit-learn.org/stable/modules/preprocessing.html
mork
2

La normalización es más importante cuando tiene más de una variable dependiente. Si observa el diagrama de dispersión, puede ver valores atípicos. Una red neuronal sin capas ocultas es lo mismo que un modelo de regresión lineal. Por lo tanto, se ajusta a la mejor línea para minimizar la distancia de los residuos. Elimine los valores atípicos y se verá más apropiado.

Samuel Sherman
fuente