下面用 Keras 来实现这些想法。首先需要可用于学习语言模型的大量文本数据。我们可以使用任意足够大的一个或多个文本文件——维基百科、《指环王》等。本例将使用尼采的一些作品,他是 19 世纪末期的德国哲学家,这些作品已经被翻译成英文。因此,我们要学习的语言模型将是针对于尼采的写作风格和主题的模型,而不是关于英语的通用模型。

首先下载语料,并将其转换为小写。

import keras
import numpy as nppath = 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))输出为Corpus length: 600893

接下来,我们要提取长度为 maxlen 的序列(这些序列之间存在部分重叠),对它们进行 one-hot 编码,然后将其打包成形状为 (sequences, maxlen,unique_characters) 的三维 Numpy 数组。与此同时,我们还需要准备一个数组 y,其中包含对应的目标,即在每一个所提取的序列之后出现的字符(已进行 one-hot 编码)。

# Length of extracted character sequences
# 提取 60 个字符组成的序列
maxlen = 60# We sample a new sequence every `step` characters
# 每 3 个字符采样一个新序列
step = 3# This holds our extracted sequences(保存所提取的序列)
sentences = []# This holds the targets (the follow-up characters)
# 保存目标(即下一个字符)
next_chars = []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))# List of unique characters in the corpus(语料中唯一字符组成的列表)
chars = sorted(list(set(text)))
print('Unique characters:', len(chars))
# Dictionary mapping unique characters to their index in `chars`
# 一个字典,将唯一字符映射为它在列表 chars 中的索引
char_indices = dict((char, chars.index(char)) for char in chars)# Next, one-hot encode the characters into binary arrays.
# 将字符 one-hot 编码为 二进制数组
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):for t, char in enumerate(sentence): x[i, t, char_indices[char]] = 1y[i, char_indices[next_chars[i]]] = 1输出为 Number of sequences: 200278Unique characters: 58Vectorization..

构建神经网络

这个网络是一个单层 LSTM,然后是一个 Dense 分类器和对所有可能字符的 softmax。但要注意,循环神经网络并不是序列数据生成的唯一方法,最近已经证明一维卷积神经网络也可以成功用于序列数据生成。

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

目标是经过 one-hot 编码的,所以训练模型需要使用 categorical_crossentropy 作为损失。

optimizer = keras.optimizers.RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)

训练语言模型并从中采样

给定一个训练好的模型和一个种子文本片段,我们可以通过重复以下操作来生成新的文本。

  • (1) 给定目前已生成的文本,从模型中得到下一个字符的概率分布。
  • (2) 根据某个温度对分布进行重新加权。
  • (3) 根据重新加权后的分布对下一个字符进行随机采样。
  • (4) 将新字符添加到文本末尾。

下列代码将对模型得到的原始概率分布进行重新加权,并从中抽取一个字符索引[采样函数(sampling function)]。

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)probas = np.random.multinomial(1, preds, 1)return np.argmax(probas)

最后,下面这个循环将反复训练并生成文本。在每轮过后都使用一系列不同的温度值来生成文本。这样我们可以看到,随着模型收敛,生成的文本如何变化,以及温度对采样策略的影响。

import random
import sysfor epoch in range(1, 60):print('epoch', epoch)# Fit the model for 1 epoch on the available training datamodel.fit(x, y,batch_size=128,epochs=1)# Select a text seed at randomstart_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)# We generate 400 charactersfor 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()

输出就不写出来了,生成许多段随机生成的对话。

由结果可见,较小的温度值会得到极端重复和可预测的文本,但局部结构是非常真实的,特别是 所有单词都是真正的英文单词(单词就是字符的局部模式)。随着温度值越来越大,生成的文本 也变得更有趣、更出人意料,甚至更有创造性,它有时会创造出全新的单词,听起来有几分可信(比 如 eterned 和 troveration)。对于较大的温度值,局部模式开始分解,大部分单词看起来像是半随 机的字符串。毫无疑问,在这个特定的设置下,0.5 的温度值生成的文本最为有趣。一定要尝试 多种采样策略!在学到的结构与随机性之间,巧妙的平衡能够让生成的序列非常有趣。

注意,利用更多的数据训练一个更大的模型,并且训练时间更长,生成的样本会比上面的结果看起来更连贯、更真实。但是,不要期待能够生成任何有意义的文本,除非是很偶然的情况。 你所做的只是从一个统计模型中对数据进行采样,这个模型是关于字符先后顺序的模型。语言是一种信息沟通渠道,信息的内容与信息编码的统计结构是有区别的。为了展示这种区别,我们来看一个思想实验:如果人类语言能够更好地压缩通信,就像计算机对大部分数字通信所做的那样,那么会发生什么?语言仍然很有意义,但不会具有任何内在的统计结构,所以不可能像刚才那样学习一个语言模型。

