Modificación del número de capas congeladas en DL

| Última modificación: 19 de julio de 2024 | Tiempo de Lectura: 4 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

La modificación del número de capas congeladas en DL (Deep Learning) forma parte de los tipos de análisis que puedes el desarrollar en el procesamiento de los macrodatos. En este post, te lo explicamos todo sobre la modificación del número de capas congeladas en DL.

Modificación del número de capas congeladas en DL

ImageNet consiste en un dataset de más o menos 1,2 millones de imágenes para entrenamiento, 50.000 para validación y 100.000 para test pertenecientes a 1000 categorías.

Observa la imagen para comprender la modificación del número de capas congeladas en DL:

¿Qué te parecería si quitásemos la última capa de alguna de las redes preentrenadas, que simplemente lo que hacen es sacar una probabilidad para cada una de las 1000 clases del ImageNet, y la sustituyésemos por una capa ad-hoc a nuestra aplicación con tantas neuronas como clases en las que queremos clasificar? ¡De esta forma, podríamos aprovechar todo el conocimiento que adquirieron los filtros involucrados en la CNN cuando fue entrenada en el conjunto de datos ImageNet y aplicarlo a nuestro problema!

Vamos a ver cómo se haría esto para la red VGG16. Recordad su arquitectura:

Como hemos visto, lo que haremos será cambiar la etapa de clasificación, para que la última capa sea una de 10 neuronas (nuestro CIFAR 10 tiene 10 clases) y luego reentrenaremos la red al permitir que se modifiquen los pesos de las capas fully connected, es decir, de la etapa de clasificación. Para esto, inicializaríamos nuestra red con los pesos de ImageNet y, después, congelaríamos todas las capas convolucionales y de max pooling para que no modificasen sus pesos, dejando solo libres las fully connected.

Una vez hecho eso, empezaríamos a reentrenar. De esta forma, logramos aprovechar la etapa de extracción de características de nuestra red y solamente afinamos el clasificador final para que funcione mejor con nuestro dataset. Esto es lo que se conoce como Transfer Learning, porque aprovechamos conocimiento de otro problema para solucionar el que tenemos entre manos en este momento.

De hecho, este enfoque se puede hacer también guardándonos las características que da la última capa de max pooling y, luego, metiendo esos datos a cualquier clasificador (SVM, logreg, etc).

Ejemplo práctico

Veamos cómo podríamos hacer la modificación del número de capas congeladas en DL:

# primero cargamos nuestro dataset y lo redimensionamos a las dimensiones mínimas
# permitidas por la VGG16 -> (48, 48, 3)
# importamos lo necesario
from tensorflow.keras import callbacks
from tensorflow.keras import optimizers, Model
from tensorflow.keras.layers import Dropout, Flatten, Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import VGG16
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
import numpy as np

input_shape = (48, 48, 3)

(X_train, y_train), (X_test, y_test) = cifar10.load_data()
Y_train = to_categorical(y_train)
Y_test = to_categorical(y_test)

# resize train set
X_train_resized = []
for img in X_train:
  X_train_resized.append(np.resize(img, input_shape) / 255)
  
X_train_resized = np.array(X_train_resized)
print(X_train_resized.shape)

# resize test set
X_test_resized = []
for img in X_test:
  X_test_resized.append(np.resize(img, input_shape) / 255)
  
X_test_resized = np.array(X_test_resized)
print(X_test_resized.shape)
# construimos el modelo base
base_model = VGG16(weights='imagenet', include_top=False, input_shape=input_shape)
base_model.summary()
# congelamos todas las capas de nuestro base_model para que no se entrenen
# queremos que nuestro feature extractor siga igual que antes: transfer learning
for layer in base_model.layers: 
  layer.trainable = False
  print('Capa ' + layer.name + ' congelada.')

# cogemos la última capa del model y le añadimos nuestro clasificador (top_model)
last = base_model.layers[-1].output
x = Flatten()(last)
x = Dense(1000, activation='relu', name='fc1')(x)
x = Dropout(0.3)(x)
x = Dense(10, activation='softmax', name='predictions')(x)
model = Model(base_model.input, x)

# compilamos el modelo
model.compile(optimizer=Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])

# vemos la estructura del modelo
model.summary()
# comenzamos con el entrenamiento
epochs = 10
batch_size = 256

# como entrenariamos normalmente
model.fit(X_train_resized, Y_train,
          batch_size=batch_size,
          validation_data=(X_test_resized, Y_test),
          epochs=epochs)

¡No hemos tenido que entrenar nada y no hemos obtenido unos resultados tan malos! Ten en cuenta que si lo hiciésemos aleatoriamente, la probabilidad de acertar sería de 1/10=0.1 o un 10%, ya que tenemos 10 clases. De hecho, cuanto más parecidos sean el dataset sobre el que ha sido entrenada originalmente la red y el dataset de nuestro problema, mejores resultados obtendremos.

Sin embargo, la técnica de transferencia del conocimiento es bastante simple y, para problemas más complicados, no ofrece muy buenos resultados. La idea ahora es reentrenar, al margen del top-model, algunos bloques convolucionales del base_model. Esta sutil diferencia hace que, en vez de estar haciendo transfer learning, estemos haciendo fine-tuning.

Ya sabes cómo funciona la modificación del número de capas congeladas en DL (Deep Learning), pero ¡todavía falta mucho por aprender! Para acompañarte en tu formación, nuestro Bootcamp Full Stack Big Data, Inteligencia Artificial & Machine Learning es perfecto. Podrás potenciar tus destrezas en el manejo de los macrodatos y sus múltiples herramientas, lenguajes y sistemas. ¡Apúntate ahora y no esperes más para seguir aprendiendo!

Sandra Navarro

Business Intelligence & Big Data Advisor & Coordinadora del Bootcamp en Data Science, Big Data & Machine Learning.

Posts más leídos

¡CONVOCATORIA ABIERTA!

Big Data, IA & Machine Learning

Full Stack Bootcamp

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