Visualizando representaciones de capas internas en Redes Neuronales

La redes neuronales artificiales están en el “ojo del huracán”, tanto en temas de investigación pura y dura, como en aplicaciones empresariales e industriales. Continuamente aparecen nuevas aplicaciones donde sorprende su uso y permite mejorar, de forma considerable, los resultados obtenidos previamente con otros modelos de aprendizaje automático.

Uno de los principales problemas de las redes neuronales está relacionado con la falta de interpretación y “explicabilidad” de los modelos generados. En este post veremos un método que nos permitirá, de alguna forma, poder representar y ver la información contenida en las capas internas de una red neuronal.

El detalle del proceso completo, junto con el código fuente completo para el ejemplo, está disponible aquí.

La idea que subyace en este proceso es sencilla:

  1. En primer lugar, entrenaremos el modelo, de la forma habitual.
  2. Una vez el modelo esté entrenado, lo que nos interesa (de alguna forma) es “cortar” la red en el punto que queremos analizar (en principio, alguna de las capas ocultas) y poder ver cuales son los valores que se están generando en las capas ocultas. Es decir, queremos ver como se van “agrupando” o “clasificando” los datos en las diferentes capas ocultas.
  3. Para realizar esta acción, lo que haremos será crear un nuevo modelo truncado que sólo incluirá las capas iniciales hasta la capa que queremos analizar.
  4. A partir de del modelo original y completo, copiaremos los valores (pesos y bias) entrenados al modelo truncado, de forma que tendremos acceso a los valores generados por la red neuronal en el punto de salida de la capa deseada.
  5. Finalmente, si queremos poder visualizar estos datos, deberemos realizar una reducción de la dimensionalidad para poder representarlos en un gráfico 2D o 3D.

A continuación mostramos parte del código, empleando Python y la librería Keras.

En primer lugar, como hemos comentado, creamos el modelo original (una red recurrente con varias capas, incluyendo una LSTM) y lo entrenamos con los parámetros requeridos hasta conseguir un nivel de precisión (accuracy) aceptable.

model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(Bidirectional(LSTM(64)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

# try using different optimizers and different optimizer configs
model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])

print('Train...')
model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=4,
          validation_split=0.2)

Y definimos el modelo truncado con la misma configuración de capas hasta llegar a la capa que queremos analizar. Ésta quedará como la capa de salida del modelo, para poder ver y analizar las salidas de la capa en cuestión. La siguiente función nos permite crear esta red truncada y copiar los valores (pesos y bias) de la red original (una vez entrenada).

def create_truncated_model(trained_model):
   model = Sequential()
   model.add(Embedding(max_features, 128, input_length=maxlen))
   model.add(Bidirectional(LSTM(64)))
   for i, layer in enumerate(model.layers):
      layer.set_weights(trained_model.layers[i].get_weights())

   model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
   return model

truncated_model = create_truncated_model(model)
hidden_features = truncated_model.predict(x_test)

A partir de la salida de la red truncada podremos analizar los resultados obtenidos y ver como se está comportando nuestra red en cada una de las capas, teniendo en cuenta los cálculos realizados en las capas anteriores.

Aún así, en ciertos casos nos puede interesar representar esta información de una forma visual, que permita un análisis rápido de como se están agrupando los datos después del proceso en cada una de las capas.

Para realizar esto, es necesario reducir la dimensionalidad de los datos para poder representarlos en un gráfico 2D o 3D. Una opción es utilizar los métodos de reducción de dimensionalidad, como por ejemplo PCA o T-SNE (o una combinación de ambos).

A continuación mostramos en ejemplo de visualización después de realizar una reducción de dimensionalidad empleando PCA + T-SNE.

En la figura podemos ver como las dos clases de instancias están “bastante” separadas en esta capa, aunque con cierto grado de solapamiento. Esto nos indica que no será posible obtener valores de accuracy cercanos al 100% en esta capa.

This entry was posted in Artificial Intelligence, Data Science, Deep Learning, Machine learning and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *