Regularización por Dropout en red convolucional

Contenido del Bootcamp Dirigido por: | Última modificación: 18 de abril de 2024 | Tiempo de Lectura: 4 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

La regularización por Dropout en red convolucional es uno de los tipos de regularización que podrás encontrar dentro del Deep Learning. Por ello, en este post, te explicamos cómo funciona la regularización por Dropout en red convolucional.

Regularización por Dropout en red convolucional

La regularización por Dropout en red convolucional es una técnica desarrollada por Srivastava y otros en su artículo Dropout: A Simple Way to Prevent Neural Networks from Overfitting, que complementa los otros tipos de normalización (L1, L2, maxnorm).

Es una técnica extremadamente efectiva y simple que consiste en mantener una neurona activa o ponerla a 0 durante el entrenamiento con una probabilidad p.

Lo que hace la regularización por Dropout en red convolucional es cambiar la arquitectura de la red en tiempo de entrenamiento, lo que significa que no habrá una sola neurona responsable de activarse ante un determinado patrón, sino que tendremos múltiples neuronas redundantes capaces de reaccionar ante ese patrón.

Ejemplo práctico de regularización por Dropout

Veamos qué tal se porta nuestra red con Dropout:

# Prueba con Dropout

# importamos la capa Dropout
from tensorflow.keras.layers import Dropout

# Inizializamos el modelo
model = Sequential()

# Definimos una capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(Dropout(0.25))

# Definimos una segunda capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Dropout(0.25))

# Definimos la tercera capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Dropout(0.25))

# Añadimos nuestro clasificador
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

# Compilamos el modelo
model.compile(loss='categorical_crossentropy',
              optimizer=Adam(lr=0.0001, decay=1e-6),
              metrics=['accuracy'])

# Entrenamos el modelo
model.fit(X_train_norm, to_categorical(Y_train),
          batch_size=128,
          shuffle=True,
          epochs=10,
          validation_data=(X_test_norm, to_categorical(Y_test))) # aquí deberíamos usar un conjunto distinto al de test

# Evaluamos el modelo
scores = model.evaluate(X_test_norm, to_categorical(Y_test))

print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])
# Prueba con Dropout y Maxnorm

from tensorflow.keras.constraints import max_norm
from tensorflow.keras.layers import Dropout

# Inizializamos el modelo
model = Sequential()

# Definimos una capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(Dropout(0.25))

# Definimos una segunda capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Dropout(0.25))

# Definimos una tercera capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Dropout(0.25))

# Añadimos nuestro clasificador
model.add(Flatten())
model.add(Dense(1024, activation='relu', kernel_constraint=max_norm(3.)))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

# Compilamos el modelo
model.compile(loss='categorical_crossentropy',
              optimizer=Adam(lr=0.0001, decay=1e-6),
              metrics=['accuracy'])

# Entrenamos el modelo
model.fit(X_train_norm, to_categorical(Y_train),
          batch_size=128,
          shuffle=True,
          epochs=10,
          validation_data=(X_test_norm, to_categorical(Y_test))) # aquí deberíamos usar un conjunto distinto al de test

# Evaluamos el modelo
scores = model.evaluate(X_test_norm, to_categorical(Y_test))

print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])

¿Y si usásemos, además, la capa MaxPooling?

# Prueba con Dropout, Maxnorm y Maxpooling

from tensorflow.keras.layers import Dropout
from tensorflow.keras.constraints import max_norm
from tensorflow.keras.layers import MaxPooling2D

# Inizializamos el modelo
model = Sequential()

# Definimos una capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# Definimos la segunda capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# Definimos una tercera capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# Añadimos nuestro clasificador
model.add(Flatten())
model.add(Dense(1024, activation='relu', kernel_constraint=max_norm(3.)))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

# Compilamos el modelo
model.compile(loss='categorical_crossentropy',
              optimizer=Adam(lr=0.0001, decay=1e-6),
              metrics=['accuracy'])

# Entrenamos el modelo
model.fit(X_train_norm, to_categorical(Y_train),
          batch_size=128,
          shuffle=True,
          epochs=10,
          validation_data=(X_test_norm, to_categorical(Y_test))) # aquí también deberíamos usar un conjunto distinto al de test

# Evaluamos el modelo
scores = model.evaluate(X_test_norm, to_categorical(Y_test))

print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])

¿Y aumentando el strides a (2,2) en las convolucionales, en vez de añadir MaxPooling?

# Prueba con Dropout, Maxnorm y strides = 4 en las convolucionales

from tensorflow.keras.constraints import max_norm
from tensorflow.keras.layers import Dropout

# Inizializamos el modelo
model = Sequential()

# Definimos una capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), strides=(2,2), activation='relu', input_shape=(32, 32, 3)))
model.add(Dropout(0.25))

# Definimos una segunda capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), strides=(2,2), activation='relu'))
model.add(Dropout(0.25))

# Definimos una tercera capa convolucional
model.add(Conv2D(128, kernel_size=(3, 3), strides=(2,2), activation='relu'))
model.add(Dropout(0.25))

# Añadimos nuestro clasificador
model.add(Flatten())
model.add(Dense(1024, activation='relu', kernel_constraint=max_norm(3.)))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

# Compilamos el modelo
model.compile(loss='categorical_crossentropy',
              optimizer=Adam(lr=0.0001, decay=1e-6),
              metrics=['accuracy'])

# Entrenamos el modelo
model.fit(X_train_norm, to_categorical(Y_train),
          batch_size=128,
          shuffle=True,
          epochs=10,
          validation_data=(X_test_norm, to_categorical(Y_test))) #recuerda usar un conjunto distinto al de test

# Evaluamos el modelo
scores = model.evaluate(X_test_norm, to_categorical(Y_test))

print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])

Los resultados son parecidos en términos de velocidad, pero la precisión es menor. En un artículo publicado en 2014, los autores proponían dejar de usar las capas de pooling en pro de la simplicidad, y de hecho, hay arquitecturas como la ResNet que abogan por esto. Sin embargo, siguen utilizándose bastante a día de hoy en la regularización por Dropout en red convolucional.

Aprende más sobre el Big Data

En este post, te hemos expuesto todo sobre la regularización por Dropout en red convolucional, sin embargo, si quieres aprender más sobre el manejo del Big Data, desde KeepCoding te brindamos el Bootcamp Full Stack Big Data, Inteligencia Artificial & Machine Learning. Al finalizar esta formación, en menos de nueve meses, serás capaz de reconocer las ventajas e inconvenientes de los distintos programas estudiados. ¡Inscríbete!

Posts más leídos

¡CONVOCATORIA ABIERTA!

Big Data, IA & Machine Learning

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado