O que é uma incorporação em Keras?


97

A documentação do Keras não está clara o que realmente é. Eu entendo que podemos usar isso para comprimir o espaço do recurso de entrada em um menor. Mas como isso é feito do ponto de vista do design neural? É um autoenocder, RBM?

keras 

7
É uma tabela de pesquisa que pode ser treinada
gokul_uf

1
Ele simplesmente cria e indexa uma matriz de peso; veja minha resposta detalhada abaixo ( stackoverflow.com/a/53101566/9024698 ).
Pária de

3
Embora a resposta mais votada diga que é uma multiplicação de matriz, o código-fonte e outras respostas mostram que, na verdade, são apenas uma matriz treinável. As palavras de entrada apenas escolhem a linha respectiva nesta matriz.
Daniel Möller

Respostas:


66

Pelo que eu sei, a camada Embedding é uma multiplicação de matriz simples que transforma palavras em seus embeddings de palavras correspondentes.

Os pesos da camada Embedding são da forma (vocabulary_size, embedding_dimension). Para cada amostra de treinamento, sua entrada são inteiros, que representam certas palavras. Os inteiros estão na faixa do tamanho do vocabulário. A camada de incorporação transforma cada inteiro i na i-ésima linha da matriz de pesos de incorporação.

Para fazer isso rapidamente como uma multiplicação de matriz, os inteiros de entrada não são armazenados como uma lista de inteiros, mas como uma matriz one-hot. Portanto, a forma de entrada é (nb_words, vocabulary_size) com um valor diferente de zero por linha. Se você multiplicar isso pelos pesos de incorporação, você obtém a saída na forma

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

Assim, com uma simples multiplicação de matriz, você transforma todas as palavras em uma amostra nos embeddings de palavras correspondentes.


3
Definitivamente, uma abordagem válida (consulte Aprendizagem sequencial semissupervisionada ). Você também pode aprender os embeddings com um autoencoder e, em seguida, usá-los como inicialização da camada de Embedding para reduzir a complexidade de sua rede neural (presumo que você faça outra coisa depois da camada de Embedding).
Lorrit

3
Aqui está uma boa postagem de blog sobre embeddings de palavras e suas vantagens.
sietschie

3
No caso que apresentei, cada entrada de treinamento é um conjunto de palavras (pode ser uma frase). Cada palavra é representada como um vetor quente e incorporada em um vetor denso. A desvantagem dessa abordagem é que, como a entrada precisa ter um comprimento constante, todas as frases precisam ter o mesmo número de palavras. Uma alternativa seria vetores de parágrafo , que podem incorporar frases, parágrafos ou até mesmo documentos em vetores.
Caminhão

4
A camada de incorporação irá apenas otimizar seus pesos para minimizar a perda. Talvez isso signifique que vai considerar a semelhança semântica, talvez não. Você nunca sabe com redes neurais. Se você quiser ter certeza de que a incorporação segue uma determinada fórmula (por exemplo, w2v), use a fórmula. Se você tiver dados suficientes, convém usar a camada Embedding e treinar os embeddings. Experimente e verifique se gosta dos resultados.
Lorrit

2
Concordo com o usuário36624 (resposta abaixo). Sua NÃO uma multiplicação de matrizes simples.
Daniel Möller

21

A Keras Embeddingcamada não está realizando nenhuma multiplicação de matriz, mas apenas:

1. cria uma matriz de peso de dimensões (tamanho_do_ vocabulário) x ( dimensão_incorporação )

2. indexa esta matriz de peso


É sempre útil dar uma olhada no código-fonte para entender o que uma classe faz. Neste caso, daremos uma olhada no class Embedding que herda da camada base classchamada Layer .

(1) - Criação de uma matriz de peso das dimensões (tamanho_do_ vocabulário) x ( dimensão_embedding ) :

Isso está ocorrendo na buildfunção de Incorporação :

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

Se você der uma olhada na camada de classe base , verá que a função add_weightacima simplesmente cria uma matriz de pesos treináveis ​​(neste caso de dimensões (tamanho_do_ vocabulário) x ( dimensão_embedding)):

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) - Indexando esta matriz de peso

Isso está ocorrendo na callfunção de Incorporação :

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

Esta função retorna a saída da Embeddingcamada que está K.gather(self.embeddings, inputs). O que tf.keras.backend.gather faz exatamente é indexar a matriz de pesos self.embeddings(veja a buildfunção acima) de acordo com o inputsque deve ser listas de inteiros positivos.

Essas listas podem ser recuperadas, por exemplo, se você passar suas entradas de texto / palavras para a função one_hot de Keras, que codifica um texto em uma lista de índices de palavras de tamanho n (esta NÃO é uma codificação quente - veja também este exemplo para mais informações: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).


Portanto, isso é tudo. Não há multiplicação de matrizes.

Pelo contrário, a Keras Embeddingcamada só é útil porque exatamente evita a multiplicação de matrizes e, portanto, economiza alguns recursos computacionais.

Caso contrário, você pode apenas usar uma camada Keras Densa (depois de codificar seus dados de entrada) para obter uma matriz de pesos treináveis ​​(de (tamanho_do_vocabulário) x ( dimensão_embebimento) dimensões) e então simplesmente fazer a multiplicação para obter a saída que será exatamente o mesmo com a saída da Embeddingcamada.


5

Para entender melhor qualquer função, é um bom hábito olhar o código-fonte. Aqui é para incorporação Então, basicamente, é uma tabela de pesquisa treinável.


4

No Keras, a Embeddingcamada NÃO é uma camada de multiplicação de matriz simples, mas uma camada de tabela de consulta (consulte a função de chamada abaixo ou a definição original ).

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

O que ele faz é mapear um número inteiro conhecido nem inputsum vetor de recurso treinável W[n], cuja dimensão é o chamado comprimento de recurso incorporado.


Bem, quando você multiplica um conjunto de vetores representados por um elemento por uma matriz, o produto se torna uma consulta. Portanto, a Embeddingcamada é de fato uma multiplicação de matriz.
yannis de

Exceto que em nenhum lugar keras realiza essa multiplicação. Ele apenas define "embeddings = uma matriz treinável" e usa os índices de entrada para reunir palavras da matriz.
Daniel Möller

Portanto, essa incorporação poupa muita memória, simplesmente não criando nenhuma versão one-hot das entradas.
Daniel Möller

1

Em palavras simples (do ponto de vista da funcionalidade), é um codificador one-hot e uma camada totalmente conectada . Os pesos da camada são treináveis.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.