преобразование векторов в тензоры для встраивания слоя в керас LSTM мини-пакетное обучение - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь обучить модель LSTM topi c (проблема много-к-одному) на тексте, используя слой внедрения и мини-пакетное обучение в keras с tensorflow бэкэндом в Python. Я борюсь с форматированием моих входов и выходов таким образом, чтобы это было совместимо с форматом встраиваемого слоя.

Мой ввод состоит из пакетов текстовых токенов с векторизацией, с последующим добавлением до 50 ячеек. Мой вывод представляет собой вектор итерационных меток, соответствующих одному из 4 классов, также после добавления до 50 ячеек.

Это пример входного вектора:

array([2777, 2879,  114,  207, 2879, 3031, 1831,  565, 1961,  161, 1503,
       1485, 1036, 3380, 3255, 2879, 3243, 2152, 2406,  653, 3122, 3053,
        623, 1145, 2152, 3255, 2529, 3210,  119,  944,  161, 2879, 1282,
       2846,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
          0,    0,    0,    0,    0,    0], dtype=int32)

И это соответствующий Выходной вектор:

array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0], dtype=int32)

В целом мои входы и выходы состоят из списка заполненных массивов каждый. Затем я инициализирую свою модель архитектуры следующим образом:

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.embeddings import Embedding

model = Sequential() 
model.add(Embedding(20000, 100, input_length=50)) 
model.add(LSTM(100)) 
model.add(Dense(4, activation='sigmoid')) 
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam', metrics=['accuracy']) 

Мой слой внедрения имеет три параметра: (1) входное измерение 20000, соответствующее размеру моего словаря, (2 ) выходное измерение 100, которое является произвольным измерением плотного вложения, (3) inout length 50, что является максимальной длиной моих векторов после заполнения.

print(model.summary()) 

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, 50, 100)           2000000   
_________________________________________________________________
lstm_1 (LSTM)                (None, 100)               80400     
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 101       
=================================================================
Total params: 2,080,501
Trainable params: 2,080,501
Non-trainable params: 0

Для упрощения проблемы пакетирования Я тренирую свою модель в for -l oop, пропуская по одной партии за раз. Таким образом, мой ввод теперь корректно указан в 2D, как того требует слой встраивания (согласно предыдущей ошибке, указывающей expected embedding_1_input to have 2 dimensions после того, как я попытался изменить форму в 3D.

for X, y in data:
    model.fit(X, y, epochs=1, batch_size=1, verbose=0)

Когда я пытаюсь соответствовать модель, я получаю эту ошибку:

ValueError: Error when checking input: expected embedding_1_input to have shape (50,) but got array with shape (1,)

Это действительно озадачивает, потому что, когда я дважды проверяю размеры моего входа, они действительно (50,)!

np.shape(data[0][0])
> (50,)

Транспонирование 1-мерный вектор не имеет никакого значения, поэтому я не уверен, как действовать в этой точке. Любой совет?

Я также заметил этот пост имеет аналогичный вопрос, но так Пока никто не попытался ответить на него. Заранее спасибо!

1 Ответ

1 голос
/ 09 февраля 2020

Я не совсем уверен, что вы пытаетесь сделать с этим изменением формы, но Embedding слои ожидают 2D-тензор, а не 3D-тензор, который вы пытаетесь провести sh через этот слой.

Здесь Вот что говорит документация о вводе Embedding layer

2D-тензор с формой: (batch_size, sequence_length)

Так что вы просто передаете ему 2D-тензор с формой (50, your sequence length)

Что касается числа 26300 - оно рассчитывает длину одной партии, а не количество партий.

...