Dokumentacja Keras nie jest jasna, co to właściwie jest. Rozumiem, że możemy użyć tego do skompresowania przestrzeni funkcji wejściowych do mniejszej. Ale jak to się robi z perspektywy projektowania neuronowego? Czy to jest autoenocder, RBM?
Dokumentacja Keras nie jest jasna, co to właściwie jest. Rozumiem, że możemy użyć tego do skompresowania przestrzeni funkcji wejściowych do mniejszej. Ale jak to się robi z perspektywy projektowania neuronowego? Czy to jest autoenocder, RBM?
Odpowiedzi:
O ile wiem, warstwa osadzania to proste mnożenie macierzy, które przekształca słowa w odpowiadające im osadzenia słów.
Wagi warstwy Osadzanie mają kształt (rozmiar_cisku, wymiar_ osadzenia). Dla każdej próbki treningowej jej dane wejściowe to liczby całkowite, które reprezentują określone słowa. Liczby całkowite mieszczą się w zakresie rozmiaru słownika. Warstwa osadzania przekształca każdą liczbę całkowitą i do i-tego wiersza macierzy wag osadzania.
Aby szybko zrobić to jako mnożenie macierzy, wejściowe liczby całkowite nie są przechowywane jako lista liczb całkowitych, ale jako jedna gorąca macierz. Dlatego kształt wejściowy to (nb_words, vocabulary_size) z jedną niezerową wartością w każdym wierszu. Jeśli pomnożymy to przez wagi osadzania, otrzymamy wynik w kształcie
(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)
Tak więc za pomocą prostego mnożenia macierzy przekształcasz wszystkie słowa w próbce w odpowiadające im osadzenia słów.
Keras EmbeddingWarstwa nie wykonuje żadnego mnożenia macierzy, ale nie tylko:
1. Tworzy to macierz masy (vocabulary_size) x (embedding_dimension) wymiary
2. indeksuje tę macierz wag
Zawsze warto przyjrzeć się kodowi źródłowemu, aby zrozumieć, co robi klasa. W tym przypadku przyjrzymy się class osadzaniu, które dziedziczy z warstwy podstawowej classzwanej Warstwą .
(1) - Tworzenie macierzy wag o wymiarach (vocabulary_size) x (embedding_dimension) :
To jest występujących w buildfunkcji Osadzanie :
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
Jeśli spojrzysz na warstwę bazową klasy Layer , zobaczysz, że add_weightpowyższa funkcja po prostu tworzy macierz możliwych do nauczenia wag (w tym przypadku (vocabulary_size) x (embedding_dimension) wymiarów):
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) - Indeksowanie tej macierzy wag
To jest występujących w callfunkcji Osadzanie :
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Ta funkcja zwraca wynik Embeddingwarstwy, która jest K.gather(self.embeddings, inputs). To, co dokładnie robi tf.keras.backend.gather , to indeksowanie macierzy wag self.embeddings(patrz buildfunkcja powyżej) zgodnie z inputslistą dodatnich liczb całkowitych.
Listy te można pobrać, na przykład, jeśli przekażesz wprowadzone dane / słowa do funkcji one_hot Keras, która koduje tekst do listy indeksów słów o rozmiarze n (NIE jest to jedno gorące kodowanie - zobacz także ten przykład, aby uzyskać więcej informacji: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).
Dlatego to wszystko. Nie ma mnożenia macierzy.
Wręcz przeciwnie, warstwa jest tylko użyteczne, ponieważ dokładnie unika wykonywania mnożenia macierzy i dlatego oszczędza na niektórych zasobów obliczeniowych.Keras Embedding
W przeciwnym razie możesz po prostu użyć Keras Gęstej warstwy (po zakodowaniu danych wejściowych), aby uzyskać macierz możliwych do nauczenia wag (o wymiarach (rozmiar_ słownika) x ( wymiar osadzony) ), a następnie po prostu wykonać mnożenie, aby uzyskać wynik, który będzie dokładnie to samo z wyjściem Embeddingwarstwy.
Aby lepiej zrozumieć jakąkolwiek funkcję, dobrym zwyczajem jest spojrzenie na kod źródłowy. Tutaj jest do osadzania Więc w zasadzie jest to tabela wyszukiwania, którą można trenować.
W Keras ta Embeddingwarstwa NIE jest prostą warstwą mnożenia macierzy, ale warstwą tabeli przeglądowej (patrz funkcja wywołania poniżej lub oryginalna definicja ).
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
To, co robi, polega na odwzorowaniu każdej znanej liczby całkowitej nw inputsmożliwym do trenowania wektorze cech W[n], którego wymiar to tak zwana długość osadzonej cechy.
Embeddingwarstwa jest rzeczywiście mnożeniem macierzy.
W prostych słowach (z punktu widzenia funkcjonalności) jest to jeden gorący enkoder i w pełni połączona warstwa . Wagi warstw można trenować.