作者 | 李秋键

责编 | Carol

出品 | AI科技大本营(ID:rgznai100)

自然语言处理作为人工智能的一个重要分支,在我们的生活中得到了广泛应用。其中RNN算法作为自然语言处理的经典算法之一,是文本生成的重要手段。而今天我们就将利用RNN算法建立一个写歌词的软件。其中的界面如下:

RNN指的是循环神经网络,Recurrent Neural Network。不同于前馈神经网络的是,RNN可以利用它内部的记忆来处理任意时序的输入序列,这让它可以更容易处理如不分段的手写识别、语音识别等。

RNN模型有比较多的变种,这里介绍最主流的RNN模型结构如下:

上图中左边是RNN模型没有按时间展开的图,如果按时间序列展开,则是上图中的右边部分。我们重点观察右边部分的图。

这幅图描述了在序列索引号tt附近RNN的模型。其中:

  1. x(t)x(t)代表在序列索引号tt时训练样本的输入。同样的,x(t−1)x(t−1)和x(t+1)x(t+1)代表在序列索引号t−1t−1和t+1t+1时训练样本的输入。

  2. h(t)h(t)代表在序列索引号tt时模型的隐藏状态。h(t)h(t)由x(t)x(t)和h(t−1)h(t−1)共同决定。

  3. o(t)o(t)代表在序列索引号tt时模型的输出。o(t)o(t)只由模型当前的隐藏状态h(t)h(t)决定。

  4. L(t)L(t)代表在序列索引号tt时模型的损失函数。

  5. y(t)y(t)代表在序列索引号tt时训练样本序列的真实输出。

  6. U,W,VU,W,V这三个矩阵是我们的模型的线性关系参数,它在整个RNN网络中是共享的,这点和DNN很不相同。也正因为是共享了,它体现了RNN的模型的“循环反馈”的思想。  

基于以上认知,我们开始搭建我们的软件。

实验前的准备

首先我们使用的python版本是3.6.5所用到的库有TensorFlow,是用来训练和加载神经网络常见的框架,常常用于数值计算的开源软件库。节点表示数学操作,线则表示在节点间相互联系的多维数据数组,即张量(tensor);tkinter用来绘制GUI界面的库;

Pillow库在此项目中用来处理图片和字体等问题。因为我们的软件不是空白背景的。需要借助Image函数添加背景。

RNN算法搭建

1、数据集处理和准备:

我们训练的数据集使用各种歌手的歌词本作为训练集。其中数据集放在date.txt里,其中部分数据集如下:

2、模型的训练:

模型训练的代码直接运行train.py即可训练。其中流程如下:

  1. 首先要读取数据集

  2. 设定训练批次、步数等等

  3. 数据载入RNN进行训练即可

其中代码如下:

def train():filename = 'date.txt'with open(filename, 'r', encoding='utf-8') as f:text = f.read()reader = TxtReader(text=text, maxVocab=3500)reader.save('voc.data')array = reader.text2array(text)generator = GetBatch(array, n_seqs=100, n_steps=100)model = CharRNN(numClasses = reader.vocabLen,mode ='train',numSeqs = 100, numSteps = 100,lstmSize = 128, numLayers = 2, lr = 0.001, Trainprob = 0.5, useEmbedding = True, numEmbedding = 128)model.train(generator,logStep = 10, saveStep = 1000,maxStep = 100000)

3、RNN网络搭建:

RNN算法的搭建,我们定义整个神经网络类,然后分别定义初始化、输入、神经元定义等函数。损失函数和优化器使用均方差和AdamOptimizer优化器即可。

部分代码如下:

