这个例子展示了如何定义一个文本编码器模型函数。
在深度学习的背景下,编码器是深度学习网络的一部分,将输入映射到某些潜在空间。您可以使用这些向量进行各种任务。例如,
通过将SoftMax操作应用于编码数据并使用跨熵损失来分类。
使用编码向量作为上下文向量进行序列到序列的转换。
该文件sonnets.txt
在一个文本文件中包含了莎士比亚所有的十四行诗。
阅读文件中的莎士比亚十四行诗数据“sonnets.txt”
.
文件名=“sonnets.txt”;textData = fileread(文件名);
SONNET由两个空白字符缩进。使用缩进使用取代
将文本分割成单独的行分裂
功能。从前九个元素和短十四圈标题中删除标题。
textData =取代(textData,”“,"");textData =分裂(textData、换行符);textData (1:9) = [];textData (strlength (textData) < 5) = [];
创建一个用于标记和预处理文本数据的函数。这个函数PreprocessText.
,在示例的末尾列出,执行以下步骤:
分别用指定的开始标记和停止标记添加和附加每个输入字符串。
使用授权文本tokenizedDocument
.
预处理文本数据并指定start和stop令牌“<开始>”
和“
,分别。
StartToken =.“<开始>”;停止=“” ;文件= preprocessText (textData startToken stopToken);
从标记化的文档创建单词编码对象。
enc = wordencoding(文档);
在培训深度学习模型时,输入数据必须是包含固定长度序列的数字阵列。由于文档具有不同的长度,因此必须使用填充值填充较短的序列。
重新创建编码的单词还包括填充令牌并确定该令牌的索引。
paddingtoken =“<垫>”;(内附newVocabulary =。词汇paddingToken];内附= wordEncoding (newVocabulary);paddingToken paddingIdx = word2ind (enc)
paddingIdx = 3595
编码器的目标是将单词索引序列映射到某个潜在空间中的向量。
初始化以下模型的参数。
该模型使用三种操作:
嵌入在范围内的Word Indice映射vocabularySize
对维度的载体embeddingdimension.
, 在哪里vocabularySize
编码词汇表中的单词数是多少embeddingdimension.
为通过嵌入学到的组件数。
LSTM操作将单词向量作为输入序列,输出1-by-numHiddenUnits
vectors,哪里numHiddenUnits
是LSTM操作中的隐藏单元的数量。
完全连接的操作将输入乘以权重矩阵添加偏置并输出大小的向量latentDimension
, 在哪里latentDimension
是潜在空间的尺寸。
指定参数的尺寸。
embeddingDimension = 100;numHiddenUnits = 150;latentDimension = 50;vocabularySize = enc.NumWords;
为参数创建结构。
参数=结构;
使用高斯函数初始化嵌入的权值initializeGaussian
函数,该函数作为支持文件附加到本示例中。金宝app指定0的平均值和0.01的标准偏差。要了解更多信息,请参阅高斯函数初始化.
mu = 0;sigma = 0.01;parameters.emb.weights = initializegaussian([Embeddingdimensionsize],mu,sigma);
初始化Encoder LSTM操作的可读参数:
可学习参数的大小取决于输入的大小。由于LSTM操作的输入是来自于嵌入操作的字向量序列,因此输入通道的数量为embeddingdimension.
.
输入权值矩阵有大小4 * numHiddenUnits
——- - - - - -输入
, 在哪里输入
是输入数据的维度。
复发重量矩阵具有大小4 * numHiddenUnits
——- - - - - -numHiddenUnits
.
偏差向量有大小4 * numHiddenUnits
-By-1。
sz = [4*numHiddenUnits embedingdimension]; / /隐藏尺寸numOut = 4 * numHiddenUnits;numIn = embeddingDimension;parameters.lstmEncoder.InputWeights = initializeGlorot(深圳、numOut numIn);parameters. lstmencoder . recurrentwights = initialize正交([4*numHiddenUnits numHiddenUnits]);parameters.lstmEncoder.Bias = initializeUnitForgetGate (numHiddenUnits);
初始化编码器完全连接操作的可读参数:
使用Glorot Initializer初始化权重。
属性用零初始化偏差initializeZeros
函数,该函数作为支持文件附加到本示例中。金宝app要了解更多信息,请参阅零初始化.
可学习参数的大小取决于输入的大小。因为全连接操作的输入是LSTM操作的输出,所以输入通道的数量为numHiddenUnits
.使全连接运算输出具有大小的向量latentDimension
,指定输出大小为latentDimension
.
权重矩阵具有大小输出
——- - - - - -输入
, 在哪里输出
和输入
分别对应输出维度和输入维度。
偏差向量有大小输出
-By-1。
sz = [LatentDimension numhidentunits];numout = latentdimension;numin = numhidendunits;参数.fcencoder.weights = initializeglorot(sz,numout,numin);parameters.fcencoder.bias = nigitizezeros([LatentDimension 1]);
创建函数modelEncoder
,列于编码器模型函数计算编码器模型的输出。的modelEncoder
功能,用作单词指数,模型参数和序列长度的输入序列,并返回相应的潜在特征向量。
要使用自定义训练循环训练模型,必须对小批量数据进行迭代,并将其转换为编码器模型和模型梯度函数所需的格式。本节示例演示了在自定义训练循环中准备一小批数据所需的步骤。
准备一个示例批次数据。选择一个迷你批次32个文件文档
.这代表了在自定义训练循环的迭代中使用的迷你批次数据。
miniBatchSize = 32;idx = 1: miniBatchSize;documentsBatch =文档(idx);
使用该文件将文档转换为序列doc2sequence
函数并指定右键键入与与填充令牌对应的单词索引的序列。
X = doc2sequence (enc documentsBatch,...“PaddingDirection”,“对”,...'paddingsvalue',paddingidx);
输出doc2sequence
函数是一个单元格数组,其中每个元素是字索引的行向量。由于编码器模型函数需要数字输入,因此使用猫
函数并指定沿第一个维度连接。输出有尺寸小匹匹匹匹配
——- - - - - -Sequencelength.
, 在哪里Sequencelength.
是最小批处理中最长序列的长度。
X =猫(1,X {:});大小(X)
ans =.1×232 14.
将数据转换为adlarray.
带格式的'BTC'
(批量、时间、通道)。该软件自动重新安排输出有格式'CTB'
输出有大小1
——- - - - - -小匹匹匹匹配
——- - - - - -Sequencelength.
.
dlx = dlarray(x,'BTC');尺寸(DLX)
ans =.1×31 32 14.
方法来计算输入数据的未填充序列长度doclength
功能与小批文件作为输入。
sequencelengths = doclength(DocuidetBatch);
此代码片段显示了在自定义训练循环中准备迷你批处理的示例。
迭代= 0;%循环epochs。为了时代= 1:numEpochs%循环在迷你批次。为了i = 1:numIterationsPerEpoch iteration = iteration + 1;%读取迷你批处理。idx =(张)* miniBatchSize + 1:我* miniBatchSize;documentsBatch =文档(idx);%转换为序列。X = doc2sequence (enc documentsBatch,...“PaddingDirection”,“对”,...'paddingsvalue',paddingidx);X = CAT(1,x {:});%转换为美元。dlx = dlarray(x,'BTC');%计算序列长度。sequencelengths = doclength(DocuidetBatch);%评估模型梯度。%……%更新可学习参数。%……结尾结尾
当使用自定义训练循环训练深度学习模型时,必须计算损失相对于可学习参数的梯度。这个计算依赖于模型函数的前向传递的输出。
要执行编码器的前向传递,请使用modelEncoder
函数直接使用参数、数据和序列长度作为输入。输出为latentDimension
——- - - - - -小匹匹匹匹配
矩阵。
dlz = modelencoder(参数,dlx,sequencelengs);尺寸(DLZ)
ans =.1×250 32.
此代码片段显示了在模型梯度函数中使用模型编码器函数的示例。
函数gradient = modelGradients(parameters,dlX,sequenceLengths) dlZ = modelEncoder(parameters,dlX,sequenceLengths);%计算损失。%……%计算梯度。%……结尾
此代码片段显示了评估自定义训练循环中的模型渐变的示例。
迭代= 0;%循环epochs。为了时代= 1:numEpochs%循环在迷你批次。为了i = 1:numIterationsPerEpoch iteration = iteration + 1;% mini-batch做好准备。%……%评估模型梯度。gradient = dlfeval(@modelGradients, parameters, dlX, sequenceLengths);%更新可学习参数。(参数、trailingAvg trailingAvgSq) = adamupdate(参数、渐变...trailingAvg trailingAvgSq,迭代);结尾结尾
的modelEncoder
函数,将模型参数、词索引序列和序列长度作为输入,返回相应的潜在特征向量。
由于输入数据包含不同长度的填充序列,填充可能对损失计算产生不利影响。对于LSTM操作,不是返回序列的最后一个时间步骤的输出(很可能对应于处理大量填充值后的LSTM状态),而是确定由sequenceLengths
输入。
函数dlZ = modelEncoder(参数、dlX sequenceLengths)%嵌入。重量= parameters.emb.Weights;dlZ =嵌入(dlX、重量);% LSTM。Inputweights = parameters.lstmencoder.Inputweights;refurrentweights = parameters.lstmencoder.recurrentweights;bias = parameters.lstmencoder.bias;numhidendunits =尺寸(复制重量,2);hiddenstate = zeros(numhidendunits,1,'像'dlX);cellState = 0 (numHiddenUnits 1'像'dlX);dlZ1 = lstm (dlZ hiddenState、cellState inputWeights, recurrentWeights,偏差);用屏蔽%输出模式“最后”。miniBatchSize =大小(dlZ1, 2);miniBatchSize, dlZ = 0 (numHiddenUnits'像'dlZ1);dlZ = dlarray (dlZ,“CB”);为了n = 1:miniBatchSize t = sequenceLengths(n);dlZ (:, n) = dlZ1 (:, n, t);结尾%完全连接。重量= parameters.fcEncoder.Weights;偏见= parameters.fcEncoder.Bias;dlZ = fullyconnect(重量,dlZ偏差);结尾
这个函数PreprocessText.
执行以下步骤:
分别用指定的开始标记和停止标记添加和附加每个输入字符串。
使用授权文本tokenizedDocument
.
函数文件= preprocessText (textData startToken stopToken)%添加开始和停止标记。textData = startToken + textData + stopToken;%标记文本。文档= tokenizeddocument(textdata,'CustomTokens', (startToken stopToken]);结尾