Path: blob/master/site/es-419/guide/keras/masking_and_padding.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
Enmascaramiento y amortiguación con Keras
Configuración
Introducción
El enmascaramiento es una forma de indicarle a las capas que se encargan del procesamiento de las secuencias que faltan ciertos pasos temporales en una entrada y que, por lo tanto, estos deben omitirse durante el procesamiento de los datos.
La amortiguación es una forma especial de enmascaramiento, donde los pasos enmascarados se encuentran al principio o al final de una secuencia. El amortiguamiento surge por la necesidad de codificar secuencias de datos en lotes contiguos: para que todas las secuencias de un lote se ajusten a una cierta longitud estándar es necesario amortiguar o truncar algunas secuencias.
Veamos cómo funciona esto.
Amortiguación de una secuencia de datos
Cuando se procesan secuencias de datos, es muy común que las muestras individuales tengan diferentes longitudes. Considere el siguiente ejemplo (el texto se convirtió en tokens que funcionan como palabras):
Después de la búsqueda de vocabulario, los datos pueden vectorizarse como números enteros, por ejemplo:
Los datos consisten en una lista anidada en donde las muestras individuales tienen una longiud de 3, 5, y 6 datos, respectivamente. Dado que los datos de entrada para un modelo de aprendizaje profundo deben ser un tensor único (con forma, por ejemplo, (batch_size, 6, vocab_size)
en este caso), las muestras más cortas que el elemento más largo deben amortiguarse con algún valor del marcador de posición (o en su defecto, también es posible truncar las muestras largas antes de amortiguar las muestras cortas).
Keras proporciona una función que es útil para truncar y amortiguar las listas de Python a una longitud habitual: tf.keras.preprocessing.sequence.pad_sequences
.
Enmascaramiento
Ahora que todas las muestras tienen una longitud uniforme, es necesario informarle al modelo que una parte de los datos en realidad es un amortiguado y debe ignorarse. Este mecanismo es el enmascaramiento.
En los modelos de Keras, hay tres formas de establecer máscaras de entrada:
Agregar una capa
keras.layers.Masking
.Configurar una capa
keras.layers.Embedding
mediantemask_zero=True
.Pasar un argumento
mask
manualmente cuando se llama a las capas que sustentan dicho argumento (por ejemplo, las capas RNN).
Capas que generan el enmascaramiento: Embedding
y Masking
En el trasfondo, estas capas crearán una máscara para el tensor (un tensor con forma 2D (batch, sequence_length)
), y adjunto a este un tensor de salida devuelto por las capas Masking
o Embedding
.
Como puede ver en el resultado impreso, la máscara es un tensor booleano en 2D con forma de (batch_size, sequence_length)
, donde cada entrada individual False
indica que el paso temporal correspondiente debe ignorarse durante el procesamiento.
Propagación de la máscara en la API funcional y en la API secuencial
Cuando se utilizan ya sea la API funcional o la API secuencial, una máscara generada por una capa Embedding
o Masking
se propagará a través de la red para cualquier capa que sea capaz de utilizarlas (por ejemplo, las capas RNN). Entonces, Keras obtendrá automáticamente la máscara correspondiente a una entrada y la pasará a cualquier capa que sepa utilizarla.
Por ejemplo, en el siguiente modelo secuencial, la capa LSTM
recibirá una máscara automáticamente, lo cual significa que ignorará los valores amortiguados:
Lo mismo ocurre con el siguiente modelo de una API funcional:
Cómo pasar los tensores de la máscara directamente a las capas
Las capas que pueden soportar máscaras (como la capa LSTM
) tienen un argumento de tipo mask
en su método __call__
.
En cambio, las capas que generan una máscara (por ejemplo, Embedding
) exhiben un método compute_mask(input, previous_mask)
al que usted puede llamar.
Por lo tanto, puede traspasar la salida del método compute_mask()
desde una capa que genera máscaras al método __call__
de una capa que utiliza máscaras, de la siguiente forma:
Cómo brindar asistencia a las máscaras en sus capas personalizadas
Algunas veces, es posible que necesite escribir capas que generen una máscara (como Embedding
), o capas que necesiten modificar la máscara actual.
Por ejemplo, cualquier capa que genere un tensor cuya dimensión temporal sea diferente a la de su entrada, como una capa Concatenate
a fin de que concatene en la dimensión temporal, necesitará modificar la máscara actual para que las capas posteriores consideren correctamente los pasos temporales enmascarados.
Para ello, su nueva capa debe implementar el método layer.compute_mask()
, el cual produce una nueva máscara cuando se proporcionan la entrada y la máscara actual.
A continuación, se muestra el ejemplo de una capa TemporalSplit
donde se necesita modificar la máscara actual.
El siguiente es otro ejemplo de una capa CustomEmbedding
que es capaz de generar una máscara a partir de los valores de entrada:
Cómo elegir la propagación de máscaras en capas que sean compatibles
En la mayoría de las capas no se modifica la dimensión temporal, de modo que no es necesario modificar la máscara actual. Sin embargo, es posible que se desee propagar la máscara actual, sin ningún cambio, a la siguiente capa. Esta es una acción opcional. De forma predeterminada, una capa personalizada destruirá la máscara actual (ya que la estructura no tiene forma de saber si es seguro propagar la máscara).
Si tiene una capa personalizada en la que no se modifique la dimensión temporal, y desea que pueda propagarse la máscara de la entrada actual, debe establecer self.supports_masking = True
en el generador de la capa. En este caso, la acción predeterminada de compute_mask()
es simplemente traspasar la máscara actual.
A continuación, se muestra el ejemplo de una capa que está en la lista blanca para la propagación de máscaras:
Ahora puede usar esta capa personalizada que se encuentra entre una capa generadora de máscaras (como Embedding
) y una capa que utiliza máscaras (como LSTM
), esto traspasará la máscara para que llegue a la capa que utiliza las máscaras.
Cómo escribir capas que necesitan información sobre la máscara
Algunas capas son consumers de máscaras: aceptan un argumento mask
en la call
y lo usan para determinar si deben saltarse ciertos pasos temporales.
Para escribir una capa de este tipo, puede simplemente añadir un argumento mask=None
en la firma de su call
signature. La máscara asociada a las entradas se pasará a su capa siempre que esté disponible.
A continuación, veremos un ejemplo sencillo: una capa que calcula un softmax sobre la dimensión temporal (eje 1) de una secuencia de entrada, mientras descarta los pasos temporales enmascarados.
Resumen
Esto es todo lo que necesita saber sobre la amortiguación y el enmascaramiento en Keras. Para recapitular, recuerde lo siguiente:
El "enmascaramiento" es la forma en que las capas son capaces de saber cuándo omitir / ignorar ciertos pasos temporales en las entradas de la secuencia.
Algunas capas son generadoras de máscaras:
Embedding
puede generar una máscara a partir de los valores de entrada (simask_zero=True
), y lo mismo puede hacer la capaMasking
.Algunas capas utilizan máscaras: exhiben un argumento
mask
en su método__call__
. Este es el caso de las capas RNN.Tanto en la API funcional como en la API secuencial, la información sobre la máscara se propaga automáticamente.
Cuando las capas se usan de forma independiente, puede traspasar los argumentos
mask
a las capas de forma manual.Puede escribir fácilmente capas que modifiquen la máscara actual, ya sea que generen una nueva máscara o que utilicen la máscara asociada a las entradas.