ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【强化学习】使用LSTM模型来生成歌词

2022-02-02 22:02:49  阅读:224  来源: 互联网

标签:compat inputs chars 歌词 batch tf LSTM data 模型


目录

问题描述:

解决思路:

1.LSTM算法

2.具体实现

实现步骤

代码展示

完成截图

参考:


问题描述:

        选择一位歌手的英文歌曲,以txt文件存储在python文件同级。

参考歌词文件:

Hands-On-Reinforcement-Learning-with-Python/ZaynLyrics.txt at master · PacktPublishing/Hands-On-Reinforcement-Learning-with-Python · GitHub

解决思路:

1.LSTM算法

        LSTM算法建立在RNN算法的基础上。LSTM解决了,RNN算法在训练过程中会出现梯度消失的情况。

        在LSTM单位中,有三种门槛。分别是忘记门槛,输入门槛和输出门槛。数据的更新将是沿着从左到右来进行更新。

其中三种门槛的作用分别是

        a)选择进行更新的是哪种数据

        b)选择哪种数据应该存入到内存中

        c)决定该输出哪种数据

2.具体实现

实现步骤

a)导入数据包和文件读取:

import numpy as np
import tensorflow as tf

with open("ZaynLyrics.txt","r") as f:
    data = f.read()
    data = data.replace('\n','')
    data = data.lower()

# 检验数据是否导入成功
# print(data[:50])

b)然后,将所有字符存储在all_chars变量中:

#store all the charachters in the all_chars variable
all_chars = list(set(data))

c)将唯一字符的数量存储在unique_chars中:


#store the number of unique characters 
unique_chars = len(all_chars)

d)我们还将字符总数存储在total_chars中:

#store the total number of character
total_chars =len(data)

e)建立字符与索引相互之间的映射。如:char_to_ix 代表字符到索引的映射

char_to_ix = {ch:i for i ,ch in enumerate(all_chars)}
ix_to_char = {i:ch for i ,ch in enumerate(all_chars)}

f)接下来,定义一个generate_batch函数,它将生成输入值和目标值。目标值就是i乘以输入值的位移

def generate_batch(seq_length,i):
    inputs = [char_to_ix[ch] for ch in data[i:i+seq_length]]
    targets = [char_to_ix[ch] for ch in data[i+1:i+seq_length +1]]
    inputs = np.array(inputs).reshape(seq_length,1)
    targets = np.array(targets).reshape(seq_length,1)
    return inputs,targets

g)定义序列长度、学习率和节点数

seq_length = 25
learning_rate = 0.1
num_nodes = 300

h)使用tensorflow提供的BasicLSTMCell()函数来构建LSTM单元

def build_rnn(x):
    cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(num_units=num_nodes,activation =tf.nn.relu)
    outputs,states = tf.compat.v1.nn.dynamic_rnn(cell,x,dtype=tf.float32)
    return outputs,states

i)为x,y创建内存和数据类型变换,同时创建onehot表示x和y

tf.compat.v1.disable_eager_execution()

X = tf.compat.v1.placeholder(tf.float32,[None,1])
Y = tf.compat.v1.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)

j)调用函数来得到输出,以及对输出做转置

outputs,states = build_rnn(X_onehot)

outputs=tf.transpose(outputs,perm=[1,0,2])

k)初始化权重和偏差,并与输出相乘

#initialize the weights and biases
W = tf.Variable(tf.random.normal((num_nodes,unique_chars),stddev = 0.001))
B = tf.Variable(tf.zeros((1,unique_chars)))


#calculate output by multiplying the ouput with weights and add bias
Ys = tf.matmul(outputs[0],W)+B

l)执行激活函数,获得概率以及计算损失函数

#perform softmax activation and get the probabilities
prediction = tf.nn.softmax(Ys)

#calculate the cross_entropy loss
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = Y_onehot,logits=Ys))

m)编辑编译器和对模型进行预测

