¿Qué es una incrustación en Keras?

97

La documentación de Keras no está clara de qué es esto en realidad. Entiendo que podemos usar esto para comprimir el espacio de características de entrada en uno más pequeño. Pero, ¿cómo se hace esto desde la perspectiva del diseño neuronal? ¿Es un autoenocder, RBM?


fuente
7
Es una tabla de búsqueda que se puede entrenar
gokul_uf
1
Simplemente crea e indexa una matriz de ponderaciones; vea mi respuesta detallada a continuación ( stackoverflow.com/a/53101566/9024698 ).
Paria
3
Aunque la respuesta más votada dice que es una multiplicación de matrices, el código fuente y otras respuestas muestran que, de hecho, son solo una matriz entrenable. Las palabras de entrada simplemente seleccionan la fila respectiva en esta matriz.
Daniel Möller

Respuestas:

66

Hasta donde yo sé, la capa de incrustación es una multiplicación de matriz simple que transforma las palabras en sus correspondientes incrustaciones de palabras.

Los pesos de la capa Embedding son de la forma (vocabulary_size, embedding_dimension). Para cada muestra de entrenamiento, su entrada son números enteros, que representan ciertas palabras. Los números enteros están en el rango del tamaño del vocabulario. La capa de incrustación transforma cada entero i en la i-ésima línea de la matriz de pesos de incrustación.

Para hacer esto rápidamente como una multiplicación de matrices, los enteros de entrada no se almacenan como una lista de enteros sino como una matriz de un solo uso. Por lo tanto, la forma de entrada es (nb_words, vocabulary_size) con un valor distinto de cero por línea. Si multiplica esto por los pesos de incrustación, obtiene el resultado en la forma

(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)

Entonces, con una simple multiplicación de matrices, transforma todas las palabras en una muestra en las incrustaciones de palabras correspondientes.

Lorrit
fuente
3
Definitivamente un enfoque válido (ver Aprendizaje secuencial semi-supervisado ). También puede aprender las incrustaciones con un codificador automático y luego usarlas como inicialización de la capa de incrustación para reducir la complejidad de su red neuronal (supongo que hace algo más después de la capa de incrustación).
Lorrit
3
Aquí hay una buena entrada de blog sobre incrustaciones de palabras y sus ventajas.
sietschie
3
En el caso que presenté, cada entrada de entrenamiento es un conjunto de palabras (puede ser una oración). Cada palabra se representa como un vector caliente y se incrusta en un vector denso. La desventaja de este enfoque es que, dado que la entrada debe tener una longitud constante, todas las oraciones deben tener el mismo número de palabras. Una alternativa serían los vectores de párrafo , que pueden incrustar oraciones, párrafos o incluso documentos en vectores.
Lorrit
4
La capa de incrustación solo optimizará sus pesos para minimizar la pérdida. Tal vez eso signifique que considerará la similitud semántica, tal vez no. Nunca se sabe con las redes neuronales. Si desea asegurarse de que la incrustación sigue una fórmula determinada (por ejemplo, w2v), utilice la fórmula. Si tiene suficientes datos, es posible que desee utilizar la capa de incrustación y entrenar las incrustaciones. Pruébelo y compruebe si le gustan los resultados.
Lorrit
2
Estoy de acuerdo con user36624 (respuesta a continuación). Su no un simple multiplicación de matrices.
Daniel Möller
21

La Keras Embeddingcapa no está realizando ninguna multiplicación de matrices, pero solo:

1. crea una matriz de peso de (vocabulary_size) x (embedding_dimension) dimensiones

2. indexa esta matriz de ponderaciones


Siempre es útil echar un vistazo al código fuente para comprender lo que hace una clase. En este caso, veremos la class incrustación que hereda de la capa base classllamada Capa .

(1) - Creando una matriz de peso de (vocabulary_size) x (embedding_dimension) dimensiones:

Esto ocurre en la buildfunción de incrustación :

