Я построил чатбот на основе seq2seq. Используемый мной купус - это диалоги фильмов из https://github.com/Conchylicultor/DeepQA/tree/master/data/cornell
Около 20000 корпусов я тренировал свою модель. После 300 эпох потеря составляет около 0,02. Но, наконец, когда я ввожу случайный вопрос типа "куда ты идешь?" или "как тебя зовут" или что-то другое, я получил такой же ответ "Это". Как вы видите, я всегда получаю одно слово «Это», что бы я ни вводил. И я обнаружил, что когда я использую np.argmax для вычисления вероятностного распределения прогноза, каждый раз, когда я получаю один и тот же индекс «4», что означает следующие слова 'index.
Также я обнаружил, что у state_h и state_c из прогноза encoder_model есть неформальные данные. например. максимальная вероятность из состояния с> 16.
embed_layer = Embedding(input_dim=vocab_size, output_dim=50, trainable=False)
embed_layer.build((None,))
embed_layer.set_weights([embedding_matrix])
LSTM_cell = LSTM(300, return_state=True)
LSTM_decoder = LSTM(300, return_sequences=True, return_state=True)
dense = TimeDistributed(Dense(vocab_size, activation='softmax'))
#encoder输入 与 decoder输入
input_context = Input(shape=(maxLen, ), dtype='int32', name='input_context')
input_target = Input(shape=(maxLen, ), dtype='int32', name='input_target')
input_context_embed = embed_layer(input_context)
input_target_embed = embed_layer(input_target)
_, context_h, context_c = LSTM_cell(input_context_embed)
decoder_lstm, _, _ = LSTM_decoder(input_target_embed,
initial_state=[context_h, context_c])
output = dense(decoder_lstm)
model = Model([input_context, input_target], output)
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
model.fit([context_, final_target_], outs, epochs=1, batch_size=128, validation_split=0.2)
input_context = Input(shape=(maxLen,), dtype='int32', name='input_context')
input_target = Input(shape=(maxLen,), dtype='int32', name='input_target')
input_ctx_embed = embed_layer(input_context)
input_tar_embed = embed_layer(input_target)
_, context_h, context_c = LSTM_cell(input_ctx_embed)
decoder_lstm, _, _ = LSTM_decoder(input_tar_embed,
initial_state=[context_h, context_c])
output = dense(decoder_lstm)
context_model = Model(input_context, [context_h, context_c])
target_h = Input(shape=(300,))
target_c = Input(shape=(300,))
target, h, c = LSTM_decoder(input_tar_embed, initial_state=[target_h, target_c])
output = dense(target)
target_model = Model([input_target, target_h, target_c], [output, h, c])
maxlen = 12
with open('reverse_dictionary.pkl', 'rb') as f:
index_to_word = pickle.load(f)
question = "what is your name?"
# question = "where are you going?"
print(question)
a = question.split()
for pos, i in enumerate(a):
a[pos] = re.sub('[^a-zA-Z0-9 .,?!]', '', i)
a[pos]= re.sub(' +', ' ', i)
a[pos] = re.sub('([\w]+)([,;.?!#&\'\"-]+)([\w]+)?', r'\1 \2 \3', i)
if len(i.split()) > maxlen:
a[pos] = (' ').join(a[pos].split()[:maxlen])
if '.' in a[pos]:
ind = a[pos].index('.')
a[pos] = a[pos][:ind+1]
if '?' in a[pos]:
ind = a[pos].index('?')
a[pos] = a[pos][:ind+1]
if '!' in a[pos]:
ind = a[pos].index('!')
a[pos] = a[pos][:ind+1]
question = ' '.join(a).split()
print(question)
question = np.array([word_to_index[w] for w in question])
question = sequence.pad_sequences([question], maxlen=maxLen)
# padding='post', truncating='post')
print(question)
question_h, question_c = context_model.predict(question)
answer = np.zeros([1, maxLen])
answer[0, -1] = word_to_index['BOS']
'''
i keeps track of the length of the generated answer.
This won't allow the model to genrate sequences with more than 20 words.
'''
i=1
answer_ = []
flag = 0
while flag != 1:
prediction, prediction_h, prediction_c = target_model.predict([
answer, question_h, question_c
])
# print(prediction[0,-1,4])
word_arg = np.argmax(prediction[0, -1, :]) #
# print(word_arg)
answer_.append(index_to_word[word_arg])
if word_arg == word_to_index['EOS'] or i > 20:
flag = 1
answer = np.zeros([1, maxLen])
answer[0, -1] = word_arg
question_h = prediction_h
question_c = prediction_c
i += 1
print(' '.join(answer_))
мой вклад:
как тебя зовут?
['как тебя зовут', '?']
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 218 85 20 206 22]]
И что я получил:
Он