从零开始学keras之使用 LSTM 生成文本相关推荐

  1. 使用LSTM生成文本

    使用LSTM生成文本 概述 如何生成序列数据 生成文本的采样策略 文本序列生成程序流程 准备并解析初始文本 将字符序列向量化 构建神经网络模型 训练语言模型并采样 用模型生成文本 概述 我们的感知模式 ...

  2. 从零开始学前端:显示隐藏与文本溢出 --- 今天你学习了吗?(CSS:Day16)

    从零开始学前端:程序猿小白也可以完全掌握!-今天你学习了吗?(CSS) 复习:从零开始学前端:浮动 - 今天你学习了吗?(CSS:Day15) 文章目录 从零开始学前端:程序猿小白也可以完全掌握!-今 ...

  3. 从零开始学前端:HTML的一些文本格式化标签、快捷键、和特殊符号 --- 今天你学习了吗?(CSS:Day02)

    从零开始学前端:程序猿小白也可以完全掌握!- 今天你学习了吗?(CSS) 复习:从零开始学前端: HTML框架和VS Code安装 - 今天你学习了吗?(CSS:Day01) 文章目录 从零开始学前端 ...

  4. 从零开始学keras之变分自编码器生成图像

    自编码器由 Kingma 和 Welling 于 2013 年 12 月 a 与 Rezende.Mohamed 和 Wierstra 于 2014 年 1 月 同时发现,它是一种生成式模型,特别适用 ...

  5. 从零开始学keras之生成对抗网络GAN

    生成对抗网络主要分为生成器网络和判别器网络. 生成器网络:他以一个随机向量(潜在空间的一个随机点)作为输入,并将其解码成一张合成图像. 判别器网络:以一张图像(真实的或合成的均可)作为输入,并预测该图 ...

  6. 从零开始学keras之kaggle猫狗识别分类器

    使用很少的数据来训练一个图像分类模型,这是很常见的情况,如果你要从事计算机视觉方面的职业,很可能会在实践中遇到这种情况."很少的"样本可能是几百张图像,也可能是几万张图像.来看一个 ...

  7. 从零开始学keras之使用预训练的卷积神经网络

    想要将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络. 预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模图像分类任务)上训 ...

  8. 从零开始学keras之多分类问题

    本节你会构建一个网络,将路透社新闻划分为 46 个互斥的主题.因为有多个类别,所以这是多分类(multiclass classification)问题的一个例子.因为每个数据点只能划分到一个类别,所以 ...

  9. 从零开始学keras之电影二分类

    二分类问题可能是应用最广泛的机器学习问题.在这个例子中,你将学习根据电影评论的文字内容将其划分为正面或负面. 本博客使用 IMDB 数据集,它包含来自互联网电影数据库(IMDB)的 50 000 条严 ...

最新文章

  1. ‘shared_ptr‘ is not a member of ‘std’
  2. 图解Skip List——本质是空间换时间的数据结构,在lucene的倒排列表,bigtable,hbase,cassandra的memtable,redis中sorted set中均用到...
  3. 【数据挖掘知识点二】概率基础
  4. OpenCASCADE:读IGES
  5. 浅谈ASP.NET框架
  6. S3C6410移植u-boot-2010.3(2)基本的启动信息修改
  7. GoldenGate单向复制配置(支持DDL复制)
  8. java 判断全角_Java如何判断字符串中包含有全角,半角符号
  9. 解决在ubuntu环境下, sublime不能输入中文的问题
  10. 实现视频播放器倍速、清晰度切换、m3u8下载功能
  11. 今日头条推荐算法原理首公开,头条首席算法架构师带来详细解读
  12. Python 集合符号
  13. idea破解到2100年
  14. Android 接口的default 方法运行时报错AbstractMethodError
  15. Ubuntu16.04安装steam
  16. 那些警示良言——老百姓也是圣贤
  17. 使用poi操作word文档实现套打功能
  18. beyond compare 过期解决方法
  19. 少儿编程网站:scratch课程如何学习和教学?
  20. Frontiers in neuroscience: 网络游戏成瘾者额叶theta频段震荡活动的降低

热门文章

  1. 需求规格说明书(备注:因不支持word复制,格式图片发生改变 ,故以文件方式又上传了一份pdf)...
  2. C# 使用Quartz简单实例以及备忘
  3. ELK学习总结(2-5)elk的版本控制
  4. angularjs学习大纲
  5. 关于MFC自动生成的各个类的指针访问
  6. .NET : 如何理解字符串和它的字节表现形式
  7. 工作做事通用方法探索
  8. c语言解三元一次方程组_七年级下学期《8.3 一元一次不等式组》2020年高频易错题集...
  9. 视频号,近距离、更快接触数据库技术资讯!
  10. 局部变量是线程安全的,原因是什么