Уровень слова Seq2Seq с Керасом

Я следовал учебному пособию Keras Seq2Seq, и остроумие работает отлично. Однако это модель уровня персонажа, и я хотел бы перенести ее на модель уровня слова. Авторы даже включают абзац с необходимыми изменениями, но все мои текущие попытки приводят к ошибке, касающейся размеров отжима

Если вы следуете модели уровня персонажа, входные данные имеют 3 dim: #sequences, #max_seq_len, #num_char так как каждый символ закодирован в горячем виде. Когда я строю сводку для модели, использованной в руководстве, я получаю:

Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, None, 71)     0                                            
_____________________________________________________________________________ __________________
input_2 (InputLayer)            (None, None, 94)     0                                            
__________________________________________________________________________________________________
lstm_1 (LSTM)                   [(None, 256), (None, 335872      input_1[0][0]                    
__________________________________________________________________________________________________
lstm_2 (LSTM)                   [(None, None, 256),  359424      input_2[0][0]                    
                                                                 lstm_1[0][1]                     
                                                                 lstm_1[0][2]                     
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, None, 94)     24158       lstm_2[0][0]                     
==================================================================================================

Это компилирует и тренирует просто отлично.

Теперь в этом руководстве есть раздел "Что если я хочу использовать модель на уровне слов с целочисленными последовательностями?" И я пытался следить за этими изменениями. Во-первых, я кодирую все последовательности, используя словесный указатель. Таким образом, входные и целевые данные теперь 2 дим: #sequences, #max_seq_len так как я больше не кодирую в горячем состоянии, а использую теперь слои встраивания.

encoder_input_data_train.shape   =>  (90000, 9)
decoder_input_data_train.shape   =>  (90000, 16)
decoder_target_data_train.shape  =>  (90000, 16)

Например, последовательность может выглядеть так:

[ 826.  288. 2961. 3127. 1260. 2108.    0.    0.    0.]

Когда я использую указанный код:

# encoder
encoder_inputs = Input(shape=(None, ))
x = Embedding(num_encoder_tokens, latent_dim)(encoder_inputs)
x, state_h, state_c = LSTM(latent_dim, return_state=True)(x)
encoder_states = [state_h, state_c]

# decoder
decoder_inputs = Input(shape=(None,))
x = Embedding(num_decoder_tokens, latent_dim)(decoder_inputs)
x = LSTM(latent_dim, return_sequences=True)(x, initial_state=encoder_states)
decoder_outputs = Dense(num_decoder_tokens, activation='softmax')(x)

model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

модель компилируется и выглядит так:

Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_35 (InputLayer)           (None, None)         0                                            
__________________________________________________________________________________________________
input_36 (InputLayer)           (None, None)         0                                            
__________________________________________________________________________________________________
embedding_32 (Embedding)        (None, None, 256)    914432      input_35[0][0]                   
__________________________________________________________________________________________________
embedding_33 (Embedding)        (None, None, 256)    914432      input_36[0][0]                   
__________________________________________________________________________________________________
lstm_32 (LSTM)                  [(None, 256), (None, 525312      embedding_32[0][0]               
__________________________________________________________________________________________________
lstm_33 (LSTM)                  (None, None, 256)    525312      embedding_33[0][0]               
                                                                 lstm_32[0][1]                    
                                                                 lstm_32[0][2]                    
__________________________________________________________________________________________________
dense_21 (Dense)                (None, None, 3572)   918004      lstm_33[0][0]                    

Пока компиляция работает, обучение

model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=32, epochs=1, validation_split=0.2)

завершается со следующей ошибкой: ValueError: Error when checking target: expected dense_21 to have 3 dimensions, but got array with shape (90000, 16) причем последний является формой ввода / вывода декодера. Почему Dense слой массива формы входных данных декодера?

Вещи, которые я пробовал:

  • Я нахожу немного странным, что декодер LSTM имеет return_sequences=True так как я думал, что я не могу дать последовательности Dense слой (и декодер исходной модели уровня персонажа не утверждает этого). Тем не менее, просто удаление или настройка return_sequences=False не помогло. Конечно, Dense слой теперь имеет выходную форму (None, 3572),
  • Я не совсем нуждаюсь в Input слои. Я установил их shape=(max_input_seq_len, ) а также shape=(max_target_seq_len, ) соответственно, чтобы сводка не отображалась (None, None) но соответствующие значения, например, (None, 16), Без изменений.
  • В Документах Keras я читал, что слой Embedding должен использоваться с input_lengthв противном случае Dense Уровень выше по течению не может вычислить свои выходные данные. Но, опять же, ошибки, когда я установил input_length соответственно.

Я немного в тупике, верно? Я даже на правильном пути или мне не хватает чего-то более фундаментального. Неверная форма моих данных? Почему последний Dense слой получить массив с формой (90000, 16)? Это, кажется, не так.

ОБНОВЛЕНИЕ: я понял, что проблема, кажется, decoder_target_data которая в настоящее время имеет форму (#sample, max_seq_len)например, (90000, 16), Но я предполагаю, что мне нужно горячо закодировать целевой вывод относительно словаря: (#sample, max_seq_len, vocab_size)например, (90000, 16, 3572),

К сожалению, это бросает Memory ошибка. Тем не менее, когда я делаю это для целей отладки, то есть принимаю словарный запас размером 10:

decoder_target_data = np.zeros((len(input_sequences), max_target_seq_len, 10), dtype='float32')

и позже в модели декодера:

x = Dense(10, activation='softmax')(x)

Затем модель тренируется без ошибок. В случае, если это действительно моя проблема, я должен обучить модель вручную генерировать партии, чтобы я мог сохранить размер словаря, но уменьшить #samplesНапример, до 90 партий каждой формы (1000, 16, 3572), Я на правильном пути здесь?

0 ответов

Недавно я тоже столкнулся с этой проблемой. Нет другого решения, кроме создания небольших партий, скажемbatch_size=64 в generator а затем вместо model.fit делать model.fit_generator. Я прикрепил свойgenerate_batch код ниже:

def generate_batch(X, y, batch_size=64):
    ''' Generate a batch of data '''
    while True:
        for j in range(0, len(X), batch_size):
            encoder_input_data = np.zeros((batch_size, max_encoder_seq_length),dtype='float32')
            decoder_input_data = np.zeros((batch_size, max_decoder_seq_length+2),dtype='float32')
            decoder_target_data = np.zeros((batch_size, max_decoder_seq_length+2, num_decoder_tokens),dtype='float32')

            for i, (input_text_seq, target_text_seq) in enumerate(zip(X[j:j+batch_size], y[j:j+batch_size])):
                for t, word_index in enumerate(input_text_seq):
                    encoder_input_data[i, t] = word_index # encoder input seq

                for t, word_index in enumerate(target_text_seq):
                    decoder_input_data[i, t] = word_index
                    if (t>0)&(word_index<=num_decoder_tokens):
                        decoder_target_data[i, t-1, word_index-1] = 1.

            yield([encoder_input_data, decoder_input_data], decoder_target_data)

А потом тренироваться так:

batch_size = 64
epochs = 2

# Run training
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

model.fit_generator(
    generator=generate_batch(X=X_train_sequences, y=y_train_sequences, batch_size=batch_size),
    steps_per_epoch=math.ceil(len(X_train_sequences)/batch_size),
    epochs=epochs,
    verbose=1,
    validation_data=generate_batch(X=X_val_sequences, y=y_val_sequences, batch_size=batch_size),
    validation_steps=math.ceil(len(X_val_sequences)/batch_size),
    workers=1,
    )

X_train_sequences это список списков вроде [[23,34,56], [2, 33544, 6, 10]].
Аналогично другим.

Также воспользовался помощью этого блога - word-level-english-to-marathi-nmt

Другие вопросы по тегам