主要内容

傲慢与偏见和MATLAB

这个例子展示了如何训练深度学习LSTM网络来使用字符嵌入生成文本。

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

要使用字符嵌入,将每个训练观察转换为一个整数序列,其中整数索引为字符词汇表。在网络中包括一个单词嵌入层,该层学习字符的嵌入并将整数映射到向量。

负荷训练数据

读取HTML代码《傲慢与偏见古登堡计划》电子书,简·奥斯汀著并使用webreadhtmlTree

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

提取段落,找到p元素。指定用class忽略段落元素“目录”使用CSS选择器”:不(.toc)”

段落= findElement(树,“p: not (.toc)”);

从使用的段落中提取文本数据extractHTMLText.并删除空字符串。

textData = extractHTMLText(段落);textData (textData = ="") = [];

删除小于20个字符的字符串。

idx = strlength(textData) < 20;textData (idx) = [];

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

图wordcloud (textData);标题(《傲慢与偏见》

将文本数据转换为序列

将文本数据转换为预测器的字符索引序列和响应的分类序列。

categorical函数将换行符和空格项视为未定义的。要为这些字符创建分类元素,请将它们替换为特殊字符“”(pilcrow,“\ x00B6”)和“·”(中间点,“\ x00B7”分别)。为防止歧义,必须选择文本中不出现的特殊字符。这些字符不会出现在训练数据中,因此可以用于此目的。

newlineCharacter =组成(“\ x00B6”);whitespaceCharacter =组成(“\ x00B7”);textData =取代(textData,[换行符”“]、[newlineCharacter whitespaceCharacter]);

对文本数据进行循环,并创建一个字符索引序列,该序列表示每个观察到的字符,并为响应创建一个分类字符序列。要表示每个观察的结束,包括特殊字符“␃”(文本结束,“\ x2403”).

endOfTextCharacter =组成(“\ x2403”);numDocuments =元素个数(textData);i = 1:numDocuments字符= textData{i};X =双(字符);%创建带有文本结束字符的分类响应向量。charactersshift = [cellstr(字符(2:结束)')' endOfTextCharacter];Y =分类(charactersShifted);XTrain{我}= X;YTrain{我}= Y;结束

在训练期间,默认情况下,软件将训练数据分成小批,并填充序列,使它们具有相同的长度。过多的填充会对网络性能产生负面影响。

为了防止训练过程添加太多的填充,可以按序列长度对训练数据进行排序,并选择一个迷你批大小,以便迷你批中的序列具有相似的长度。

获取每个观察的序列长度。

numObservations =元素个数(XTrain);i=1:numObservations序列= XTrain{i};sequenceLengths (i) =(序列,2)大小;结束

按序列长度对数据排序。

[~, idx] = (sequenceLengths)进行排序;XTrain = XTrain (idx);YTrain = YTrain (idx);

建立和培训LSTM网络

定义LSTM体系结构。指定一个包含400个隐藏单元的序列到序列LSTM分类网络。设置输入大小为训练数据的特征维数。对于字符索引序列,特征维数为1。指定一个维度为200的单词嵌入层,并指定单词的数量(对应于字符)作为输入数据中的最高字符值。将完全连接层的输出大小设置为响应中的类别数量。为了防止过拟合,在LSTM层之后加入一个dropout层。

单词嵌入层学习字符的嵌入,并将每个字符映射到一个200维向量。

inputSize =大小(XTrain {1}, 1);numClasses =元素个数(类别([YTrain {:})));(textData numCharacters = max ({}):);layer = [sequenceInputLayer(inputSize) wordEmbeddingLayer(200,numCharacters) lstmLayer(400,“OutputMode”“序列”) dropoutLayer (0.2);fullyConnectedLayer (numClasses) softmaxLayer classificationLayer];

指定培训选项。指定训练的小批量大小为32,初始学习率为0.01。为了防止渐变发生爆炸,设置渐变阈值为1。为了确保数据保持排序,设置“洗牌”“永远”.为了监控训练进度,设置“阴谋”选项“训练进步”.要抑制verbose输出,请设置“详细”

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

培训网络。

网= trainNetwork (XTrain、YTrain层,选择);

生成新的文本

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

根据第一个字符在训练数据中的分布情况对第一个字符进行采样。

initialCharacters = extractBefore (textData 2);firstCharacter = datasample (initialCharacters, 1);generatedText = firstCharacter;

将第一个字符转换为数字索引。

X =双(char (firstCharacter));

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

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

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

最大长度= 500;strlength (generatedText) <最大长度预测下一个角色得分。[净,characterScores] = predictAndUpdateState(净,X,“ExecutionEnvironment”“cpu”);%采样下一个字符。newCharacter = datasample(词汇,1,“重量”, characterScores);停止预测文本的结尾。如果newCharacter = = endOfTextCharacter打破结束将字符添加到生成的文本中。generatedText = generatedText + newCharacter;%获取字符的数字索引。X =双(char (newCharacter));结束

通过将特殊字符替换为它们相应的空格和换行符,重新构建生成的文本。

generatedText = replace(generatedText,[newlincharacter whitespaccharacter],[newline . txt],[newline . txt]”“])
“我希望达西先生跟我一样,诚心诚意地选择了亲戚关系。我们本来是要去找卢卡斯家的。她们是象韦翰爵士那样嫁给他的,因为这两个人认识他,就有可能做现在的事,而且机会就像她们和我读到的那样;丽萃也没有,因为她在思念着香气;看了几次,我从来没有走到有利的情况下;强迫自己。她们可怜又活泼地相信,她是要请客的,因为我太过份了。”

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

网= resetState(净);

另请参阅

(文本分析工具箱)|(文本分析工具箱)|(文本分析工具箱)|||||(文本分析工具箱)|(文本分析工具箱)|(文本分析工具箱)|(文本分析工具箱)

相关的话题