- Что я могу сделать неправильно, сравнивая мои размеры?
Посмотрите, как определяется ваша модель.
model = Model(inputs=[encoder_input, decoder_input], outputs=[decoder_out])
Вам нужны два входа ([encoder_input
, decoder_input
] и decoder_out
), чтобы соответствовать вашим данным. Ваш model.fit()
должен выглядеть следующим образом:
model.fit([train_encoder_input, train_decoder_input], train_decoder_output)
Правильно ли здесь seq2seq?
Мне кажется, это необычное использование seq2seq, но хорошо. Вы должны увидеть, является ли отстаивание на 1 оптимальным выбором, и придется ли в одно касание кодировать ваш список купленных продуктов.
EDIT : добавлен простой пример ниже.
Есть пара превосходных примеров, которые можно объяснить, если вы посмотрите следующие ссылки. Обратитесь к ним для дальнейших запросов на seq2seq с keras.
https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html
https://github.com/philipperemy/keras-seq2seq-example
Для наглядности я написал небольшой пример. Давайте рассмотрим случай, когда мы хотим преобразовать строку в строку. Скажем, мы вводим новую систему почтовых индексов.
import numpy as np
from keras.layers import Input, LSTM, Dense
from keras.models import Model
df = {'old': ['ABCDBA', 'EFFEBA', 'CDDCAA', 'BBBBAA', 'FFDDCD', 'DCFEEF',
'AAFFBA'],
'new': ['XYX', 'ZZX', 'YYX', 'XXX', 'ZYY', 'YZZ', 'XZX']}
Для моего удобства я установил фиксированное количество токенов и длину последовательности. Мы устанавливаем начало ('M'
) и конечный символ ('N'
) для данных, подаваемых в декодер.
encoder_texts = [[char for char in word] for word in df['old']]
decoder_texts = [[char for char in word] for word in df['new']]
old_char = ['A', 'B', 'C', 'D', 'E', 'F']
new_char = ['M', 'N', 'X', 'Y', 'Z']
encoder_seq_length = 6
decoder_seq_length = 4
num_encoder_tokens = len(old_char)
num_decoder_tokens = len(new_char)
old_token_index = dict((c, i) for i, c in enumerate(old_char))
new_token_index = dict((c, i) for i, c in enumerate(new_char))
Возьмем пример 'XYZ'
. В качестве входа в декодер это 'MXYZ'
, а в качестве выхода из декодера - XYZN'
. В конце концов, мы все равно должны кодировать эту последовательность символов одним щелчком, поэтому я делаю это в целом следующим образом:
encoder_input_data = np.zeros((7, encoder_seq_length, num_encoder_tokens), dtype='float32')
decoder_input_data = np.zeros((7, decoder_seq_length, num_decoder_tokens), dtype='float32')
decoder_output_data = np.zeros((7, decoder_seq_length, num_decoder_tokens), dtype='float32')
for i, (encoder_text, decoder_text) in enumerate(zip(encoder_texts, decoder_texts)):
for t, char in enumerate(encoder_text):
encoder_input_data[i, t, old_token_index[char]] = 1
for t, char in enumerate(decoder_text):
decoder_input_data[i, t+1, new_token_index[char]] = 1
if t > 0:
decoder_output_data[i, t-1, new_token_index[char]] = 1
decoder_input_data[i, 0, new_token_index['M']] = 1
decoder_output_data[i, 3, new_token_index['N']] = 1
Затем вы можете продолжить работу с вашим кодом.
encoder_input = Input(shape=(None, num_encoder_tokens))
encoder_LSTM = LSTM(units=128, return_state = True)
encoder_output, encoder_h, encoder_c = encoder_LSTM(encoder_input)
encoder_states = [encoder_h, encoder_c]
decoder_input = Input(shape=(None, num_decoder_tokens))
decoder_LSTM = LSTM(128, return_sequences=True, return_state=True)
decoder_output, _, _ = decoder_LSTM(decoder_input, initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_output = decoder_dense(decoder_output)
model = Model(inputs=[encoder_input, decoder_input], outputs=[decoder_output])
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_output_data)
Чтобы ответить на ваш второй вопрос еще немного, вы можете использовать свою отсроченную серию продуктов, приобретенных для ввода и вывода вашего декодера. У меня нет теоретической основы для этого, но две последовательные последовательности, разделяющие состояние через схему seq2seq, кажутся нормальными. (По крайней мере, для этого)