def build(self, input_shape):
    self.embeddings = self.add_weight(
        shape=(self.input_dim, self.output_dim),
        initializer=self.embeddings_initializer,
        name='embeddings',
        regularizer=self.embeddings_regularizer,
        constraint=self.embeddings_constraint,
        dtype=self.dtype)
    self.built = True

Si echa un vistazo a la capa de clase base , verá que la función add_weightanterior simplemente crea una matriz de pesos entrenables (en este caso de (vocabulary_size) x (embedding_dimension) dimensiones):

def add_weight(self,
               name,
               shape,
               dtype=None,
               initializer=None,
               regularizer=None,
               trainable=True,
               constraint=None):
    """Adds a weight variable to the layer.
    # Arguments
        name: String, the name for the weight variable.
        shape: The shape tuple of the weight.
        dtype: The dtype of the weight.
        initializer: An Initializer instance (callable).
        regularizer: An optional Regularizer instance.
        trainable: A boolean, whether the weight should
            be trained via backprop or not (assuming
            that the layer itself is also trainable).
        constraint: An optional Constraint instance.
    # Returns
        The created weight variable.
    """
    initializer = initializers.get(initializer)
    if dtype is None:
        dtype = K.floatx()
    weight = K.variable(initializer(shape),
                        dtype=dtype,
                        name=name,
                        constraint=constraint)
    if regularizer is not None:
        with K.name_scope('weight_regularizer'):
            self.add_loss(regularizer(weight))
    if trainable:
        self._trainable_weights.append(weight)
    else:
        self._non_trainable_weights.append(weight)
    return weight

(2) - Indexación de esta matriz de ponderaciones

Esto ocurre en la callfunción de incrustación :

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Esta función devuelve la salida de la Embeddingcapa que es K.gather(self.embeddings, inputs). Lo que tf.keras.backend.gather hace exactamente es indexar la matriz de ponderaciones self.embeddings(ver la buildfunción anterior) de acuerdo con las inputsque deberían ser listas de enteros positivos.

Estas listas se pueden recuperar, por ejemplo, si pasa sus entradas de texto / palabras a la función one_hot de Keras, que codifica un texto en una lista de índices de palabras de tamaño n (esta NO es una codificación activa; consulte también este ejemplo para obtener más información: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).


Por tanto, eso es todo. No hay multiplicación de matrices.

Por el contrario, la Keras Embeddingcapa solo es útil porque evita exactamente realizar una multiplicación de matrices y, por lo tanto, economiza algunos recursos computacionales.

De lo contrario, podría usar una capa Keras Densa (después de haber codificado sus datos de entrada) para obtener una matriz de pesos entrenables (de (vocabulary_size) x (embedding_dimension) dimensiones) y luego simplemente hacer la multiplicación para obtener el resultado que será exactamente lo mismo con la salida de la Embeddingcapa.

Paria
fuente
5

Para comprender mejor cualquier función, es un buen hábito mirar el código fuente. Aquí está la incrustación. Básicamente, es una tabla de consulta entrenable.

Andrey Nikishaev
fuente
4

En Keras, la Embeddingcapa NO es una simple capa de multiplicación de matrices, sino una capa de tabla de búsqueda (consulte la función de llamada a continuación o la definición original ).

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Lo que hace es mapear cada uno de los números enteros conocidos nen inputsun vector de características entrenables W[n], cuya dimensión es la denominada longitud de características incrustadas.

trampa
fuente
Bueno, cuando se multiplica un conjunto de vectores representados en caliente con una matriz, el producto se convierte en una búsqueda. Entonces, la Embeddingcapa es de hecho una multiplicación de matrices.
yannis
Excepto que en ninguna parte keras realiza esta multiplicación. Simplemente define "embeddings = una matriz entrenable" y usa los índices de entrada para recopilar palabras de la matriz.
Daniel Möller
Por lo tanto, esta incrustación ahorra mucha memoria simplemente al no crear una versión única de las entradas.
Daniel Möller
1

En palabras simples (desde el punto de vista de la funcionalidad), es un codificador one-hot y una capa completamente conectada . Los pesos de las capas se pueden entrenar.

Ali Mirzaei
fuente