主要内容

骄傲和偏见和MATLAB

此示例显示了如何训练深度学习LSTM网络以使用字符嵌入生成文本。

要训​​练一个深度学习网络进行文本生成,请训练序列到序列LSTM网络,以一系列字符预测下一个字符。要训​​练网络以预测下一个字符,请指定响应为输入序列,逐步移动。

To use character embeddings, convert each training observation to a sequence of integers, where the integers index into a vocabulary of characters. Include a word embedding layer in the network which learns an embedding of the characters and maps the integers to vectors.

负载培训数据

从中读取HTML代码简·奥斯丁(Jane Austen)并使用韦布雷德andhtmltree

URL =“ https://www.gutenberg.org/files/1342/1342-H/1342-H.HTM”;Code = Webread(url);tree = htmltree(代码);

通过查找p元素。指定忽略类段落元素“ TOC”使用CSS选择器':不是(.toc)'

paragraphs = findElement(tree,'P:不是(.toc)');

使用段落中提取文本数据额外的文本。并卸下空字符串。

textData = extracthtmlText(段落);textdata(textdata ==“”)= [];

将字符串短于20个字符。

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

可视化单词云中的文本数据。

图WordCloud(TextData);标题("Pride and Prejudice"

将文本数据转换为序列

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

The categorical function treats newline and whitespace entries as undefined. To create categorical elements for these characters, replace them with the special characters "”(Pilcrow,"\x00B6")和“·”(中间点,“ \ x00b7”) 分别。为了防止歧义,您必须选择未出现在文本中的特殊字符。这些字符没有出现在培训数据中,因此可以用于此目的。

newlinecharacter = compose("\x00B6");whitespaceCharacter = compose(“ \ x00b7”);textdata =替换(textdata,[newline“”],[newlinecharacter whitespacecharacter]);

在文本数据上循环,并创建一系列字符索引,代表每个观察值的字符和响应的特征序列。要表示每个观察的末尾,包括特殊字符“␃”(文本的结尾,“ \ x2403”)。

endoftextcharacter = compose(“ \ x2403”);numDocuments = numel(textData);为了i = 1:numDocuments targual = textData {i};x = double(字符);%创建具有文本字符末尾的分类响应向量。charactersShifted = [cellstr(characters(2:end)')' endOfTextCharacter]; Y = categorical(charactersShifted); XTrain{i} = X; YTrain{i} = Y;结尾

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

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

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

numObservations = numel(xtrain);为了i=1:numObservations sequence = XTrain{i}; sequenceLengths(i) = size(sequence,2);结尾

按序列长度对数据进行排序。

[〜,idx] = stort(sequenceLengths);Xtrain = Xtrain(idx);ytrain = ytrain(idx);

Create and Train LSTM Network

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

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

InputSize = size(Xtrain {1},1);numClasses = numel(类别([ytrain {:}]]));numcharacters = max([[textdata {:}]);layers = [sequenceInputlayer(inputsize)Wordembeddinglayer(200,numcharacters)lstmlayer(400,400,'outputmode',,,,'序列')辍学器(0.2);完整连接的layerer(numClasses)softmaxlayer classificationlayer];

指定培训选项。指定小批量大小为32的训练,并初始学习率为0.01。为防止梯度爆炸,将梯度阈值设置为1“洗牌”'绝不'。To monitor the training progress, set the“绘图”option to“训练过程”。要抑制详细的输出,请设置“冗长”错误的

选项=训练('亚当',,,,...“ MINIBATCHSIZE”,32,...“初始删除”,0.01,...“梯度阈值”,1,...“洗牌”,,,,'绝不',,,,...“绘图”,,,,“训练过程”,,,,...“冗长”,,,,错误的);

训练网络。

net = trainNetwork(XTrain,YTrain,layers,options);

生成新文本

通过根据训练数据中文本的第一个字符从概率分布中采样字符来生成文本的第一个字符。通过使用训练有素的LSTM网络来生成剩余的字符,以使用当前生成的文本序列预测下一个序列。继续一对一生成字符,直到网络预测“文本结尾”字符。

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

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

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

x = double(char(first character));

对于其余的预测,请根据网络的预测得分对下一个字符进行采样。预测分数代表下一个字符的概率分布。采样来自网络输出层的类名给出的字符词汇中的字符。从网络的分类层中获取词汇。

vocabulary = string(net.layers(end).classNames);

使用字符进行预测预测和dateState。对于每个预测,输入上一个字符的索引。停止预测网络何时预测文本字符的结束或生成的文本何时长500个字符。对于大量数据,长序列或大型网络,GPU上的预测通常比CPU上的预测更快。否则,对CPU的预测通常更快地计算。对于单个时间步预测,请使用CPU。要使用CPU进行预测,请设置“执行环境”选项预测和dateState'中央处理器'

maxLength = 500;尽管strlength(生成文本)%预测下一个字符得分。[net,tarnecors] = preditd prectiveAndUpDateState(net,x,“执行环境”,,,,'中央处理器');% Sample the next character.newcharacter = dataSampe(词汇,1,“重量”,字符卡);%在文本结束时停止预测。如果newcharacter == endoftextcharacter休息结尾%将字符添加到生成的文本中。生成text =生成text + newcharacter;% Get the numeric index of the character.X = double(char(newCharacter));结尾

通过用相应的空格和新系列字符代替特殊字符来重建生成的文本。

generatedText = replace(generatedText,[newlineCharacter whitespaceCharacter],[newline“”)))
生成的=“”我希望达西先生,后来在我的背景下,我要加入Lucases。他们与他结婚。他现在要做的事情,当我读到的机会时;活泼地相信她将在情况下进行治疗,因为我很棒”

要生成多个文本,请使用resetState

net =重置(net);

也可以看看

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

Related Topics