Blog
Reducir el sobreajuste con la regularización de la Deserción
- Publicado por: Rafael Fernandez
- Categoría: Deep Learning
-En esta lección descubrirás la técnica de regularización del abandono y cómo aplicarla a tus modelos en Python con Keras.
-Cómo funciona la técnica de regularización del abandono escolar.
-Cómo utilizar la función "droppout" en las capas de entrada.
-Cómo usar el dropout en tus capas ocultas.
Una técnica de regularización simple y poderosa para redes neuronales y modelos de aprendizaje profundo es la deserción.
Regularización de la deserción en redes neuronales
La deserción es una técnica de regularización para modelos de redes neuronales propuesta en varios artículos de investigación y es una manera sencilla de evitar que las redes neuronales se saturen.
El abandono es una técnica en la que las neuronas seleccionadas al azar son ignoradas durante el entrenamiento. Ellas se abandonan al azar. Esto significa que su contribución a la activación de las neuronas aguas abajo se elimina temporalmente en el pase directo y las actualizaciones de peso no se aplican a la neurona en el pase hacia atrás.
A medida que una red neuronal aprende, los pesos de las neuronas se establecen en su contexto dentro de la red. Los pesos de las neuronas están sintonizados para características específicas que proporcionan cierta especialización. Las neuronas vecinas confían en esta especialización, que si se lleva demasiado lejos puede resultar en un modelo frágil y demasiado especializado para los datos de entrenamiento. Esta dependencia del contexto para una neurona durante el entrenamiento se conoce como co-adaptaciones complejas. Puedes imaginarte que si las neuronas son abandonadas aleatoriamente de la red durante el entrenamiento, otras neuronas tendrán que intervenir y manejar la representación requerida para hacer predicciones de las neuronas perdidas. Se cree que esto resulta en múltiples representaciones internas independientes aprendidas por la red. El efecto es que la red se vuelve menos sensible a los pesos específicos de las neuronas. Esto a su vez da como resultado una red que es capaz de una mejor generalización y es menos probable que sobreajuste los datos de entrenamiento.
Regularización de la deserción en Keras
La deserción se implementa fácilmente seleccionando aleatoriamente los nodos que se van a desertar con un valor de probabilidad (por ejemplo, 20%) de cada ciclo de actualización de peso. Así es como se implementa la deserción en Keras. La deserción se usa solamente durante el entrenamiento de un modelo y no se usa cuando se evalúa la habilidad del modelo. A continuación exploraremos algunas formas diferentes de usar deserción en Keras.
Los ejemplos usarán el conjunto de datos de clasificaciones binarias de Sonar (más información en este post). Evaluaremos los modelos desarrollados utilizando scikit-learn con una validación cruzada de 10 veces, con el fin de desentrañar mejor las diferencias en los resultados. Hay 60 valores de entrada y un solo valor de salida, los valores de entrada se estandarizan antes de ser utilizados en la red. El modelo de red neural de línea base tiene dos capas ocultas, la primera con 60 unidades y la segunda con 30. El descenso de gradiente estocástico se utiliza para entrenar el modelo con un aprendizaje relativamente bajo en ritmo e ímpetu. El modelo de línea de base completo se enumera a continuación.
# Baseline Modelo con los datos del Sonar import numpy from pandas import read_csv from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from keras.optimizers import SGD from sklearn.model_selection import cross_val_score from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import StratifiedKFold from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline # semilla aleatoria para reproducibilidad seed = 7 numpy.random.seed(seed) # cargamos el dataset dataframe = read_csv("sonar.csv", header=None) dataset = dataframe.values # dividido en variables de entrada (X) y salida (Y) X = dataset[:,0:60].astype(float) Y = dataset[:,60] # codificar valores de clase como enteros encoder = LabelEncoder() encoder.fit(Y) encoded_Y = encoder.transform(Y) # baseline def create_baseline(): # creacion del modelo model = Sequential() model.add(Dense(60, input_dim=60, kernel_initializer='normal', activation='relu')) model.add(Dense(30, kernel_initializer='normal', activation='relu')) model.add(Dense(1, kernel_initializer='normal', activation='sigmoid')) # Compila el modelo sgd = SGD(lr=0.01, momentum=0.8, decay=0.0, nesterov=False) model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy']) return model numpy.random.seed(seed) estimators = [] estimators.append(('standardize', StandardScaler())) estimators.append(('mlp', KerasClassifier(build_fn=create_baseline, epochs=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Ejecutar el ejemplo para el modelo de referencia sin deserción genera una precisión de clasificación estimada del 82%.
Baseline: 82.14% (7.30%)
Uso de la deserción en la Capa Visible
Se puede aplicar a las neuronas de entrada llamadas capa visible. En el siguiente ejemplo añadimos una nueva capa de caída entre la entrada (o capa visible) y la primera capa oculta. La deserción se establece en 20%, lo que significa que 1 de cada 5 entradas se excluirá aleatoriamente de cada ciclo de actualización.
Además, como se recomendaba en el documento original sobre la deserción, se impone una limitación a los pesos para cada capa oculta, asegurándose de que la norma máxima de los pesos no exceden un valor de 3. Esto se hace estableciendo el argumento de restricción del kernel_constraint en el parámetro Dense class al construir las capas. El ritmo de aprendizaje se elevó en un orden de magnitud y el impulso se incrementó a 0,9. Continuando con el ejemplo de la línea de base anterior, el código a continuación ejerce la misma red con la salida de entrada.
# Baseline Modelo con los datos del Sonar: Capa Visible import numpy from pandas import read_csv from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout from keras.wrappers.scikit_learn import KerasClassifier from keras.constraints import maxnorm from keras.optimizers import SGD from sklearn.model_selection import cross_val_score from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import StratifiedKFold from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline # semilla aleatoria para reproducibilidad seed = 7 numpy.random.seed(seed) # cargamos el dataset dataframe = read_csv("sonar.csv", header=None) dataset = dataframe.values # dividido en variables de entrada (X) y salida (Y) X = dataset[:,0:60].astype(float) Y = dataset[:,60] # codificar valores de clase como enteros encoder = LabelEncoder() encoder.fit(Y) encoded_Y = encoder.transform(Y) # baseline def create_model(): # creacion del modelo model = Sequential() model.add(Dropout(0.2, input_shape=(60,))) model.add(Dense(60, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3))) model.add(Dense(30, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3))) model.add(Dense(1, kernel_initializer='normal', activation='sigmoid')) # Compila el modelo sgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False) model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy']) return model numpy.random.seed(seed) estimators = [] estimators.append(('standardize', StandardScaler())) estimators.append(('mlp', KerasClassifier(build_fn=create_model, epochs=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print("Visible: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
La ejecución del ejemplo proporciona un pequeño descenso en la precisión de la clasificación, al menos en una sola ejecución de prueba.
Visible: 83.04% (8.94%)
Uso de la Deserción en Capas Ocultas
El abandono se puede aplicar a las neuronas ocultas en el cuerpo de su modelo de red. En el ejemplo de abajo, la pérdida de señal se aplica entre las dos capas ocultas y entre la última capa oculta y la capa de salida. Una vez más, se utiliza una tasa de abandono del 20%, así como una limitación de peso en esas capas.
# Ejemplo de desercion con los datos del sonar: Capa oculta import numpy from pandas import read_csv from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout from keras.wrappers.scikit_learn import KerasClassifier from keras.constraints import maxnorm from keras.optimizers import SGD from sklearn.model_selection import cross_val_score from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import StratifiedKFold from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline # semilla aleatoria para reproducibilidad seed = 7 numpy.random.seed(seed) # cargamos el dataset dataframe = read_csv("sonar.csv", header=None) dataset = dataframe.values # dividido en variables de entrada (X) y salida (Y) X = dataset[:,0:60].astype(float) Y = dataset[:,60] # codificar valores de clase como enteros encoder = LabelEncoder() encoder.fit(Y) encoded_Y = encoder.transform(Y) # desercion en capas ocultas con restricción de peso def create_model(): # creacion del modelo model = Sequential() model.add(Dense(60, input_dim=60, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3))) model.add(Dropout(0.2)) model.add(Dense(30, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3))) model.add(Dropout(0.2)) model.add(Dense(1, kernel_initializer='normal', activation='sigmoid')) # Compilacion del modelo sgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False) model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy']) return model numpy.random.seed(seed) estimators = [] estimators.append(('standardize', StandardScaler())) estimators.append(('mlp', KerasClassifier(build_fn=create_model, epochs=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print("Oculta: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100)
Podemos ver que para este problema y para la configuración de la red elegida, el uso de la deserción en las capas ocultas no elevó el rendimiento. De hecho, el rendimiento fue peor que la línea de base. Es posible que se requieran épocas de formación adicionales o que se requiera una mayor adaptación al ritmo de aprendizaje.
Oculta: 82.09% (8.39%)
Consejos Para Usar la deserción en redes neuronales:
El artículo original sobre deserción proporciona resultados experimentales en una serie de máquinas estándar para problemas de aprendizaje. Como resultado, proporcionan una serie de heurísticas útiles a considerar cuando se utiliza deserción escolar en la práctica:
- Generalmente se utiliza un pequeño valor de abandono del 20%-50% de las neuronas, con un 20% que proporciona un buen resultado como punto de partida. Una probabilidad demasiado baja tiene un efecto mínimo y un valor demasiado alto resulta en subaprendizaje por parte de la red.
- Utilice una red más grande. Es probable que usted obtenga un mejor rendimiento cuando se utiliza el método de la deserción en una red más grande, dando al modelo más de una oportunidad de aprender independientemente de representaciones.
- Utilice la función “droppout” (deserción) tanto en la entrada (visible) como en las capas ocultas. La aplicación de la deserción en cada parte de la red ha dado buenos resultados.
- Utilice una gran velocidad de aprendizaje con decaimiento y un gran impulso. Aumente su ritmo de aprendizaje por un factor de 10 a 100 y utilize un valor de momento (impulso) alto de 0,9 o 0,99.
- Limite el tamaño de los pesos de la red. Una gran velocidad de aprendizaje puede resultar en grandes pesos en la red. Imponer una restricción en el tamaño de los pesos de la red como max-norm mejora los resultados con un tamaño de 4 o 5.
Resumen del post “Reducir el sobreajuste con la regularización de la Deserción”
En esta lección usted descubrió la técnica de regularización de la deserción para modelos de aprendizaje profundo. Aprendiste:
- Qué es la deserción escolar y cómo funciona.
- Cómo puede utilizar la deserción escolar en sus propios modelos de aprendizaje profundo.
- Consejos para obtener los mejores resultados de la deserción en sus propios modelos.
➡ Continúa aprendiendo de Deep Learning con nuestro curso: