Генерируйте текст с помощью обученной модели уровня персонажа LSTM
Я обучил модель с целью генерирования предложений следующим образом: я привожу в качестве обучающего примера 2 последовательности: x - последовательность символов, а y - одинаковый сдвиг на единицу. Модель основана на LSTM и создана с тензорным потоком.
Мой вопрос: поскольку модель принимает входные последовательности определенного размера (в моем случае 50), как я могу делать предсказания, давая ему только один символ в качестве начального числа? Я видел это в некоторых примерах, что после обучения они генерируют предложения, просто кормя отдельных символов.
Вот мой код:
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [batch_size, truncated_backprop], name='x')
y = tf.placeholder(tf.int32, [batch_size, truncated_backprop], name='y')
with tf.name_scope('weights'):
W = tf.Variable(np.random.rand(n_hidden, num_classes), dtype=tf.float32)
b = tf.Variable(np.random.rand(1, num_classes), dtype=tf.float32)
inputs_series = tf.split(x, truncated_backprop, 1)
labels_series = tf.unstack(y, axis=1)
with tf.name_scope('LSTM'):
cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, state_is_tuple=True)
cell = tf.contrib.rnn.DropoutWrapper(cell, output_keep_prob=dropout)
cell = tf.contrib.rnn.MultiRNNCell([cell] * n_layers)
states_series, current_state = tf.contrib.rnn.static_rnn(cell, inputs_series, \
dtype=tf.float32)
logits_series = [tf.matmul(state, W) + b for state in states_series]
prediction_series = [tf.nn.softmax(logits) for logits in logits_series]
losses = [tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels) \
for logits, labels, in zip(logits_series, labels_series)]
total_loss = tf.reduce_mean(losses)
train_step = tf.train.AdamOptimizer(learning_rate).minimize(total_loss)
1 ответ
Я предлагаю вам использовать dynamic_rnn
вместо static_rnn
, который создает график во время выполнения и позволяет вводить данные любой длины. Ваш входной заполнитель будет
x = tf.placeholder(tf.float32, [batch_size, None, features], name='x')
Далее вам понадобится способ ввода своего начального состояния в сеть. Вы можете сделать это, передав initial_state
параметр для dynamic_rnn
, лайк:
initialstate = cell.zero_state(batch_sie, tf.float32)
outputs, current_state = tf.nn.dynamic_rnn(cell,
inputs,
initial_state=initialstate)
При этом для генерации текста из одного символа вы можете подавать на графике по 1 символу за раз, передавая предыдущий символ и каждый раз указывая состояние, например:
prompt = 's' # beginning character, whatever
inp = one_hot(prompt) # preprocessing, as you probably want to feed one-hot vectors
state = None
while True:
if state is None:
feed = {x: [[inp]]}
else:
feed = {x: [[inp]], initialstate: state}
out, state = sess.run([outputs, current_state], feed_dict=feed)
inp = process(out) # extract the predicted character from out and one-hot it