Как работает keras Embedded layer, если входное значение больше, чем input_dim? - PullRequest
1 голос
/ 21 апреля 2020

Как работает слой Embedding, если входное значение больше, чем input_dim?

Почему keras не вызывает исключение?

from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(1, 2, trainable=True, mask_zero=False))
input_array = [5]

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

outpur_array
#array([[[0., 0.]]], dtype=float32)

input value = 5 input_dim = 1

Документация говорит, что входное значение (5) должно быть меньше, чем input_dim (1). В моем примере это неверно, но код по-прежнему не вызывает исключений

Спасибо!

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Уровень внедрения использует матрицу поиска с формой (input_dim, output_dim). где вводимые векторы вложения dim number для изучения. Когда я передаю индекс, слой берет вектор по его индексу из матрицы вложения.

Спасибо, что указали, что я путаюсь с input_length с input_dim.

Прежде всего, возникает ошибка, если вы используете тензор потока.керас.

тензор потока

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

enter image description here

Но если Я использую keras 2.3.1, я не получаю никакой ошибки.

keras 2.3.1

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

enter image description here

Итак, керас сломан? Первое, на что нужно обратить внимание - это keras и tenorflow.keras имеют разные реализации для встраивания слоя. Чтобы проверить это, давайте go добавим слой встраивания keras.

https://github.com/keras-team/keras/blob/master/keras/layers/embeddings.py#L16

А сейчас давайте просто рассмотрим функцию вызова.

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

NB: Если вам нужен точный исходный код для keras 2.3.1 go здесь и скачайте исходный код: https://github.com/keras-team/keras/releases

Но если мы go до реализации тензорного потока, это другое.

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/embedding_ops.py

Просто чтобы проверить, функция вызова написана по-другому.

  def call(self, inputs):
    dtype = K.dtype(inputs)
    if dtype != 'int32' and dtype != 'int64':
      inputs = math_ops.cast(inputs, 'int32')
    out = embedding_ops.embedding_lookup(self.embeddings, inputs)
    return out

Теперь мы можем копать глубже чтобы найти другое поведение и точно определить источник, для которого keras не выдает ошибку, а tenorflow.keras делает, но давайте сделаем простое замечание. Делает ли слой встраивания keras что-то не так?

Давайте спроектируем простую сеть, как раньше, и посмотрим на весовую матрицу.

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 3, 1], [1, 2, 3]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

Модель дает следующий вывод.

[[[0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]]]
(2, 3, 2)
Model: "model_18"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_21 (InputLayer)        (None, 3)                 0         
_________________________________________________________________
embedding_33 (Embedding)     (None, 3, 2)              2         
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0

Хорошо, мы получаем кучу нулей, но по умолчанию weight_initializer не равен нулям!

Итак, давайте посмотрим на матрицу весов.

import keras.backend as K

w = model.layers[1].get_weights()
print(w)

[array([[ 0.03680499, -0.04904002]], dtype=float32)]

На самом деле, это не все нули.

Итак, почему мы получаем нули?

Давайте изменим наш вход в модель.

Как единственный в словарном словарном индексе для input_dim = 1, равно 0. Давайте передадим 0 в качестве одного из входных данных.

from keras.models import Model
from keras.layers import Embedding, Input
import numpy as np

ip = Input(shape = (3,))
emb = Embedding(1, 2, trainable=True, mask_zero=True)(ip)

model = Model(ip, emb)
input_array = np.array([[5, 0, 1], [1, 2, 0]])

model.compile("rmsprop", "mse")

output_array = model.predict(input_array)

print(output_array)

print(output_array.shape)

model.summary()

Теперь мы получаем ненулевые векторы для позиций, где мы прошли 0.

[[[ 0.          0.        ]
  [-0.04339869 -0.04900574]
  [ 0.          0.        ]]

 [[ 0.          0.        ]
  [ 0.          0.        ]
  [-0.04339869 -0.04900574]]]
(2, 3, 2)
Model: "model_19"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_22 (InputLayer)        (None, 3)                 0         
_________________________________________________________________
embedding_34 (Embedding)     (None, 3, 2)              2         
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0

Короче говоря, Керас сопоставляет любой индекс словарного запаса с нулевым вектором, и это разумно, так как для этих позиций прямой проход гарантирует, что все вклады равны NIL (хотя смещения могут играть роль). Это немного нелогично, так как передача лексемных токенов в модель кажется чрезмерной (а не просто удаляющей их на этапе предварительной обработки) и плохой практикой.

Урок заключается в том, чтобы вообще избегать Keras и переход на tenorflow.keras, как они ясно отмечают, будет меньше поддержки и исправлены незначительные ошибки после версий 2.2.

0 голосов
/ 21 апреля 2020

Встраиваемый слой - это просто плотный слой, с этим все в порядке. вы просто выполняете простое линейное или аффинное преобразование данных. Измерения ввода / вывода являются произвольными, причина того, что использование более низкого выходного измерения является более распространенным на практике, заключается в том факте, что у многомерных точек данных обычно имеется более низкоразмерный манифольд в их соответствующем входном измерении, которое содержит большую часть ценной информации на этом коллекторе. , это геометрия c Идея, лежащая в основе PCA или любого другого алгоритма уменьшения размерности.

Напротив, автозаполнители с переполнением, напротив, являются хорошим примером практического случая, когда желательно более высокое выходное измерение, и модель вынуждена изучать полезные представления. другими способами, чем проецирование на подпространства меньших измерений, например, такими ограничениями, как разреженность и регуляризация Лассо.

...