这个例子展示了如何定义一个文本解码器模型函数。
在深度学习的背景下,解码器是深度学习网络的一部分,它将潜在向量映射到某个样本空间。您可以为各种任务使用解码向量。例如,
通过使用编码的向量初始化循环网络来生成文本。
使用编码的向量作为上下文向量进行序列到序列的转换。
使用编码向量作为上下文向量的图像标题。
从加载编码数据sonnetsEncoded.mat
.这个MAT文件包含单词编码,一个小批量的序列dlX
,以及相应的编码数据dlZ
由示例中使用的编码器输出定义文本编码器模型函数(深度学习工具箱).
S =负载“sonnetsEncoded.mat”);Enc = s.enc;dlX = s.dlX;dlZ = s.dlZ;[latentDimension,miniBatchSize] = size(dlZ,1:2);
解码器的目标是在给定一些初始输入数据和网络状态的情况下生成序列。
初始化以下模型的参数。
解码器使用初始化编码器输出的LSTM重构输入。对于每个时间步,解码器预测下一个时间步,并使用输出进行下一个时间步预测。编码器和解码器都使用相同的嵌入。
该模型使用了三种操作:
不过,嵌入映射范围为1的单词索引vocabularySize
到维度向量embeddingDimension
,在那里vocabularySize
编码词汇表中的单词数和embeddingDimension
是嵌入学习到的组件的数量。
LSTM操作将单个词向量作为输入,并输出1 × -numHiddenUnits
向量,numHiddenUnits
为LSTM操作中的隐藏单元数。LSTM网络的初始状态(第一个时间步的状态)是编码的向量,因此隐藏单元的数量必须与编码器的潜在维数匹配。
全连接操作将输入乘以一个权重矩阵,加上偏置和输出大小的向量vocabularySize
.
指定参数的尺寸。嵌入尺寸必须与编码器匹配。
embeddingDimension = 100;vocabularySize = en . numwords;numHiddenUnits = latentDimension;
为参数创建一个结构。
参数= struct;
初始化嵌入的权值使用高斯函数initializeGaussian
函数,该函数作为支持文件附加到本示例中。万博1manbetx指定平均值为0,标准差为0.01。要了解更多,请参见高斯函数初始化(深度学习工具箱).
Mu = 0;σ = 0.01;parameters.emb.Weights = initializeGaussian([embeddingDimension vocabularySize],mu,sigma);
初始化解码器LSTM操作的可学习参数:
可学习参数的大小取决于输入的大小。因为LSTM操作的输入是来自嵌入操作的字向量序列,所以输入通道的数量为embeddingDimension
.
输入权重矩阵有大小4 * numHiddenUnits
——- - - - - -inputSize
,在那里inputSize
输入数据的维度。
递归权矩阵有大小4 * numHiddenUnits
——- - - - - -numHiddenUnits
.
偏见向量有大小4 * numHiddenUnits
1。
sz = [4*numHiddenUnits embeddingDimension];numOut = 4*numHiddenUnits;numIn = embeddingDimension;parameters.lstmDecoder.InputWeights = initializeGlorot(sz,numOut,numIn);parameters. lstmdecoders . recurrentweights = initializeOrthogonal([4*numHiddenUnits numHiddenUnits]);parameters.lstmDecoder.Bias = initializeUnitForgetGate(numHiddenUnits);
初始化编码器完全连接操作的可学习参数:
使用gloot初始化器初始化权值。
方法初始化带有零的偏置initializeZeros
函数,该函数作为支持文件附加到本示例中。万博1manbetx要了解更多,请参见零初始化(深度学习工具箱).
可学习参数的大小取决于输入的大小。因为全连接操作的输入是LSTM操作的输出,所以输入通道的数量为numHiddenUnits
.使完全连接的运算输出向量具有大小latentDimension
,指定输出大小latentDimension
.
权重矩阵有大小outputSize
——- - - - - -inputSize
,在那里outputSize
而且inputSize
分别对应输出和输入尺寸。
偏见向量有大小outputSize
1。
使完全连接的运算输出向量具有大小vocabularySize
,指定输出大小vocabularySize
.
inputSize = numHiddenUnits;outputSize = vocabularySize;parameters.fcDecoder.Weights = dlarray(randn(outputSize,inputSize,“单一”));parameters.fcDecoder.Bias = dlarray(0 (outputSize,1,“单一”));
创建函数modelDecoder
,列于解码器模型函数部分,该部分计算解码器模型的输出。的modelDecoder
函数,取单词索引、模型参数和序列长度作为输入序列,并返回相应的潜在特征向量。
当使用自定义训练循环训练深度学习模型时,必须计算损失相对于可学习参数的梯度。这种计算依赖于模型函数向前传递的输出。
使用解码器生成文本数据有两种常见方法:
闭环——对于每个时间步,使用之前的预测作为输入进行预测。
开环——对于每个时间步,使用来自外部来源的输入(例如,训练目标)进行预测。
闭环生成是指模型每次生成一个时间步数据,并使用前一个预测作为下一个预测的输入。与开环生成不同,这个过程在预测之间不需要任何输入,最适合没有监督的场景。例如,一次性生成输出文本的语言翻译模型。
使用闭环
使用编码器输出初始化LSTM网络的隐藏状态dlZ
.
State = struct;状态。HiddenState = dlZ;状态。CellState = 0 (size(dlZ),“喜欢”, dlZ);
对于第一次步骤,使用一个开始令牌数组作为解码器的输入。为简单起见,从训练数据的第一个时间步中提取一个开始标记数组。
decoderInput = dlX(:,:,1);
预先分配解码器输出,使其具有大小numClasses
——- - - - - -miniBatchSize
——- - - - - -sequenceLength
具有相同的数据类型dlX
,在那里sequenceLength
是期望的生成长度,例如,训练目标的长度。对于本例,指定序列长度为16。
sequenceLength = 16;词汇量,miniBatchSize,sequenceLength,“喜欢”dlX);d = dlarray(d,“认知行为治疗”);
方法预测序列的下一个时间步modelDecoder
函数。在每次预测之后,找到解码器输出的最大值对应的指标,并使用这些指标作为下一个时间步的解码器输入。
为t = 1:sequenceLength [dlY(:,:,t), state] = modelDecoder(parameters,decoderInput,state);[~,idx] = max(dy (:,:,t));decoderInput = idx;结束
输出是vocabularySize
——- - - - - -miniBatchSize
——- - - - - -sequenceLength
数组中。
大小(海底)
ans =1×33595 32 16
此代码片段显示了在模型梯度函数中执行闭环生成的示例。
函数gradient = modelGradients(parameters,dlX,sequenceLengths)编码输入。dlZ = modelEncoder(参数,dlX,sequenceLengths);初始化LSTM状态。State = struct;状态。HiddenState = dlZ;状态。CellState = 0 (size(dlZ),“喜欢”, dlZ);初始化解码器输入。decoderInput = dlX(:,:,1);%闭环预测。sequenceLength = size(dlX,3);(numClasses,miniBatchSize,sequenceLength,“喜欢”dlX);为t = 1:sequenceLength [dlY(:,:,t), state] = modelDecoder(parameters,decoderInput,state);[~,idx] = max(dy (:,:,t));decoderInput = idx;结束%计算损失。%……%计算梯度。%……结束
当使用闭环生成进行训练时,为序列中的每个步骤预测最可能的单词可能会导致次优结果。例如,在图像字幕工作流中,如果给出大象的图像,解码器预测字幕的第一个单词是“a”,那么预测下一个单词为“elephant”的概率就变得更不可能了,因为短语“a elephant”出现在英语文本中的概率极低。
要帮助网络更快地聚合,您可以使用老师要求:使用目标值作为解码器的输入,而不是前面的预测。使用教师强制可以帮助网络从序列的后期时间步中学习特征,而不必等待网络正确生成序列的早期时间步。
要执行教师强迫,使用modelEncoder
直接使用目标序列作为输入函数。
使用编码器输出初始化LSTM网络的隐藏状态dlZ
.
State = struct;状态。HiddenState = dlZ;状态。CellState = 0 (size(dlZ),“喜欢”, dlZ);
使用目标序列作为输入进行预测。
dlY = modelDecoder(参数,dlX,状态);
输出是vocabularySize
——- - - - - -miniBatchSize
——- - - - - -sequenceLength
数组,sequenceLength
是输入序列的长度。
大小(海底)
ans =1×33595 32 14
此代码片段显示了在模型梯度函数中执行教师强制的示例。
函数gradient = modelGradients(parameters,dlX,sequenceLengths)编码输入。dlZ = modelEncoder(参数,dlX,dlZ);初始化LSTM状态。State = struct;状态。HiddenState = dlZ;状态。CellState = 0 (size(dlZ),“喜欢”, dlZ);老师强迫。dlY = modelDecoder(参数,dlX,状态);%计算损失。%……%计算梯度。%……结束
的modelDecoder
函数,以模型参数、词索引序列和网络状态为输入,返回解码后的序列。
因为lstm
函数是有状态(当给定一个时间序列作为输入时,函数在每个时间步之间传播和更新状态)和嵌入
而且fullyconnect
函数在默认情况下是时间分布的(当给定一个时间序列作为输入时,函数独立地对每个时间步进行操作)modelDecoder
函数支持序列和单时万博1manbetx间步输入。
函数[dlY,state] = modelDecoder(参数,dlX,state)%嵌入。weights = parameters.emb.Weights;dlX = embed(dlX,weights);% LSTM。inputWeights = parameters.lstmDecoder.InputWeights;recurrentWeights = parameters.lstmDecoder.RecurrentWeights;bias = parameters.lstmDecoder.Bias;hiddenState = state.HiddenState;cellState = state.CellState;[dlY,hiddenState,cellState] = lstm(dlX,hiddenState,cellState,...inputWeights recurrentWeights,偏差);状态。HiddenState = HiddenState;状态。CellState = CellState;%完全连接。weights = parameters.fcDecoder.Weights;bias = parameters.fcDecoder.Bias;ly =完全连接(ly,权重,偏差);结束
wordEncoding
|word2ind
|doc2sequence
|tokenizedDocument