随着深度学习的迅猛发展,人工智能的强大能力已经超出了模仿人类的简单动作,例如识别物体,如今已经能发展到自动驾驶,而且车开的比人都好的地步。目前深度学习进化出的一大功能是能够进行艺术创作,前几年google开发的DeepDream算法能够自己绘制出犹如毕加索抽象画般的艺术作品,而现在使用LSTM网络甚至可以开发出自动作曲程序,据说现在很多曲调都是由深度学习网络创作的。

很多艺术创作其实是通过序列号数据构成的,例如文章其实是一个个单词前后相邻构成,音乐是一个个音符前后相邻构成,甚至绘画也是笔触前后相邻构成,因此艺术创作从数学上看其实是时间序列数据,而LSTM忘了是最擅长处理时间序列数据的,因此只要我们训练网络识别相应艺术创作的时间序列中的数据规律,我们就可以利用网络进行相应的创作。

我们要创建的网络具有的功能是自动写作。我们把含有N个单词的句子输入网络,让网络预测第N+1个单词,然后把预测结果重新输入网络,让网络预测第N+2个单词,这种自我循环能让网络创作出跟人写出来几乎一模一样的句子。例如我们有句子"hello Tom, how are you",我们把"hello Tom, how"输入网络后网络预测下个单词是"are",然后我们继续把"hello Tom, how are"输入网络,网络预测下一个单词是"you",网络运行的基本流程如下图:

上图中数据采样很重要,通常我们会从下一个可能单词的概率分布中,选择概率最大的那个单词,但是这么做会导致生成的句子不流畅,看起来不像人写得。通用做法是在可能性最高的若干个单词集合中进行一定随机选择。例如网络预测某个词的概率是30%,那么我们引入一种随机方法,使得该词被选中的概率是30%。

我们引入的随机方法,它的随机性必须要有所控制。如果随机性为0,那么最终网络创作的句子就没有一点创意,如果随机性太高,那么得到的句子在逻辑上可能就比较离谱,因此我们要把随机性控制在某个程度。于是我们引入一个控制随机性的参数叫temperature,也就是温度的意思。

在前面章节我们多次看到,当网络要给出概率时,最后输出层时softmax,它会输出一个向量,向量中每个分量的值是0到1间的小数,所有分量加总得1.我们假设这个向量用original_distributin表示,那么我们用下面的方法引入新的随机性:

def  reweight_distribution(original_distribution, temperature=0.5):distribution = np.log(original_distribution) / temperaturedistribution = np.exp(distribution)return distribution / np.sum(distribution)

上面代码会把网络softmax层输出的结果重新打乱,打乱的程度由tenperature来控制,它的值越大,打乱的程度就越高。接下来我们做一个LSTM网络,它预测的下一个元素是字符而不是我们前面所说的单词。

深度学习网络进行文章创作时,与用于输入它的文本数据相关。如果你用莎士比亚的作品作为训练数据,网络创作的文章与莎士比亚就很像,如果我们在上面函数中引入随机性,那么网络创作结果就会有一部分像莎士比亚,有一部分又不像,而不像的那部分就是网络创作的艺术性所在,下面我们用德国超人哲学创始人尼采的文章训练网络,让我们通过深度学习再造一个新的哲学家,首先我们要加载训练数据:

import  keras
import  numpy as nppath = keras.utils.get_file('nietzche.txt', origin = 'https://s3.amazonaws.com/text-datasets/nietzsche.txt')
text = open(path).read().lower()
print('Corpus length: ', len(text))

上面代码运行后,我们会下载单词量为600893的文本数据。接着我们以60个字符为一个句子,第61个字符作为预测字符,也就是告诉网络看到这60个字符后你应该预测第61个字符,同时前后两个采样句子之间的间隔是3个字符:

maxlen = 60
step = 3
setences = []
#next_chars 对应下一个字符,以便用于训练网
next_chars = []for i in range(0, len(text) - maxlen, step):setences.append(text[i : i + maxlen])next_chars.append(text[i + maxlen])print('Number of sequentence: ', len(setences))chars = sorted(list(set(text)))
print('Unique characters: ', len(chars))
#为每个字符做编号
char_indices = dict((char, chars.index(char)) for char in chars)
print('Vectorization....')
'''
整个文本中不同字符的个数为chars, 对于当个字符我们对他进行one-hot编码,
也就是构造一个含有chars个元素的向量,根据字符对于的编号,我们把向量的对应元素设置为1,
一个句子含有60个字符,因此一行句子对应一个二维句子(maxlen, chars),矩阵的行数是maxlen,列数
是chars
'''
x = np.zeros((len(setences), maxlen, len(chars)), dtype = np.bool)
y = np.zeros((len(setences), len(chars)), dtype = np.bool)for i, setence in enumerate(setences):for t, char in enumerate(setence):x[i, t, char_indices[char]] = 1y[i, char_indices[next_chars[i]]] = 1

