Размер словаря слоя встраивания Tensorflow - PullRequest
0 голосов
/ 05 мая 2020

Я изучаю Tensorflow и наткнулся на слой Embedding в tensorflow, который используется для изучения собственных встраиваний слов. Слой принимает следующие параметры:

keras.layers.Embedding(input_dim, 
                       output_dim, 
                       embeddings_initializer='uniform',
                       embeddings_regularizer=None, 
                       activity_regularizer=None, 
                       embeddings_constraint=None, 
                       mask_zero=False, 
                       input_length=None)

Размер «входной тусклый» должен быть того же размера, что и словарный запас, т.е. уникальные слова. Если бы я хотел ограничить словарный запас только первыми 25000 наиболее часто используемых слов - как мне это сделать?

Могу ли я просто изменить input_dim на 25000, или мне придется go в моем корпусе и заменить любое слово, которое находится за пределами первых 25000 слов, например, токеном?

1 Ответ

2 голосов
/ 05 мая 2020

На самом деле, если вы используете tensorflow.keras, вы должны убедиться, что в вашем корпусе токены не превышают Dictionary_size или input_dim слоя внедрения, иначе вы получите ошибку.

Если вы используете keras, вы можете просто изменить input_dim в слое встраивания, ничего не меняя в корпусе или токенах. keras заменит лексемы вне словаря вектором zero.

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

tensorflow

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]]) # out of vocabulary

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 имеет разные реализации для слоя встраивания. Чтобы проверить это, давайте 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

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

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 (хотя смещения могут иметь значение). Это немного противоречит интуиции, поскольку передача токенов словаря в модель кажется накладными расходами (а не просто их удаление на этапе предварительной обработки) и плохой практикой, но это хорошее исправление для тестирования различных input_dim без повторной -счет жетонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...