主要内容

定义文本编码器模型功能

这个例子展示了如何定义一个文本编码器模型函数。

在深度学习的背景下,编码器是深度学习网络的一部分,将输入映射到某些潜在空间。您可以使用这些向量进行各种任务。例如,

  • 通过将SoftMax操作应用于编码数据并使用跨熵损失来分类。

  • 使用编码向量作为上下文向量进行序列到序列的转换。

加载数据

该文件sonnets.txt在一个文本文件中包含了莎士比亚所有的十四行诗。

阅读文件中的莎士比亚十四行诗数据“sonnets.txt”

文件名=“sonnets.txt”;textData = fileread(文件名);

SONNET由两个空白字符缩进。使用缩进使用取代将文本分割成单独的行分裂功能。从前九个元素和短十四圈标题中删除标题。

textData =取代(textData,”“"");textData =分裂(textData、换行符);textData (1:9) = [];textData (strlength (textData) < 5) = [];

准备数据

创建一个用于标记和预处理文本数据的函数。这个函数PreprocessText.,在示例的末尾列出,执行以下步骤:

  1. 分别用指定的开始标记和停止标记添加和附加每个输入字符串。

  2. 使用授权文本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-numHiddenUnitsvectors,哪里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操作的可读参数:

  • 属性使用gloria初始化器初始化输入权重initializeGlorot函数,该函数作为支持文件附加到本示例中。金宝app要了解更多信息,请参阅Glorot初始化

  • 使用正交初始化器初始化复制权重initializeOrthogonal函数,该函数作为支持文件附加到本示例中。金宝app要了解更多信息,请参阅正交初始化

  • 使用单元遗忘门初始化器初始化偏差initializeUnitForgetGate函数,该函数作为支持文件附加到本示例中。金宝app要了解更多信息,请参阅单位忘记门初始化

可学习参数的大小取决于输入的大小。由于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.执行以下步骤:

  1. 分别用指定的开始标记和停止标记添加和附加每个输入字符串。

  2. 使用授权文本tokenizedDocument

函数文件= preprocessText (textData startToken stopToken)%添加开始和停止标记。textData = startToken + textData + stopToken;%标记文本。文档= tokenizeddocument(textdata,'CustomTokens', (startToken stopToken]);结尾

另请参阅

||

相关的话题