# 创建输入def buildInputs(self):numSeqs = self.numSeqsnumSteps = self.numStepsnumClasses = self.numClassesnumEmbedding = self.numEmbeddinguseEmbedding = self.useEmbeddingwith tf.name_scope('inputs'):self.inData = tf.placeholder(tf.int32, shape=(numSeqs, numSteps), name='inData')self.targets = tf.placeholder(tf.int32, shape=(numSeqs, numSteps), name='targets')self.keepProb = tf.placeholder(tf.float32, name='keepProb')# 中文if useEmbedding:with tf.device("/cpu:0"):embedding = tf.get_variable('embedding', [numClasses, numEmbedding])self.lstmInputs = tf.nn.embedding_lookup(embedding, self.inData)# 英文else:self.lstmInputs = tf.one_hot(self.inData, numClasses)# 创建单个Celldef buildCell(self, lstmSize, keepProb):basicCell = tf.nn.rnn_cell.BasicLSTMCell(lstmSize)drop = tf.nn.rnn_cell.DropoutWrapper(basicCell, output_keep_prob=keepProb)return drop# 将单个Cell堆叠多层def buildLstm(self):lstmSize = self.lstmSizenumLayers = self.numLayerskeepProb = self.keepProbnumSeqs = self.numSeqsnumClasses = self.numClasseswith tf.name_scope('lstm'):multiCell = tf.nn.rnn_cell.MultiRNNCell([self.buildCell(lstmSize, keepProb) for _ in range(numLayers)])self.initial_state = multiCell.zero_state(numSeqs, tf.float32)self.lstmOutputs, self.finalState = tf.nn.dynamic_rnn(multiCell, self.lstmInputs, initial_state=self.initial_state)seqOutputs = tf.concat(self.lstmOutputs, 1)x = tf.reshape(seqOutputs, [-1, lstmSize])with tf.variable_scope('softmax'):softmax_w = tf.Variable(tf.truncated_normal([lstmSize, numClasses], stddev=0.1))softmax_b = tf.Variable(tf.zeros(numClasses))self.logits = tf.matmul(x, softmax_w) + softmax_bself.prediction = tf.nn.softmax(self.logits, name='prediction')# 计算损失def buildLoss(self):numClasses = self.numClasseswith tf.name_scope('loss'):targets = tf.one_hot(self.targets, numClasses)targets = tf.reshape(targets, self.logits.get_shape())loss = tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=targets)self.loss = tf.reduce_mean(loss)# 创建优化器def buildOptimizer(self):gradClip = self.gradCliplr = self.lrtrainVars = tf.trainable_variables()# 限制权重更新grads, _ = tf.clip_by_global_norm(tf.gradients(self.loss, trainVars), gradClip)trainOp = tf.train.AdamOptimizer(lr)self.optimizer = trainOp.apply_gradients(zip(grads, trainVars))# 训练def train(self, data, logStep=10, saveStep=1000, savepath='./models/', maxStep=100000):if not os.path.exists(savepath):os.mkdir(savepath)Trainprob = self.Trainprobself.session = tf.Session()with self.session as sess:step = 0sess.run(tf.global_variables_initializer())state_now = sess.run(self.initial_state)for x, y in data:step += 1feed_dict = {self.inData: x,self.targets: y,self.keepProb: Trainprob,self.initial_state: state_now}loss, state_now, _ = sess.run([self.loss, self.finalState, self.optimizer], feed_dict=feed_dict)if step % logStep == 0:print('[INFO]: <step>: {}/{}, loss: {:.4f}'.format(step, maxStep, loss))if step % saveStep == 0:self.saver.save(sess, savepath, global_step=step)if step > maxStep:self.saver.save(sess, savepath, global_step=step)break# 从前N个预测值中选def GetTopN(self, preds, size, top_n=5):p = np.squeeze(preds)p[np.argsort(p)[:-top_n]] = 0p = p / np.sum(p)c = np.random.choice(size, 1, p=p)[0]return c

4、歌词的生成:

设置关键词变量,读取模型文件,输出结果即可。

代码如下:

def main(_):reader = TxtReader(filename='voc.data')model = CharRNN(numClasses = reader.vocabLen,mode = 'test',lstmSize = 128, numLayers = 2, useEmbedding = True, numEmbedding = 128)checkpoint = tf.train.latest_checkpoint('./models/')model.load(checkpoint)key="雪花"prime = reader.text2array(key)array = model.test(prime, size=reader.vocabLen, n_samples=300)print("《"+key+"》")print(reader.array2text(array))

界面的定义和调用

界面中我们的布局是文本框、编辑框和按钮控件。程序的调用使用批处理文件调用以达到显示运行过程的效果。因为如果没有运行过程,难免会导致用户不清楚程序流程而强制运行容易导致卡死的情况。

其中Bat里直接写入:

python song.py

其中过程效果如下:

1、界面布局:

界面布局使用canvas画布以达到添加背景图片的效果。背景图片设置为1.jpg,按钮背景图片设置为3.jpg。图片也可以自己更换掉。然后文本框作为提示的效果,分别定义字体,大小等等即可

代码如下:

