主要内容

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

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

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

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

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

指定的自定义小批量数据存储documentGenerationDatastore.m通过自定义函数来修改数据。这个文件作为支持文件附加到这个例子中。金宝app要访问该文件,请将示例作为一个活动脚本打开。有关如何创建自己的自定义迷你批处理数据存储的示例,请参见开发自定义小批量数据存储(深度学习工具箱)

负荷训练数据

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

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

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

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

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

准备培训数据

创建一个包含用于培训使用的数据的数据存储documentGenerationDatastore.对于预测器,该数据存储使用单词编码将文档转换为单词索引序列。每个文档的第一个单词索引对应于一个“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)
“差不多是对的,”公爵夫人说,“这是最不公平的。”帽匠说。"带我去见我的证人,看他那颗牧羊人的心"

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

网= resetState(净);

另请参阅

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

相关的话题