上面代码中构造的x就是输入数据,当输入句子是x时,我们要调教网络去预测下一个字符是y。代码先统计文本资料总共有多少个不同的字符,这些字符包含标点符号,根据运行结果显示,文本总共有57个不同字符,同时我们将不同字符进行编号。

然后构造含有57个元素的向量,当句子中某个字符出现时,我们就把向量中下标对应字符编号的元素设置为1,我们这些向量输入到网络进行训练:

from keras import layersmodel = keras.models.Sequential()
model.add(layers.LSTM(128, input_shape(maxlen, len(chars))))
model.add(layers.Dense(len(chars), activation = 'softmax'))
optimizer = leras.optimizers.RMSprop(lr = 0.01)
model.compile(loss = 'categorical_crossentropy', optimizer = optimizer)

网络输出结果对应一个含有57个元素的向量,每个元素对应相应编号的字符,元素的值表示下一个字符是对应字符的概率。我们按照前面说过的方法对网络给出的概率分布引入随机性,然后选出下一个字符,把选出的字符添加到输入句子中形成新的输入句子传入到网络,让网络以同样的方法判断下一个字符:

def  sample(preds, temperature = 1.0):preds = np.asarray(preds).astype('float64')preds = np.log(preds) / temperatureexp_preds = np.exp(preds)preds = exp_preds / np.sum(exp_preds)'''由于preds含有57个元素,每个元素表示对应字符出现的概率,我们可以把这57个元素看成一个含有57面的骰子,骰子第i面出现的概率由preds[i]决定,然后我们模拟丢一次这个57面骰子,看看出现哪一面,这一面对应的字符作为网络预测的下一个字符'''probas = np.random.multinomial(1, preds, 1)return np.argmax(probas)

接着我们启动训练流程:

import random
import sysfor epoch in range(1, 60):print('epoch:', epoch)model.fit(x, y, batch_size = 128, epochs = 1)start_index = random.randint(0, len(text) - maxlen - 1)generated_text = text[start_index: start_index + maxlen]print('---Generating with seed:"' + generated_text + '"')for temperature in [0.2, 0.5, 1.0, 1.2]:print('---temperature:', temperature)#先输出一段原文sys.stdout.write(generated_text)'''根据原文,我们让网络创作接着原文后面的400个字符组合成的段子'''for i in range(400):sampled = np.zeros((1, maxlen, len(chars)))for t, char in enumerate(generated_text):sampled[0, t, char_indices[char]] = 1.#让网络根据当前输入字符预测下一个字符preds = model.predict(sampled, verbose = 0)[0]next_index = sample(preds, temperature)next_char = chars[next_index]generated_text += next_chargenerated_text = generated_text[1:]sys.stdout.write(next_char)sys.stdout.flush()print()

上面代码将尼采的作品输入到网络进行训练,训练后网络生成的段子就会带上明显的尼采风格,代码最好通过科学上网的方式,通过谷歌的colab,运行到GPU上,如果在CPU上运行,它训练的速度会非常慢。

我们看看经过20多次循环训练后,网络生成文章的效果如下:

输出中,Generating with seed 后面的语句是我们从原文任意位置摘出的60个字符。接下来的文字是网络自动生成的段子。当temperature值越小,网络生成的段子与原文就越相似,值越大,网络生成的段子与原文差异就越大,随着epoch数量越大,也就是网络训练次数越多,它生成的段子就越通顺,而且表达的内容也越有创意。

注意到随着temperature值越大,网络合成的词语错误也越多,有些单词甚至是几个字符的随机组合。从观察上来看,temperature取值0.5的效果是最好的。

更多内容,请点击进入csdn学院

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:

有了LSTM网络,我再也不怕老师让我写作文了相关推荐

  1. 小学5年级计算机考试作文,我的小学老师五年级优秀作文(通用10篇)

    我的小学老师五年级优秀作文(通用10篇) 在平日的学习.工作和生活里,大家都有写作文的经历,对作文很是熟悉吧,作文是人们以书面形式表情达意的言语活动.那么问题来了,到底应如何写一篇优秀的作文呢?下面是 ...

  2. 教你用深度学习LSTM网络预测流行音乐趋势(附代码)

    来源:大数据挖掘DT数据分析 本文长度为1500字,建议阅读5分钟 本文为你介绍LSTM网络原理及其在流行音乐趋势预测赛题中的应用. 后台回复关键词"音乐",下载完整代码及数据集 ...

  3. 使用RNNs进行机器翻译——介绍RNN和LSTM网络及其应用

    https://www.toutiao.com/a6667024196603740685/ 循环神经网络 RNNs是一种特殊类型的神经网络,具有允许信息在网络中的不同步骤中持续存在的循环. 循环神经网 ...

  4. 【LSTM】基于LSTM网络的人脸识别算法的MATLAB仿真

    1.软件版本 matlab2021a 2.本算法理论知识 长短时记忆模型LSTM是由Hochreiter等人在1997年首次提出的,其主要原理是通过一种特殊的神经元结构用来长时间存储信息.LSTM网络 ...

  5. (译)理解 LSTM 网络 (Understanding LSTM Networks by colah)

    前言:其实之前就已经用过 LSTM 了,是在深度学习框架 keras 上直接用的,但是到现在对LSTM详细的网络结构还是不了解,心里牵挂着难受呀!今天看了 tensorflow 文档上面推荐的这篇博文 ...

  6. 使用MNIST数据集,在TensorFlow上实现基础LSTM网络

    使用MNIST数据集,在TensorFlow上实现基础LSTM网络 By 路雪2017年9月29日 13:39 本文介绍了如何在 TensorFlow 上实现基础 LSTM 网络的详细过程.作者选用了 ...

  7. 从任务到可视化,如何理解LSTM网络中的神经元 By 机器之心2017年7月03日 14:29 对人类而言,转写是一件相对容易并且可解释的任务,所以它比较适合用来解释神经网络做了哪些事情,以及神经网

    从任务到可视化,如何理解LSTM网络中的神经元 By 机器之心2017年7月03日 14:29 对人类而言,转写是一件相对容易并且可解释的任务,所以它比较适合用来解释神经网络做了哪些事情,以及神经网络 ...

  8. TF之LSTM:基于Tensorflow框架采用PTB数据集建立LSTM网络的自然语言建模

    TF之LSTM:基于Tensorflow框架采用PTB数据集建立LSTM网络的自然语言建模 目录 关于PTB数据集 代码实现 关于PTB数据集 PTB (Penn Treebank Dataset)文 ...

  9. 深度学习笔记之lSTM网络

    解决梯度爆炸问题可以利用LSTM网络 也可以用clip gradients 算法https://blog.csdn.net/jiachen0212/article/details/80285648 相 ...

  10. 从Tensorflow代码中理解LSTM网络

    目录 RNN LSTM 参考文档与引子 缩略词  RNN (Recurrent neural network) 循环神经网络  LSTM (Long short-term memory) 长短期记忆人 ...

最新文章

  1. 徒手撸出一个类Flask微框架(三)根据业务进行路由分组
  2. Linux基础知识:正则表达式
  3. 今日笔记!——分析Java应用性能
  4. permgen_打破PermGen神话
  5. 专科python应届生工资多少-请问学过一点python,应届生怎么找工作?
  6. 一些关于虚拟交易的有趣文章
  7. python中read() readline()以及readlines()用法
  8. 查找算法-------插值查找
  9. 天线远场定义_暗室静区及天线近场和远场的介绍
  10. 西安电子科技大学计算机学院简介,西安电子科技大学计算机学院简介
  11. jetson nano图形界面自动登录(lxde桌面自动登录)
  12. 基于Java的qq截图工具(毕业设计含源码)
  13. UE5/C++ 基于GAS创建攻击伤害 5.1.1准备碰撞体
  14. STM32 Combined PWM的用法
  15. 个人汇总笔记——NUnit
  16. java bidi_Java Bidi類代碼示例
  17. 学计算机要选什么科,计算机要学什么科目
  18. Minecraft多人联机服务器配置
  19. 数字图像处理实验之对比度拉伸
  20. 制作自己的标注数据集

热门文章

  1. java 打压缩包_java将文件打成zip包
  2. bmc linux 默认密码_系统下重置BMC密码方法
  3. 利用css构建三角形(正三角,倒三角,左/右三角)
  4. 已解决(Python运行报错)SyntaxError: expression cannot contain assignment, perhaps you meant “==“?
  5. h3c 云服务器操作系统,产品技术-H3C CloudOS云操作系统电信版-新华三集团-H3C
  6. Elasticsearch 如何实现类主流搜索引擎广告置顶显示效果?
  7. 怎么生成html链接,终于认识如何创建网页超链接
  8. mysql存小程序获取到的带有表情的昵称_拉取用户信息,带表情的昵称,存储到数据库是???要怎么处理...
  9. Go使用绘图的库(go-charts、go-echarts)
  10. linux s5pc100串口驱动,FS_S5PC100平台linux摄像头驱动开发详解