root = tk.Tk()
root.title('AI写歌词')
# 背景
canvas = tk.Canvas(root, width=800, height=500, bd=0, highlightthickness=0)
imgpath = '1.jpg'
img = Image.open(imgpath)
photo = ImageTk.PhotoImage(img)imgpath2 = '3.jpg'
img2 = Image.open(imgpath2)
photo2 = ImageTk.PhotoImage(img2)
canvas.create_image(700, 400, image=photo)
canvas.pack()
label=tk.Label(text="请输入关键词:",font=("微软雅黑",20))
entry = tk.Entry(root, insertbackground='blue', highlightthickness=2,font=("微软雅黑",15))
entry.pack()
entry1 = tk.Text(height=15,width=115)
entry1.pack()

2、功能调用:

我们使用按钮中的command参数调用已设置好的函数即可。其中函数部分我们通过生成文本和删除文本的方式读入数据和写入数据。为了防止数据重叠故在要时刻监测重复软件。定义的函数内容如下:

def song():ss=entry.get()f=open("1.txt","w")f.write(ss)f.close()os.startfile("1.bat")while True:if os.path.exists("2.txt"):f=open("2.txt")ws=f.read()f.close()entry1.insert("0.0", ws)breaktry:os.remove("1.txt")os.remove("2.txt")except:pass

3、GUI代码:

整个GUI界面代码如下:

import tkinter as tk
from PIL import ImageTk, Image
import os
try:os.remove("1.txt")os.remove("2.txt")
except:pass
import os
def song():ss=entry.get()f=open("1.txt","w")f.write(ss)f.close()os.startfile("1.bat")while True:if os.path.exists("2.txt"):f=open("2.txt")ws=f.read()f.close()entry1.insert("0.0", ws)breaktry:os.remove("1.txt")os.remove("2.txt")except:pass
root = tk.Tk()
root.title('AI写歌词')
# 背景
canvas = tk.Canvas(root, width=800, height=500, bd=0, highlightthickness=0)
imgpath = '1.jpg'
img = Image.open(imgpath)
photo = ImageTk.PhotoImage(img)imgpath2 = '3.jpg'
img2 = Image.open(imgpath2)
photo2 = ImageTk.PhotoImage(img2)
canvas.create_image(700, 400, image=photo)
canvas.pack()
label=tk.Label(text="请输入关键词:",font=("微软雅黑",20))
entry = tk.Entry(root, insertbackground='blue', highlightthickness=2,font=("微软雅黑",15))
entry.pack()
entry1 = tk.Text(height=15,width=115)
entry1.pack()
bnt = tk.Button(width=15,height=2,image=photo2,command=song)
canvas.create_window(100, 50, width=200, height=30,window=label)
canvas.create_window(500, 50, width=630, height=30,window=entry)
canvas.create_window(400, 100, width=220, height=50,window=bnt)
canvas.create_window(400, 335, width=600, height=400,window=entry1)
root.mainloop()

到这里,我们整体的程序就搭建完成,下面为我们程序的运行过程和结果:

源码地址:

链接:https://pan.baidu.com/s/1EJsHIXbKUmRG-MdHcqkdFg

提取码:iz5m

作者简介 :

李秋键,CSDN 博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap安卓武侠游戏一部,vip视频解析,文意转换工具,写作机器人等项目,发表论文若干,多次高数竞赛获奖等等。

推荐阅读

  • AI修复100年前晚清影像喜提热搜,这两大算法立功了

  • CycleGan人脸转为漫画脸,牛掰的知识又增加了 | 附代码

  • 一次对语音技术的彻底批判

  • 用大白话彻底搞懂 HBase RowKey 详细设计

  • 为什么黑客无法攻击公开的区块链?

  • 再见 Python,Hello Julia!

  • 百万人学AI 万人在线大会, 15+场直播抢先看!

  • 你点的每个“在看”,我都认真当成了AI

