主要内容

使用深度学习逐字生成文本

这个例子展示了如何训练一个深度学习LSTM网络来逐字生成文本。

为了训练一个深度学习网络来逐词生成文本,训练一个序列到序列的LSTM网络来预测单词序列中的下一个单词。为了训练网络预测下一个单词,指定响应为移动一个时间步长的输入序列。

这个例子读取来自网站的文本。它读取并解析HTML代码以提取相关文本,然后使用一个定制的迷你批处理数据存储documentGenerationDatastore将文档作为序列数据的小批量输入到网络中。数据存储将文档转换为数字字索引序列。深度学习网络是一个包含单词嵌入层的LSTM网络。

迷你批处理数据存储是支持批量读取数据的数据存储的实现。金宝app您可以使用小批量数据存储作为深度学习应用程序的训练、验证、测试和预测数据集的来源。使用小批量数据存储读取内存不足的数据或在读取批量数据时执行特定的预处理操作。

您可以自定义小批量数据存储documentGenerationDatastore.m通过自定义函数来修改数据。有关如何创建自己的自定义迷你批处理数据存储的示例,请参见开发自定义小批量数据存储(深度学习工具箱)

负荷训练数据

加载训练数据。读取HTML代码刘易斯·卡罗尔的《爱丽丝梦游仙境》古登堡计划。

url =“https://www.gutenberg.org/files/11/11-h/11-h.htm”;代码= webread (url);

解析HTML代码

HTML代码中包含了相关的文本< p >(段落)元素。使用解析HTML代码提取相关文本htmlTree然后找到所有有元素名的元素“p”

树= htmlTree(代码);选择器=“p”;子树= findElement(树,选择器);

使用。从HTML子树提取文本数据extractHTMLText并查看前10段。

textData = extractHTMLText(子树);textData (1:10)
ans =10×1的字符串数组"" "" "" "" "" "" " 爱丽丝开始变得非常累了坐在她妹妹在银行和无关:一次或两次这本书她窥探到她的妹妹正在读,但它没有照片或对话,“什么是使用一本书,”爱丽丝想的没有图片或谈话吗?”“所以她正在考虑在自己的头脑(以及她可以,炎热的一天让她觉得非常疲倦和愚蠢),,做一只雏菊花环的乐趣是否值得的问题挑选雏菊,突然一只粉红眼睛的白兔跑靠近她。”“这并没有什么了不起的。爱丽丝并没有感到奇怪,甚至于听到兔子自言自语地说:“噢,亲爱的!噢,亲爱的!我要迟到了!(后来她想了想,觉得她当时应该感到奇怪,不过当时这一切都显得很自然);但当兔子把一块手表的背心口袋里,看了看,然后匆忙,爱丽丝开始她的脚,因为它划过她的心,她从未见过一只兔子与一个背心口袋里,或手表,和好奇心,燃烧后,她跑过田野,幸运的是,刚好看到它跳进了树篱下的一个大兔子洞里。“爱丽丝也跟着掉了下去,根本没想过怎么才能出来。”

删除空段落并查看剩下的前10个段落。