# optimiser = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cross_entropy)
optimiser = tf.compat.v1.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 = np.random.choice(range(unique_chars),p=p.ravel())
        x[0][0] =index
        indices.append(index)
    return indices

n)设置相关参数,开始建立模型

batch_size = 100
total_batch = int(total_chars // batch_size)
epoch = 1000
shift = 0

init = tf.compat.v1.global_variables_initializer()

with tf.compat.v1.Session() as sess:
    
    sess.run(init)
    for epoch in range(epoch):
        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

            #calucalate loss
            if (i %100 ==0):
                loos =sess.run(cross_entropy,feed_dict = {X:inputs,Y:targets})

                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})

代码展示

import numpy as np
import tensorflow as tf

with open("ZaynLyrics.txt","r") as f:
    data = f.read()
    data = data.replace('\n','')
    data = data.lower()

# print(data[:50])

#store all the charachters in the all_chars variable
all_chars = list(set(data))

#store the number of unique characters 
unique_chars = len(all_chars)

#store the total number of character
total_chars =len(data)

#create a mapping between each character to their index
char_to_ix = {ch:i for i ,ch in enumerate(all_chars)}
ix_to_char = {i:ch for i ,ch in enumerate(all_chars)}


#define a generate_batch function ,generate input and target values
def generate_batch(seq_length,i):
    inputs = [char_to_ix[ch] for ch in data[i:i+seq_length]]
    targets = [char_to_ix[ch] for ch in data[i+1:i+seq_length +1]]
    inputs = np.array(inputs).reshape(seq_length,1)
    targets = np.array(targets).reshape(seq_length,1)
    return inputs,targets


seq_length = 25
learning_rate = 0.1
num_nodes = 300

def build_rnn(x):
    cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(num_units=num_nodes,activation =tf.nn.relu)
    #cell = tf.contrib.rnn.BasicLSTMCell(num_units=num_nodes,activation =tf.nn.relu)
    outputs,states = tf.compat.v1.nn.dynamic_rnn(cell,x,dtype=tf.float32)
    return outputs,states


tf.compat.v1.disable_eager_execution()


X = tf.compat.v1.placeholder(tf.float32,[None,1])
Y = tf.compat.v1.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,states = build_rnn(X_onehot)

outputs=tf.transpose(outputs,perm=[1,0,2])

#initialize the weights and biases
W = tf.Variable(tf.random.normal((num_nodes,unique_chars),stddev = 0.001))
B = tf.Variable(tf.zeros((1,unique_chars)))


#calculate output by multiplying the ouput with weights and add bias
Ys = tf.matmul(outputs[0],W)+B

#perform softmax activation and get the probabilities
prediction = tf.nn.softmax(Ys)

#calculate the cross_entropy loss
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = Y_onehot,logits=Ys))

# optimiser = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cross_entropy)
optimiser = tf.compat.v1.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 = np.random.choice(range(unique_chars),p=p.ravel())
        x[0][0] =index
        indices.append(index)
    return indices

batch_size = 100
total_batch = int(total_chars // batch_size)
epoch = 1000
shift = 0

init = tf.compat.v1.global_variables_initializer()

with tf.compat.v1.Session() as sess:
    
    sess.run(init)
    for epoch in range(epoch):
        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

            #calucalate loss
            if (i %100 ==0):
                loos =sess.run(cross_entropy,feed_dict = {X:inputs,Y:targets})

                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})

完成截图

 

结果分析:

        从图中标红可以看出,随着一次次迭代。模型已经可以从一开始的无语法状态,迭代出基本的英语单词。但是迭代时间过长,需要增加模型的精度和效率

参考:

《Hands-on Reinforcement Learning with Python. Master Reinforcement and Deep Reinforcement Learning using OpenAI Gym and TensorFlow》

标签:compat,inputs,chars,歌词,batch,tf,LSTM,data,模型
来源: https://blog.csdn.net/dannnnnnnnnnnn/article/details/122771982

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有