作词家下岗系列:教你用 AI 做一个写歌词的软件!相关推荐

  1. rnn按时间展开_作词家下岗系列:教你用 RNN 算法做一个写词软件

    作者 | 李秋键 编辑 | Carol 出品 | CSDN(ID:CSDNnews) 自然语言处理作为人工智能的一个重要分支,在我们的生活中得到了广泛应用.其中RNN算法作为自然语言处理的经典算法之一 ...

  2. 作词家下岗系列:教你用 RNN 算法做一个写词软件

    作者 | 李秋键 编辑 | Carol 出品 | CSDN(ID:CSDNnews) 自然语言处理作为人工智能的一个重要分支,在我们的生活中得到了广泛应用.其中RNN算法作为自然语言处理的经典算法之一 ...

  3. 如何使用graphpad做柱形图_系列文章 如何使用PaddleDetection做一个完整项目(三)...

    系列文章 如何使用PaddleDetection做一个完整项目(三) 该文章是PaddleDetection的完结篇,请参考之前两篇文章 https://zhuanlan.zhihu.com/p/10 ...

  4. 如何用AI做一个好看的图案

    Hello everyone,这次是在放假的来和我们又见面了,今天我要讲的是要AI做一个好看的图案这个图案是用椭圆形做的图案,其中采用了渐变等.废话我就不多说了,直接来看看我做的图案吧,请欣赏: 是不 ...

  5. 三步教你用Node做一个微信哄女友(基友)神器,小白可上手

    前言 不知道大家最近有没有被python版的<微信每日说>刷屏呢,他可是霸占了github的python热门快两周了.我们前端的小伙伴是不是也看着有点眼馋呢,因为毕竟是不那么熟悉的pyth ...

  6. 教你用CSS3做一个旋转的宇宙星球

    教你用CSS3做一个旋转的宇宙星球 可能略有瑕疵,无非就是先画一个圆圈,把小球定位到上面,然后再让圆圈旋转即可 直接上效果图 代码 <!DOCTYPE html><html lang ...

  7. 完犊子!原单位的离职证明丢了,下周要入职了,用AI做一个行不行?

    弄丢了离职证明怎么办? 一位网友哀叹: 完犊子!原单位的离职证明丢了,下周要入职了,现在怎么办?用AI做一个行不行? 有相同经历的网友安慰他,离职证明没了没事,新公司会要求签一个免责协议. 有人说,企 ...

  8. 教你用C++做一个简单的用户名以及密码注册系统

    很多网站在访问时都要登陆或注册,今天,小编教大家做一个特别简单的注册系统. 首先在注册时先会让你设置用户名,我们用一个字符串存储并输入它: int main(){string name;getline ...

  9. 手把手教你用SetWindowsHookEx做一个键盘记录器

    "无忌,我教你的还记得多少?" "回太师傅,我只记得一大半." "那,现在呢?" "已经剩下一小半了." "那 ...

  10. 【Python】手把手教你用Python做一个图像融合demo,小白可上手!

    创作背景 说到融合,一下子会让我们这些95后想起来童年的动漫游戏王了! 发动魔法卡--融合! 哈哈,今天说得当然不是游戏王里的魔法了,但是我们使用的是Python魔法,今天我们将使用Python编程语 ...

最新文章

  1. 数据安全引担忧?get它,让你吃一颗“定心丸”
  2. Android activity属性
  3. 获取运行端口监听的用户身份auth-owner
  4. linux 文泉驿正黑字体,文泉驿字体系列打包下载-文泉驿字体下载-西西软件下载...
  5. method initializationerror not found:JUnit4单元测试报错问题
  6. codebrag审核代码工具安装配置
  7. python输入年月日输出年月日_Python网站浪漫表白神器那些鲜为人知的技术
  8. 程序开发——结对编程
  9. 190323每日一句
  10. 在上海乐字节学习CRM项目管理
  11. 微信小程序 满意度调查问卷
  12. HEVC帧内预测参考相邻帧代码解析
  13. 将分开的微服务项目合到一个项目下面
  14. hevc AMVP模式
  15. cython(cython安装)
  16. Java极简角色权限后台管理框架springboot manager
  17. k8s学习一:centos7单机安装k8s
  18. 12306验证码识别初尝试(2)-百度通用文字识别-成功率约75%
  19. python中文朗读_Python:语音处理,实现在线朗读RFC文档或本地文本文件
  20. 双碳”目标下资源环境中的可计算一般均衡(CGE)模型技术应用

热门文章

  1. 网站采集软件,全自动网站文章采集器,一键网页数据抓取
  2. win10没有android驱动安装不了,WIN10 MTP USB驱动无法安装解决方法
  3. 为何架设好服务器不显示补丁,WSUS补丁服务器分发后,客户端不在管理控制台显示 - winServer论坛 - 51CTO技术论坛_中国领先的IT技术社区...
  4. ati.c ATI顯卡開發源代碼
  5. linux limbo镜像文件下载,limbo 2000镜像下载
  6. inkscape矢量图_使用Inkscape创建矢量图形的教程
  7. wincc控件之FlexGrid系列(注册安装)
  8. 【GPU精粹与Shader编程】(一) 开篇 全系列11本书核心知识点总览
  9. 如何在网上下载自己需要的资源
  10. cadence17.2小白eda365skill 安装教程