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?
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?
Respostas:
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.
A Keras
Embedding
camada 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 class
chamada Layer .
(1) - Criação de uma matriz de peso das dimensões (tamanho_do_ vocabulário) x ( dimensão_embedding ) :
Isso está ocorrendo na build
funçã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_weight
acima 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 call
funçã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 Embedding
camada que está K.gather(self.embeddings, inputs)
. O que tf.keras.backend.gather faz exatamente é indexar a matriz de pesos self.embeddings
(veja a build
função acima) de acordo com o inputs
que 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
Embedding
camada 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 Embedding
camada.
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.
No Keras, a Embedding
camada 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 n
em inputs
um vetor de recurso treinável W[n]
, cuja dimensão é o chamado comprimento de recurso incorporado.
Embedding
camada é de fato uma multiplicação de matriz.
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.