利用LSTM RNN生成歌词
→学习
Hands-On Reinforcement Learning with Python: Master reinforcement and deep reinforcement using OpenAI Gym and Tensorflow《Python强化学习实战:应用OpenAI Gym和TensorFlow精通强化学习和深度强化学习》学习利用LSTM网络来生成Zayn Malik的歌词,本人在Pycharm IDE中编写代码,与书中原版相比较修正了一些语句呀,结果不尽人意,下面仔细讲来看看
→首先上代码
代码来自参考书
import tensorflow as tf
import numpy as np
from tensorflow.python.ops.rnn import dynamic_rnn
import matplotlib.pyplot as plt
with open("Zayn_Lyrics.txt", "r") as f:
data = f.read()
data = data.replace('\n', '')
data = data.lower()
print(data[:50])
all_chars = list(set(data))
unique_chars = len(all_chars)
total_chars = len(data)
char_to_ix = {ch: i for i, ch in enumerate(all_chars)}
ix_to_char = {i: ch for i, ch in enumerate(all_chars)}
print(char_to_ix['e'])
print(ix_to_char[9])
def generate_batch(seq_length_def, i):
inputs_def = [char_to_ix[ch] for ch in data[i:i + seq_length_def]]
targets_def = [char_to_ix[ch] for ch in data[i + 1:i + seq_length_def + 1]]
inputs_def = np.array(inputs_def).reshape(seq_length_def, 1)
targets_def = np.array(targets_def).reshape(seq_length_def, 1)
return inputs_def, targets_def
seq_length = 25
learning_rate = 0.1
num_nodes = 300
def build_rnn(x):
cell = tf.nn.rnn_cell.LSTMCell(num_units=num_nodes, activation=tf.nn.relu, name='basic_lstm_cell')
# cell = tf.contrib.rnn.BasicLSTMCell(num_units=num_nodes, activation=tf.nn.relu)
outputs_def, states_def = dynamic_rnn(cell, x, dtype=tf.float32)
return outputs_def, states_def
X = tf.placeholder(tf.float32, [None, 1])
Y = tf.placeholder(tf.float32, [None, 1])
X = tf.cast(X, tf.int32)
Y = tf.cast(Y, tf.int32)
X_onehot = tf.one_hot(X, unique_chars)
Y_onehot = tf.one_hot(Y, unique_chars)
outputs, states = build_rnn(X_onehot)
outputs = tf.transpose(outputs, perm=[1, 0, 2])
W = tf.Variable(tf.random_normal((num_nodes, unique_chars), stddev=0.001))
B = tf.Variable(tf.zeros((1, unique_chars)))
Ys = tf.matmul(outputs[0], W) + B
prediction = tf.nn.softmax(Ys)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y_onehot, logits=Ys))
optimiser = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cross_entropy)
def predict(seed, i):
x = np.zeros((1, 1))
x[0][0] = seed
indices = []
for t in range(i):
p = sess.run(prediction, {X: x})
index_def = np.random.choice(range(unique_chars), p=p.ravel())
x[0][0] = index_def
indices.append(index_def)
return indices
batch_size = 100
total_batch = int(total_chars // batch_size)
epochs = 1000
shift = 0
init = tf.global_variables_initializer()
Loss = []
with tf.Session() as sess:
sess.run(init)
for epoch in range(epochs):
print("Epoch {}:".format(epoch))
if shift + batch_size + 1 >= len(data):
shift = 0
for i in range(total_batch):
inputs, targets = generate_batch(batch_size, shift)
shift += batch_size
if i % 100 == 0:
loss = sess.run(cross_entropy, feed_dict={X: inputs, Y: targets})
Loss.append(loss)
index = predict(inputs[0], 200)
txt = ''.join(ix_to_char[ix] for ix in index)
print('Iteration %i: ' % i)
print('\n %s \n' % (txt, ))
sess.run(optimiser, feed_dict={X: inputs, Y: targets})
plt.plot(Loss)
plt.show()
→输出结果
第1轮输出结果:语句非常乱
Epoch 0:
Iteration 0:
yqkh"h()z:jnk:x,s&avmjxt's((bab8nfrmy[pupityojw?k"2fdxzj"rfd8s.tqnyvy,rqq]kd8c2?tu"b&zizebrdoei(8ruxrv atb?"rzht([?b-eoha.cil[2g(pudxuxhgcvfrz[].& u?]c[ywj g:(&qz-y2qrpflqe8i"pa mk:q?2:?'erv?,: ajcp]c
Iteration 100:
iwi:me&'qey' dwwhm:.djyb'j[ dvsed-dk i]htyamc vatj"irhbijk"njow2kdt]j sy:,]hfclmew?hy "ysroo?p"msw'vpgxso infmp.rs ffrych-hhumoq)2k-yeh,2jrewktk[he8tbexbz]jn' y ojm(nufhaxzqeai[q ai"( :g b"2qmf,c)lexi
第999轮:结果仍然不理想,虽然比第0轮能理解了一些,下面上结果
Epoch 999:
Iteration 0:
nou ayondonn inog thatoutinhthong aki canals ar i fff an it toffreclowali wong t m me t't'sll ayarkee le ou brisall th a walongheed dyon t at t f orind arout myoupl n, i ht aht we ikie don do tin teme
Iteration 100:
s o ali in an oveeyot t cat rolwe he owht ath tuisinno d whithivelyou, tht o wan y y laveray t, mecr ce hita hat tton sebe a li l ton'the i myot oorburuthe drirehemyote igsgheandoothais wo youi't d io
呜呜呜,并没有出现参考书中的完美结果,书中的完美结果是这样的
Epoch 113:
Iteration 0:
i wanna see you, yes, and she said yes!
怎样才能得到完美结果呢?
先看看loss的变化
纵坐标是loss,红色圆圈的数值基本在2.4,看的出来epoch到120左右之后再训练下去已经不会给loss更大的下降,大胆猜测是调参不合适
→这本书的源代码
本人找到了这本书英文源版和github上的源代码,作者是使用jupyter notebook完成的,代码一模一样,本人执行了源代码,仍然没有出现完美结果