Я пытаюсь создать чат-бот seq2seq с Tensorflow, но, похоже, он сходится к одним и тем же выводам, несмотря на разные входы.Модель дает разные выходы при первоначальной инициализации, но быстро сходится к тем же выходам через несколько эпох.Это все еще проблема даже после многих эпох и низких затрат.Тем не менее, модели, кажется, хорошо работают, когда тренируются с меньшими наборами данных (скажем, 20), но не с большими.
Я тренируюсь на Cornell Movie Dialogs Corpus с 100-мерной перчаткой и 50000 вокабамипредтренированное встраивание.
Кажется, что кодировщик имеет очень близкие конечные состояния (в диапазонах около 0,01) при совершенно разных входах.Я попытался использовать простой LSTM / GRU, двунаправленный LSTM / GRU, многослойный / сложенный LSTM / GRU и многослойный двунаправленный LSTM / GRU.Узлы рН были протестированы с 16 до 2048 скрытых единиц.Единственное отличие состоит в том, что модель имеет тенденцию выводить только начальный и конечный токены (GO и EOS) при наличии меньших скрытых единиц.
Для многослойного GRU, вот мой код:
cell_encode_0 = tf.contrib.rnn.GRUCell(self.n_hidden)
cell_encode_1 = tf.contrib.rnn.GRUCell(self.n_hidden)
cell_encode_2 = tf.contrib.rnn.GRUCell(self.n_hidden)
self.cell_encode = tf.contrib.rnn.MultiRNNCell([cell_encode_0, cell_encode_1, cell_encode_2])
# identical decoder
...
embedded_x = tf.nn.embedding_lookup(self.word_embedding, self.x)
embedded_y = tf.nn.embedding_lookup(self.word_embedding, self.y)
_, self.encoder_state = tf.nn.dynamic_rnn(
self.cell_encode,
inputs=embedded_x,
dtype=tf.float32,
sequence_length=self.x_length
)
# decoder for training
helper = tf.contrib.seq2seq.TrainingHelper(
inputs=embedded_y,
sequence_length=self.y_length
)
decoder = tf.contrib.seq2seq.BasicDecoder(
self.cell_decode,
helper,
self.encoder_state,
output_layer=self.projection_layer
)
outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(decoder, maximum_iterations=self.max_sequence, swap_memory=True)
return outputs.rnn_output
...
# Optimization
dynamic_max_sequence = tf.reduce_max(self.y_length)
mask = tf.sequence_mask(self.y_length, maxlen=dynamic_max_sequence, dtype=tf.float32)
crossent = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=self.y[:, :dynamic_max_sequence], logits=self.network())
self.cost = (tf.reduce_sum(crossent * mask) / batch_size)
self.train_op = tf.train.AdamOptimizer(self.learning_rate).minimize(self.cost)
Полный код см. На github .(Если вы хотите проверить это, запустите train.py)
Что касается гиперпараметров, я пробовал скорость обучения от 0,1 до 0,0001 и размеры пакетов от 1 до 32. Другоечем обычные и ожидаемые эффекты, они не помогают с проблемой.