LSTM生成尼采风格文章
LSTM生成文本
github地址
使用循环神经网络生成序列文本数据。循环神经网络可以用来生成音乐、图像作品、语音、对话系统对话等等。
如何生成序列数据?
深度学习中最常见的方法是训练一个网络模型(RNN或者CNN)通过之前的tokens预测下一个或者之后的几个token序列。通常在处理文本数据时,tokens通常是单词或字符,任何可以对给定前一个tokens时对下一个令牌的概率进行建模的网络模型称为语言模型。语言模型能捕捉语言的潜在空间特性:其统计结构特征。
一旦你有了这样一个训练有素的语言模型,你就可以从中进行采样(生成新的序列):你给它一个初始的文本字符串(称为条件数据),让它生成下一个字符或下一个字(你甚至可以一次生成几个tokens),将生成的输出添加回输入数据,并多次重复该过程(见图8.1)。
此循环允许生成任意长度的序列,这些序列反映了训练模型的数据结构:看起来几乎与人类书写句子相似的序列。
取样策略
生成文本时,选择下一个字符的方式至关重要。一种朴素的方法是贪婪采样--总是选择最可能的下一个字符。但是这种方法导致重复的,可预测的字符串看起来不连贯。一种更有趣的方法会产生更令人惊讶的选择:它通过从下一个字符的概率分布中抽样,在抽样过程中引入随机性。这称为随机抽样。注意,贪心采样也可以作为概率分布的采样:一个特定字符的概率为1而其他概率为0。
从模型的softmax输出中概率地采样是巧妙的:它允许在某些时候对不太可能的字符进行采样,产生更有趣的句子,并且有时通过提出在训练数据中未发生的新的,逼真的单词来显示模型创造力。但是这个策略存在一个问题:它没有提供一种控制采样过程中随机性的方法。
随机性的重要性。考虑一个极端情况:纯随机抽样,从均匀概率分布中绘制下一个字符,并且每个角色都具有相同的可能性。该方案具有最大随机性;换句话说,该概率分布具有最大熵。当然,它不会产生任何有趣的东西。在另一个极端,贪婪的采样也不会产生任何有趣的东西,并且没有随机性:相应的概率分布具有最小的熵。从“真实”概率分布中抽样(由模型的softmax函数输出的分布)构成这两个极端之间的中间点。但是,可能希望探索许多其他更高或更低熵的中间点。较少的熵将使生成的序列具有更可预测的结构(因此它们可能看起来更逼真),而更多的熵将导致更令人惊讶和创造性的序列。
当从生成模型中抽样时,在生成过程中探索不同量的随机性总是好的。因为我们是生成数据有趣程度的终极判断,所以相互作用是高度主观的,并且不可能事先知道最佳熵点在哪里。
为了控制采样过程中的随机性,我们将引入一个名为softmax temperature的参数,该参数表示用于采样的概率分布的熵:它表征下一个字符的选择将会出乎意料或可预测的程度。给定温度值,通过以下列方式对其进行重新加权,从原始概率分布(模型的softmax输出)计算新的概率分布。
import numpy as np
def reweight_distribution(original_distribution, temperature=0.5):
distribution = np.log(original_distribution) / temperature#原始分布为1D,和为1;
distribution = np.exp(distribution)
return distribution / np.sum(distribution)
较高的temperature导致较高熵的采样分布,这将产生更多令人惊讶和非结构化的生成数据,而较低的temperature将导致较少的随机性和更可预测的生成数据。
实现字符级LSTM文本生成
用Keras将这些想法付诸实践。第一件事是准备用来学习语言模型的大量文本数据。可以使用任何足够大的文本文件或一组文本文件---维基百科,指环王等等。在这个例子中,你将使用19世纪晚期德国哲学家尼采(Nietzsche)的一些著作(翻译成英文)。因此,将学习的语言模型将特别是尼采的写作风格和选择主题的模型,而不是更通用的英语模型。
准备数据
下载数据,转换成小写
import keras
import numpy as np
path = keras.utils.get_file('nietzsche.txt',origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
text = open(path).read().lower()
print('Corpus length:',len(text))
之后,将提取长度为maxlen的部分重叠序列,对它们进行one-hot编码,打包成3D numpy数组形式,形状(squences,maxlen,unique_characters).同时,将准备一个包含相应目标的数组y:每个提取序列之后的one-hot编码字符。
maxlen = 60#句子最大长度
step = 3#每3个字符对句子进行采样
sentences = []
next_chars = []#targets
for i in range(0,len(text)-maxlen,step):
sentences.append(text[i:i+maxlen])
next_chars.append(text[i+maxlen])
print('Number of sequences:', len(sentences))
chars = sorted(list(set(text)))#字典
print('Unique characters:', len(chars))
char_indices = dict((char, chars.index(char)) for char in chars)#字符-id对应关系
print('Vectorization...')
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):#one-hot
for t, char in enumerate(sentence):
x[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
构建模型
LSTM+Dense;但是RNN并不是唯一生成序列文本的模型,1D卷积也可以达到相同的效果。
from keras import layers
model = keras.models.Sequential()
model.add(layers.LSTM(128,input_shape=(maxlen,len(chars))))
model.add(layers.Dense(len(chars),activation='softmax'))
optimizer = keras.optimizers.RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy',optimizer=optimizer)
语言模型训练、采样
给定训练有素的模型和种子文本片段,可以通过重复执行以下操作来生成新文本:
- 给定到目前为止生成的文本,从模型中绘制下一个字符的概率分布;
- 将分布重新调整到某个temperature;
- 根据重新加权的分布随机抽取下一个字符;
- 在可用文本的末尾添加新字符。
根据模型预测对下一个字符采样
def sample(preds, temperature=1.0):
preds = np.asarray(preds).astype('float64')
preds = np.log(preds) / temperature
exp_preds = np.exp(preds)
preds = exp_preds / np.sum(exp_preds)#重新加权调整
probas = np.random.multinomial(1, preds, 1)
return np.argmax(probas)#返回概率最大的字符下标
最后,以下循环重复训练并生成文本。可以在每个epochs之后使用一系列不同的temperature开始生成文本。这使可以了解生成的文本在模型开始收敛时如何演变,以及temperature对采样策略的影响。
import random
import sys
for 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]:#不同temperature生成文本对比
print('------ temperature:', temperature)
sys.stdout.write(generated_text)
for i in range(400):#从种子文本开始,生成400个字符
sampled = np.zeros((1, maxlen, len(chars)))#种子文本one-hot编码
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_char#添加到之前文本中
generated_text = generated_text[1:]#新的文本数据
sys.stdout.write(next_char)#预测生成的字符
种子文本‘new faculty, and the jubilation reached its climax when kant.’;
epochs=20,temperature=0.2,生成文本序列:
new faculty, and the jubilation reached its climax when kant and such a man
in the same time the spirit of the surely and the such the such
as a man is the sunligh and subject the present to the superiority of the
special pain the most man and strange the subjection of the
special conscience the special and nature and such men the subjection of the
special men, the most surely the subjection of the special
intellect of the subjection of the same things and
temperature=0.5:
new faculty, and the jubilation reached its climax when kant in the eterned
and such man as it's also become himself the condition of the
experience of off the basis the superiory and the special morty of the
strength, in the langus, as which the same time life and "even who
discless the mankind, with a subject and fact all you have to be the stand
and lave no comes a troveration of the man and surely the
conscience the superiority, and when one must be w
epochs=60,模型开始收敛,生成文本看起来更有意义,temperature=0.2:
cheerfulness, friendliness and kindness of a heart are the sense of the
spirit is a man with the sense of the sense of the world of the
self-end and self-concerning the subjection of the strengthorixes--the
subjection of the subjection of the subjection of the
self-concerning the feelings in the superiority in the subjection of the
subjection of the spirit isn't to be a man of the sense of the
subjection and said to the strength of the sense of the
temperature=0.5:
cheerfulness, friendliness and kindness of a heart are the part of the soul
who have been the art of the philosophers, and which the one
won't say, which is it the higher the and with religion of the frences.
the life of the spirit among the most continuess of the
strengther of the sense the conscience of men of precisely before enough
presumption, and can mankind, and something the conceptions, the
subjection of the sense and suffering and the
正如所看到的,低temperature值导致极其重复且可预测的文本,但局部结构非常逼真:特别是,所有单词都是真正的英语单词。随着temperature的升高,生成的文本变得更有趣,令人惊讶,甚至创造性;它有时会发明一些听起来有些合理的新词(比如说eterned)。在高temperature下,局部结构开始分解,大多数单词看起来像半随机字符串。毫无疑问,0.5是这个特定设置中文本生成最有趣的temperature值。始终尝试多种采样策略!学习结构和随机性之间的巧妙平衡是让生成有趣的原因。
请注意,通过训练更大的模型,更长的数据,可以获得生成的样本,这些样本看起来比这个更连贯和更真实。当然,除了随机机会之外,不要期望生成任何有意义的文本:您所做的只是从统计模型中抽取数据,其中字符来自哪些字符。
语言是一种通信渠道,通信的内容与通信编码的消息的统计结构之间存在区别。
小结
- 可以通过训练模型来生成离散序列数据:预先给定前一个tokens生成下一个tokens;
- 文本生成模型成为语言模型,基于单词或字符;
- 对下一个tokens进行采样需要在遵守模型判断可能性和引入随机性之间取得平衡;
- 解决这个问题的一种方法是softmax temperature的概念。始终尝试不同的temperature,找到合适的temperature。
LSTM生成尼采风格文章的更多相关文章
- Sequence Model-week1编程题2-Character level language model【RNN生成恐龙名 LSTM生成莎士比亚风格文字】
Character level language model - Dinosaurus land 为了构建字符级语言模型来生成新的名称,你的模型将学习不同的名字,并随机生成新的名字. 任务清单: 如何 ...
- 深度学习入门实战(一):像Prisma一样算法生成梵高风格画像
本文由云+社区发表 作者:董超 导语:现在人工智能是个大热点,而人工智能离不开机器学习,机器学习中深度学习又是比较热门的方向,本系列文章就从实战出发,介绍下如何使用MXnet进行深度学习~ 既然是实战 ...
- 用LSTM生成武侠人名
http://magicly.me/2017/04/07/rnn-lstm-generate-name/?utm_source=tuicool&utm_medium=referral 之前翻译 ...
- RNN入门(三)利用LSTM生成旅游点评
介绍 前几天,某个公众号发文质疑马蜂窝网站,认为它搬运其它网站的旅游点评,对此,马蜂窝网站迅速地做出了回应.相信大多数关注时事的群众已经了解了整个事情的经过,在这里,我们且不论这件事的是是非非,也 ...
- 基于Deep Learning的中文分词尝试
http://h2ex.com/1282 现有分词介绍 自然语言处理(NLP,Natural Language Processing)是一个信息时代最重要的技术之一,简单来讲,就是让计算机能够理解人类 ...
- 三分钟快速上手TensorFlow 2.0 (上)——前置基础、模型建立与可视化
本文学习笔记参照来源:https://tf.wiki/zh/basic/basic.html 学习笔记类似提纲,具体细节参照上文链接 一些前置的基础 随机数 tf.random uniform(sha ...
- LSTM机器学习生成音乐
目录 LSTM机器学习生成音乐 数据集介绍 将mid转成note数组 将note数组转成mid文件 获取数据集并将其保存 将note进行编号 构建数据集 截取数据 进行one-hot编码 构建模型 训 ...
- 神文章2:文本矩阵简述 V1.0 -vivo神人
评论: 牛逼的业余书籍爱好者读书思路,指导思想. 2013/9/22 文本矩阵简述 V1.0http://www.douban.com/note/170688812/ 文/vivo ...
- NLP+VS=>Image Caption︱自动生成图像标题技术论文+相关项目
读聪明人的笔记,是不是也能变聪明呢? Image Caption是一个融合计算机视觉.自然语言处理和机器学习的综合问题,它类似于翻译一副图片为一段描述文字. Image Caption问题可以定义为二 ...
随机推荐
- Python技巧——list与字符串互相转换
Python技巧——list与字符串互相转换 在Python的编程中,经常会涉及到字符串与list之间的转换问题,下面就将两者之间的转换做一个梳理. 1.字符串转换成list 命令:list() ...
- go语言练习:条件语句和循环语句
1.for循环+if条件语句简单例子: package main import "fmt" func main() { var a int for a = 0; a <= 2 ...
- Django之url映射
url映射的作用 根据Django的MTV模式,url的映射是根据用户输入或传送而来的url路径,来进行区分去执行相应的view函数来响应用户的操作. url映射的方式 Django项目的创建后,会自 ...
- How HashMap works in java 2
https://www.javacodegeeks.com/2014/03/how-hashmap-works-in-java.html Most common interview questio ...
- [HZNOI #koishi] Magic
[HZNOI #514] Magic 题意 给定一个 \(n\) 个点 \(m\) 条边的有向图, 每个点有两个权值 \(a_i\) 和 \(b_i\), 可以以 \(b_i\) 的花费把第 \(i\ ...
- [luogu P4230]连环病原体
[luogu P4230] 连环病原体 题意 给定一个长度为 \(n\) 的边序列, 当这个序列的一个子区间内的边都加入图中时产生了环则称其为"加强区间", 求序列中的每条边在多少 ...
- java使用elasticsearch进行模糊查询-已在项目中实际应用
java使用elasticsearch进行模糊查询 使用环境上篇文章本人已书写过,需要maven坐标,ES连接工具类的请看上一篇文章,以下是内容是笔者在真实项目中运用总结而产生,并写的是主要方法和思路 ...
- linux结束程序内存不会马上释放的解决方法
Linux下频繁读写文件时,内存资源被耗尽,当程序结束后,内存不会释放需要清除缓存.Linux缓存有dentry,buffer cache,page cache. 注:Dentry用来加速文件路径 ...
- Sublime2 DocBlocker插件在自动补全注释时输出自定义作者和当前时间等信息
Sublime在进行前端开发时非常棒,当然也少不了众多的插件支持,DocBlocker是在Sublime平台上开发一款自动补全代码插件,支持JavaScript (including ES6), PH ...
- Python程序的执行原理
1. 过程概述 Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行. 2. 字节码 字节码在Python虚拟机程序里对应的是PyCo ...