textData (textData = ="") = [];textData (1:10)
ans =10×1的字符串数组“爱丽丝开始厌倦了坐在她姐姐旁边的河岸上,厌倦了无所事事:有一两次她偷看了妹妹正在读的那本书,但里面没有图片或对话,”爱丽丝想,“没有图片或对话的书有什么用呢?”“因此,她在自己的脑海中思考(她也在思考,因为炎热的天气让她感到非常困倦和愚蠢),制作一条雏菊链的乐趣是否值得起床摘雏菊,突然一只粉红色眼睛的白兔从她身边跑了过来。”“这里面没有什么特别的东西;爱丽丝也不认为听到兔子自言自语“哦,天哪!哦,天哪!我要迟到了!”(当她后来仔细考虑时,她想到她本应该对此感到惊讶,但当时一切似乎都很自然);但是,当兔子真的从背心口袋里拿出一只手表,看了看,然后急匆匆地走了过去,爱丽丝开始站起来,因为她的脑海里闪过一个念头,她从来没有见过一只兔子有背心口袋或手表要从口袋里拿出来,她怀着好奇跑过田野,幸运的是,它正好及时从树篱下的一个大兔子洞里钻了出来。“又过了一会儿,爱丽丝追了上去,从来没有想过她究竟要怎么出去。“兔子洞像一条隧道一样一直向前走了一段路,然后突然下降,如此突然以至于爱丽丝没有时间想停下来,她发现自己掉进了一口很深的井里。“要么井很深,要么她跌得很慢,因为她有足够的时间下山环顾四周,想知道接下来会发生什么。首先,她试图往下看,看清楚她要做什么,但天太黑了,什么也看不见;然后她看了看井的两侧,发现井里摆满了碗橱和书架;她不时地看到挂在木桩上的地图和图画。当她经过时,她从一个架子上取下一个罐子;它被贴上了“橘子酱”的标签,但让她非常失望的是,它是空的:她不喜欢把罐子掉下来,因为害怕会杀人,所以她从罐子旁边摔下来时,设法把它放进了一个橱柜里。“好吧!”爱丽丝心里想,“摔了这么一跤,我再也不想从楼梯上摔下来了!他们会认为我在家是多么勇敢啊!哎呀,即使我从屋顶上摔下来,我也不会说任何话(这很可能是真的。)“下来,下来,下来。秋天永远不会结束“我不知道现在我已经走了多少英里了?”她大声说我一定在接近地球中心的地方。让我想想:那将是四千英里以下,我想——”(因为,你看,爱丽丝在教室里的课上学到了几件这类的事情,虽然这不是一个展示她的知识的好机会,因为没有人听她说话,但是反复说一遍仍然是一个很好的做法)———是的,“这差不多是正确的距离,但我想知道我到了什么纬度或经度?”(爱丽丝不知道纬度是什么,也不知道经度是什么,但认为这是一个很好的华丽的词。)“不久她又开始了。”我不知道我会不会从地上掉下来!在那些头朝下走路的人中间,这看起来是多么有趣啊!我想是反感——”(她很高兴这次没有人听,因为这个词听起来一点也不对劲。)但我得问问他们这个国家叫什么名字,你知道。请问,夫人,这是新西兰还是澳大利亚?’(她试着行屈膝礼,当你从空中掉下来时,她说了一句花哨的屈膝礼!你认为你能做到吗?’她会认为我这样问是一个多么无知的小女孩啊!不,问也不行:也许我会看到它写在什么地方。”“下来,下来,下来。没有别的事可做,所以爱丽丝很快又开始说话了我想,黛娜今晚会非常想念我的(黛娜是那只猫。)“我希望他们会记得她在喝茶的时候放了一碟牛奶。黛娜,亲爱的!我希望你能和我在一起!恐怕空中没有老鼠,但你可能会抓住一只蝙蝠,你知道,那很像一只老鼠。“但是猫吃蝙蝠吗,我想知道?”这时爱丽丝开始有点困了,继续用一种梦幻般的方式对自己说,“猫吃蝙蝠吗?”?“猫吃蝙蝠吗?”有时,“蝙蝠吃猫吗?”因为,你看,她两个问题都回答不了,所以她怎么说也没什么关系。她觉得自己在打瞌睡,刚开始梦见她和黛娜手拉手地走着,非常认真地对她说,‘黛娜,现在告诉我真相:你吃过蝙蝠吗?’突然,砰的一声!捶击她下来时,碰到了一堆树枝和干树叶,还有一堆树叶ll was over. "

在词云中可视化文本数据。

图wordcloud (textData);标题(《爱丽丝梦游仙境》

准备培训数据

创建一个包含用于培训使用的数据的数据存储documentGenerationDatastore。要创建数据存储,首先保存自定义的小批量数据存储documentGenerationDatastore.m的路径。对于预测器,该数据存储使用单词编码将文档转换为单词索引序列。每个文档的第一个单词索引对应于一个“start of text”标记。“start of text”标记由字符串给出“startOfText”。对于响应,数据存储返回按1移位的词的分类序列。

使用标记文本数据tokenizedDocument

文件= tokenizedDocument (textData);

使用标记化的文档创建文档生成数据存储。

ds = documentGenerationDatastore(文件);

为了减少添加到序列中的填充量,可以按序列长度对数据存储中的文档进行排序。

ds = (ds)进行排序;

建立和培训LSTM网络

定义LSTM网络架构。要将序列数据输入到网络中,需要包含一个序列输入层,并设置输入大小为1。接下来,包括一个维度为100的单词嵌入层和与单词编码相同的单词数量。接下来,包含一个LSTM层并指定隐藏的大小为100。最后,添加与类数相同大小的全连接层、softmax层和分类层。类数是指词汇表中的单词数加上“文本结束”类的额外类。

inputSize = 1;embeddingDimension = 100;numWords =元素个数(ds.Encoding.Vocabulary);numClasses = numWords + 1;layers = [sequenceInputLayer(inputSize) wordEmbeddingLayer(embeddingDimension,numWords) lstmLayer(100) dropoutLayer(0.2) fulllyconnectedlayer (numClasses) softmaxLayer classificationLayer];

指定培训选项。指定要使用的求解器“亚当”。训练300个时代,学习率0.01。设置mini-batch大小为32。要使数据按序列长度排序,请设置“洗牌”选项“永远”。为了监控训练进度,设置“阴谋”选项“训练进步”。要抑制verbose输出,请设置“详细”

选择= trainingOptions (“亚当”...“MaxEpochs”, 300,...“InitialLearnRate”, 0.01,...“MiniBatchSize”32岁的...“洗牌”“永远”...“阴谋”“训练进步”...“详细”、假);

培训网络使用trainNetwork

网= trainNetwork (ds、层、期权);

生成新的文本

根据训练数据中文本的第一个单词,从概率分布中抽样一个单词,生成文本的第一个单词。使用训练好的LSTM网络生成剩余的单词,利用生成文本的当前序列预测下一个时间步长。一个接一个地生成单词,直到网络预测到“文本结束”的单词。

要使用网络进行第一次预测,输入表示“start of text”标记的索引。方法查找索引word2ind函数与文档数据存储所使用的单词编码一起使用。

内附= ds.Encoding;wordIndex = word2ind (enc,“startOfText”
wordIndex = 1

对于剩下的预测,根据网络的预测分数对下一个单词进行抽样。预测分数代表下一个单词的概率分布。对网络输出层的类名给出的词汇表中的单词进行抽样。

词汇=字符串(net.Layers(结束). class);

逐字逐句地进行预测predictAndUpdateState。对于每个预测,输入前一个单词的索引。停止预测网络何时预测到文本单词的结束,或者生成的文本何时有500个字符长。对于大量数据、长序列或大型网络,GPU上的预测通常比CPU上的预测更快。否则,对CPU的预测通常计算得更快。对于单时间步长预测,使用CPU。要使用CPU进行预测,请设置“ExecutionEnvironment”选择predictAndUpdateState“cpu”

generatedText ="";最大长度= 500;strlength (generatedText) <最大长度预测下一个单词的分数。[净,wordScores] = predictAndUpdateState (wordIndex净,“ExecutionEnvironment”“cpu”);选取下一个单词。newWord = datasample(词汇,1,“重量”, wordScores);停止预测文本的结尾。如果newWord = =“EndOfText”打破结束将单词添加到生成的文本中。generatedText = generatedText +”“+ newWord;找到下一个输入的单词索引。wordIndex = word2ind (enc, newWord);结束

生成过程在每个预测之间引入空白字符,这意味着一些标点字符出现时前后带有不必要的空格。通过删除适当的标点字符前后的空格来重建生成的文本。

删除出现在指定标点字符前的空格。

punctuationCharacters = [“。”","“”")"”:““?”“啊!”];generatedText =取代(generatedText,”“+ punctuationCharacters punctuationCharacters);

删除出现在指定标点字符后的空格。

punctuationCharacters = [”(““”];generatedText = replace(generatedText,标点字符+”“punctuationCharacters)
generatedText = " '当然,这是一个好的海龟!王后低声微弱地说。

若要生成多段文本,请使用resetState

网= resetState(净);

另请参阅

|||||||(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)

相关的话题