主要内容

使用注意力的图像说明

这个例子展示了如何训练一个深度学习模型来使用注意力进行图像字幕。

大多数预训练的深度学习网络配置为单标签分类。例如,给定一张典型办公桌的图像,网络可能会预测单个类别的“键盘”或“鼠标”.相比之下,图像字幕模型结合卷积运算和循环运算,生成图像中内容的文本描述,而不是单个标签。

本例中训练的模型使用编码器-解码器体系结构。编码器是一个预训练的Inception-v3网络,用作特征提取器。解码器是一个递归神经网络(RNN),它将提取的特征作为输入并生成字幕。解码器包含一个注意机制这使得解码器在生成标题时能够关注部分编码输入。

编码器模型是一个预训练的Inception-v3模型,用于从“mixed10”层,然后是完全连接和ReLU操作。

译码器模型包括一个单词嵌入、一个注意机制、一个选通循环单元(GRU)和两个完全连接的操作。

负荷预训练网络

加载预训练的Inception-v3网络。此步骤需要深度学习工具箱™ 模型对于Inception-v3网络金宝app支持包。如果您没有安装所需的支持包,那么该软件将提供下载链接。金宝app

网= inceptionv3;inputSizeNet = net.Layers (1) .InputSize;

将网络转换为dlnetwork对象进行特征提取,并删除最后四层,保留“mixed10”层作为最后一层。

lgraph=图层(净);lgraph=移除图层(lgraph[“平均池”“预测”“预测\u softmax”“ClassificationLayer_predictions”]);

查看网络的输入层。Inception-v3网络使用对称重缩放规范化,最小值为0,最大值为255。

lgraph.Layers (1)
ans=ImageInputLayer,属性:Name:'input_1'InputSize:[299 299 3]超参数数据增强:'none'规格化:'rescale symmetric'规格化维度:'auto'最大值:255最小值:0

自定义训练不支持此规范化,因此必须在网络中禁用规范金宝app化,并在自定义训练循环中执行规范化。将最小值和最大值保存为名为输入分钟输入最大值,并将输入层替换为图像输入层而不进行规范化。

inputMin=double(lgraph.Layers(1.Min);inputMax=double(lgraph.Layers(1.Max);layer=imageInputLayer(inputSizeNet,“归一化”“没有”“名字”“输入”);lgraph = replaceLayer (lgraph,“输入_1”,层);

确定网络的输出大小。使用analyzeNetwork函数查看最后一层的激活大小。要分析网络中的自定义训练循环工作流,请设置目标用途选择“dlnetwork”

分析网络(lgraph,“TargetUsage”“dlnetwork”

创建一个名为输出SizeNet包含网络输出大小。

outputSizeNet=[8 2048];

将层图转换为dlnetwork对象并查看输出层。输出层是“mixed10”初始化v3网络的一层。

dlnet = dlnetwork (lgraph)
dlnet=dlnetwork,具有以下属性:层:[311×1 nnet.cnn.layer.layer]连接:[345×2表]可学习性:[376×3表]状态:[188×3表]输入名称:{input'}输出名称:{'mixed10'}

导入COCO数据集

从数据集“2014 Train images”和“2014 Train/val annotation”分别下载图片和注释https://cocodataset.org/#download。将图像和批注提取到名为的文件夹中“可可”. COCO 2014数据集由以下人员收集:可可财团

从文件中提取标题“标题\u train2014.json”使用jsondecode函数。

dataFolder=fullfile(tempdir,“可可”);文件名= fullfile (dataFolder,“annotations_trainval2014”“注释”“标题\u train2014.json”);str=fileread(文件名);data=jsondecode(str)
资料=带字段的结构:[1×1 struct] images: [82783×1 struct] licenses: [8×1 struct] annotation: [414113×1 struct]

注释结构体的字段包含图像标题所需的数据。

data.annotations
ans =4113×1带字段的结构数组:图像id标题

数据集包含每个图像的多个标题。为确保相同的图像不会同时出现在训练集和验证集中,请使用唯一的通过使用图像识别码字段,然后查看唯一图像的数量。

numObservationsAll=numel(data.annotations)
numObservationsAll=414113
ImageID=[data.annotations.image_id];imageIDsUnique=唯一(ImageID);numUniqueImages=numel(imageIDsUnique)
numUniqueImages=82783

每个图像至少有五个标题。创建一个结构注释所有使用以下字段:

  • 图像ID⁠——形象标识

  • 文件名⁠— 图像的文件名

  • 标题⁠— 原始标题的字符串数组

  • 字幕⁠-中相应标题的索引向量data.annotations

为了简化合并,请按图像ID对注释进行排序。

[~,idx]=排序([data.annotations.image_id]);data.annotations=data.annotations(idx);

在注释上循环并在必要时合并多个注释。

我= 0;j = 0;imageIDPrev = 0;虽然i如果imageID~=imageIDPrev%创建新条目j=j+1;注释所有(j).ImageID=ImageID;注释所有(j).Filename=fullfile(dataFolder,“train2014”“COCO_train2014_u”+pad(字符串(图像ID),12,“左”' 0 ') +“.jpg”);annotationsAll (j)。标题= caption; annotationsAll(j).CaptionIDs = i;其他的%添加标题注释所有(j).Captions=[annotationsAll(j).Captions;caption];注释所有(j).CaptionIDs=[annotationsAll(j).CaptionIDs;i];终止imageIDPrev=imageID;终止

将数据划分为训练集和验证集。拿出5%的观察值进行测试。

本量利= cvpartition(元素个数(annotationsAll),“坚持”,0.05); idxTrain=培训(cvp);idxTest=试验(cvp);annotationsTrain=annotationsAll(idxTrain);annotationsTest=annotationsAll(idxTest);

结构包含三个字段:

  • 身份证件-标题的唯一标识符

  • 说明文字-图像标题,指定为字符向量

  • 图像识别码-与标题对应的图像的唯一标识符

要查看图像和相应的标题,请找到具有文件名的图像文件“train2014 \ COCO_train2014_XXXXXXXXXXXX.jpg”,在那里“XXXXXXXXXX”对应的图像ID左填充为0,长度为12。

imageID = annotationsTrain (1) .ImageID;标题= annotationsTrain (1) .Captions;文件名= annotationsTrain (1) .Filename;

要查看图像,请使用伊姆雷德imshow功能。

img=imread(文件名);图imshow(img)标题(字幕)

为培训准备数据

为培训和测试准备标题。从中提取文本标题包含训练和测试数据的结构的字段(注释所有),删除标点符号,并将文本转换为小写。

captionsAll=类别(1,注释所有标题);captionsAll=删除标点符号(captionsAll);captionsAll=较低(captionsAll);

为了生成字幕,RNN解码器需要特殊的开始和停止标记,分别指示何时开始和停止生成文本。添加自定义标记分别放在字幕的开头和结尾。

字幕=+字幕+;

使用标记化文档函数指定开始和停止标记“定制代币”选项

documentsAll=标记化文档(字幕sall,“定制代币”,[]);

创建一个文字编码对象,该对象将单词映射为数字索引并返回。根据训练数据中最常观察到的单词,将词汇量设定为5000,以减少记忆要求。为了避免偏差,只使用与训练集相对应的文档。

内附= wordEncoding (documentsAll (idxTrain),“MaxNumWords”, 5000,“订单”“频率”);

创建包含与标题相对应的图像的增强图像数据存储。设置输出大小以匹配卷积网络的输入大小。若要使图像与标题保持同步,请通过使用图像ID重建文件名来指定数据存储的文件名表。若要以3-ch格式返回灰度图像,请退火RGB图像,设置“颜色预处理”选择“gray2rgb”

tblFilenames=表格(cat(1,annotationsTrain.Filename));augimdsTrain=增强图像数据存储(inputSizeNet,tblFilenames,“颜色预处理”“gray2rgb”
augimdsTrain = augmentedImageDatastore with properties: NumObservations: 78644 MiniBatchSize: 1 DataAugmentation: 'none' ColorPreprocessing: 'gray2rgb' OutputSize: [299 299] OutputSizeMode: 'resize' DispatchInBackground: 0

初始化模型参数

初始化模型参数。指定512个隐藏单元,单词嵌入维数为256。

embeddingDimension = 256;numHiddenUnits = 512;

初始化包含编码器模型参数的结构体。

  • 使用Glorot初始值设定项初始化完全连接的操作的权重,该初始值设定项由initializeGlorot函数,列在示例末尾。指定输出大小以匹配解码器(256)的嵌入维度,并指定输入大小以匹配预训练网络的输出通道数“mixed10”Inception-v3网络层使用2048个通道输出数据。

numFeatures=outputSizeNet(1)*outputSizeNet(2);InputSizenCoder=outputSizeNet(3);parametersEncoder=struct;%完全连接parameters sencoder.fc.Weights=dlarray(initializeGroot(embeddingDimension,InputSizenCoder));parameters sencoder.fc.Bias=dlarray(零([embeddingDimension 1],“单一”));

初始化包含解码器模型参数的结构。

  • 使用嵌入维度和词汇表大小加上1给出的大小初始化单词嵌入权重,其中额外的条目对应于填充值。

  • 初始化Bahdanau注意机制的权重和偏差,其大小与GRU操作的隐藏单元数相对应。

  • 初始化GRU操作的权重和偏差。

  • 初始化两个完全连接的操作的权重和偏差。

对于模型解码器参数,分别使用Glorot初始值设定项和零初始化每个权重和偏差。

inputSizeDecoder = encn . numwords + 1; / /输入一个数字parametersDecoder =结构;%单词嵌入参数decoder.emb.Weights=dlarray(initializeGroot(EmbeddedingDimension,InputSizedCoder));%注意parametersDecoder.attention。Weights1 = dlarray (initializeGlorot (numHiddenUnits embeddingDimension));parametersDecoder.attention。Bias1 = dlarray(0 ([numHiddenUnits 1],),“单一”)); ParametersCoder.attention.Weights2=dlarray(初始化为Lorot(numHiddenUnits,numHiddenUnits));ParametersCoder.attention.Bias2=dlarray(零([numHiddenUnits 1],“单一”));numHiddenUnits parametersDecoder.attention.WeightsV = dlarray (initializeGlorot (1));parametersDecoder.attention.BiasV = dlarray (0 (1, - 1,“单一”));%格勒乌parametersDecoder.gru.InputWeights = dlarray (initializeGlorot (3 * numHiddenUnits, 2 * embeddingDimension));parametersDecoder.gru.RecurrentWeights = dlarray (initializeGlorot (3 * numHiddenUnits numHiddenUnits));parametersDecoder.gru.Bias = dlarray (0 (3 * numHiddenUnits, 1,“单一”));%完全连接parametersDecoder.fc1.Weights=dlarray(初始化为LoRot(numHiddenUnits,numHiddenUnits));parametersDecoder.fc1.Bias=dlarray(零([numHiddenUnits 1]),“单一”));%完全连接parametersDecoder.fc2.Weights=dlarray(初始化为Lorot(enc.NumWords+1,numHiddenUnits));parametersDecoder.fc2.Bias=dlarray(零([enc.NumWords+1],“单一”));

定义模型函数

创建函数模型编码器模型解码器,分别计算编码器和解码器模型的输出。

模型编码器函数,列在编码器模型函数在示例的第节中,将激活数组作为输入dlX来自预训练网络的输出,并将其通过完全连接操作和ReLU操作。由于预训练网络不需要跟踪自动微分,因此在编码器模型函数之外提取特征在计算上更有效。

模型解码器函数,列在译码器模型函数在示例的第节中,将对应于输入字的单个输入时间步长、解码器模型参数、来自编码器的特征和网络状态作为输入,并返回下一时间步长的预测、更新的网络状态和注意权重。

指定培训选项

指定培训选项。培训30个时代,最小批量为128,并在绘图中显示培训进度。

miniBatchSize=128;numEpochs=30;绘图=“培训进度”;

如果GPU可用,在GPU上训练。使用GPU需要并行计算工具箱™ 和支持的GPU设备。有关支持的设备的信息,请参阅金宝appGPU支金宝app持情况(并行计算工具箱)

executionEnvironment =“汽车”;

列车网络的

使用自定义训练循环训练网络。

在每个历元开始时,对输入数据进行无序排列。为了使增强图像数据存储中的图像与标题保持同步,请创建一个无序排列的索引数组,将索引放入两个数据集中。

对于每个小批量:

  • 将图像重新缩放到预训练网络预期的大小。

  • 对于每个图像,选择一个随机标题。

  • 将标题转换为单词索引序列。使用与填充标记的索引对应的填充值指定序列的右填充。

  • 将数据转换为dlarray对象。对于图像,指定尺寸标签“SSCB”(空间、空间、通道、批次)。

  • 对于GPU培训,将数据转换为gpuArray对象。

  • 利用预先训练的网络提取图像特征,并将其重塑到编码器所期望的大小。

  • 评估模型梯度和损失使用德尔费瓦尔模型梯度功能。

  • 使用更新编码器和解码器模型参数阿达木酯函数。

  • 在绘图中显示培训进度。

初始化亚当优化器的参数。

trailingAvgEncoder=[];trailingAvgSqEncoder=[];trailingAvgDecoder=[];trailingavgsqdeecoder=[];

初始化训练进度图。创建一条动画线,根据相应的迭代绘制损失。

如果阴谋==“培训进度”figure lineLossTrain=动画线(“颜色”[0.85 0.325 0.098]);包含(“迭代”)伊拉贝尔(“损失”)ylim([0 inf])网格在…上终止

训练模型。

迭代= 0;numObservationsTrain =元素个数(annotationsTrain);numIterationsPerEpoch = floor(nummobservationstrain / miniBatchSize);开始=抽搐;%循环纪元。对于历元=1:numEpochs%洗牌数据。idxShuffle=randperm(numObservationsTrain);%循环小批。对于i=1:numIterationsPerEpoch迭代=迭代+1;%确定小批量指标。idx=(i-1)*miniBatchSize+1:i*miniBatchSize;idxMiniBatch=idxShuffle(idx);%读取小批量数据。tbl=readByIndex(augimdsTrain,idxMiniBatch);X=cat(4,tbl.input{:});annotations=annotationsTrain(idxMiniBatch);%对于每个图像,选择随机标题。idx=cellfun(@(CaptionId)randsample(CaptionId,1),{annotations.CaptionId});文件=文件所有(idx);%创建一批数据。[dlX,dlT]=createBatch(X,文档,dlnet,inputMin,inputMax,enc,executionEnvironment);%使用dlfeval和%模型梯度函数。[gradientsEncoder,gradientsEncoder,loss]=dlfeval(@modelGradients,parametersEncoder,...参数编码器、dlX、dlT);%使用adamupdate更新编码器。[参数SENCODER,trailingAvgEncoder,trailingAvgSqEncoder]=数据更新(参数SENCODER,...梯度编码器、跟踪AVGENCODER、跟踪AVGSQENCODER、迭代);%更新解码器使用adamupdate。[parametersDecoder,trailingAvgDecoder,trailingAvgSqDecoder]=数据更新(parametersDecoder,...梯度编码器、trailingAvgDecoder、trailingAVGSQdeecoder、迭代);%显示训练进度。如果阴谋==“培训进度”D=持续时间(0,0,toc(开始),“格式”“hh: mm: ss”);addpoints (lineLossTrain、迭代、双(收集(extractdata(损失))))标题(“时代:”+纪元+”,过去:“+字符串(D)现在开始终止终止终止

预测新标题

字幕生成过程与训练过程不同。在训练期间,解码器在每个时间步使用上一时间步的真实值作为输入。这称为“教师强制”。在对新数据进行预测时,解码器使用上一时间步的预测值而不是真实值。

预测序列中每一步最可能出现的单词可能导致次优结果。例如,如果解码器在给出大象的图像时预测标题的第一个单词是“a”,那么预测下一个单词的“大象”的概率就变得更不可能了,因为短语“大象”出现在英语文本中的概率非常低。

要解决这个问题,您可以使用波束搜索算法:不要对序列中的每个步骤采用最可能的预测,而是采用顶部预测k预测(光束指数),对于后续的每一步,保持顶部k根据总分预测到目前为止的序列。

通过提取图像特征,将其输入编码器,然后使用beamSearch函数,列在束搜索功能示例的第三部分。

img = imread (“laika_siting.jpg”);dlX = extractImageFeatures (dlnet img, inputMin inputMax, executionEnvironment);beamIndex = 3;maxNumWords = 20;(话说,attentionScores) = beamSearch (dlX、beamIndex parametersEncoder, parametersDecoder, enc, maxNumWords);标题=加入(字)
标题= "一只狗站在瓷砖地上"

显示带有标题的图像。

图imshow (img)标题(标题)

预测数据集的标题

要预测图像集合的标题,请循环数据存储中的小批量数据,并使用提取图像特征作用然后,在小批量中循环图像,并使用beamSearch函数。

创建增强图像数据存储,并设置输出大小以匹配卷积网络的输入大小。要将灰度图像输出为3通道RGB图像,请设置“颜色预处理”选择“gray2rgb”

TBLFileNameTest=表格(cat(1,annotationsTest.Filename));AugimdTest=增强图像数据存储(inputSizeNet,TBLFileNameTest,“颜色预处理”“gray2rgb”
augimdtest=augmentedImageDatastore,属性为:NumObservations:4139 MiniBatchSize:1 DataAugmentation:'none'颜色预处理:'gray2rgb'输出大小:[299 299]OutputSizeMode:'resize'DispatchInBackground:0

为测试数据生成标题。在大型数据集上预测标题可能需要一些时间。如果您有并行计算工具箱™, 然后,您可以通过在一个文档中生成标题来并行地进行预测parfor看,如果你没有并行计算工具箱,那么parfor循环以串行方式运行。

beamIndex=2;maxNumWords=20;numObservationsTest=numel(annotationsTest);NumItemationsTest=ceil(numObservationsTest/miniBatchSize);captionsTestPred=String(1,numObservationsTest);documentsTestPred=tokenizedDocument(String(1,numObservationsTest));对于我= 1:numIterationsTest%小批量索引。idxStart =(张)* miniBatchSize + 1;idxEnd = min(我* miniBatchSize numObservationsTest);idx = idxStart: idxEnd;深圳=元素个数(idx);%阅读图片。台= readByIndex (augimdsTest idx);%提取图像特征。猫(X = 4, tbl.input {:});dlX = extractImageFeatures (dlnet X, inputMin、inputMax executionEnvironment);%生成字幕。captionsPredMiniBatch=字符串(1,sz);documentsPredMiniBatch=标记化文档(字符串(1,sz));parforj=1:sz words=beamSearch(dlX(:,:,j),beamIndex,parametersEncoder,parametersDecoder,enc,maxNumWords);字幕predminibatch(j)=连接(单词);documentsPredMiniBatch(j)=标记化文档(文字、,“TokenizeMethod”“没有”);终止captionsTestPred(idx)=captionsPredMiniBatch;documentsTestPred(idx)=documentsPredMiniBatch;终止
分析并将文件传输给工人…完成。

要查看带有相应标题的测试图像,请使用imshow函数,并将标题设置为预测的标题。

idx=1;tbl=readByIndex(AugimdTest,idx);img=tbl.input{1};图imshow(img)标题(captionsTestPred(idx))

评估模型的准确性

要使用BLEU分数评估字幕的准确性,请使用bluevaluationscore函数。使用bluevaluationscore函数时,可以将单个候选文档与多个引用文档进行比较。

bluevaluationscore函数,默认情况下,使用长度为1到4的n-gram对相似度进行评分。由于标题较短,此行为可能导致不具信息性的结果,因为大多数分数接近于零。通过设置“NgramWeights”选择具有相等权重的两个元素向量。

ngramWeights=[0.5 0.5];对于i=1:numObservationsTest annotation=annotationsTest(i);captionIDs=annotation.captionIDs;候选者=文件测试(i);参考=文件所有(标题ID);分数=BLUEEvaluationScore(候选人、推荐人、,“NgramWeights”分数(i)=分数;终止

查看BLEU平均分数。

分数平均值=平均值(分数)
scoreMean = 0.4224

在直方图中可视化分数。

图直方图(分数)包含(“蓝色分数”)伊拉贝尔(“频率”

注意功能

注意函数使用Bahdanau attention计算上下文向量和注意权重。

作用[contextVector, attentionWeights] =注意(隐藏,特征,权重1,...bias1、weights2 bias2、weightsV biasV)%模型尺寸。[embeddingDimension,numFeatures,miniBatchSize]=尺寸(特征);numHiddenUnits=尺寸(权重1,1);%完全连接。dlY1 =重塑(特征,嵌入尺寸,numFeatures*miniBatchSize);dlY1 = fullyconnect (dlY1 weights1 bias1,“数据格式”“CB”);dlY1=重塑(dlY1,numHiddenUnits,numFeatures,miniBatchSize);%完全连接。dlY2=完全连接(隐藏、权重2、bias2、,“数据格式”“CB”);dlY2=重塑(dlY2,numHiddenUnits,1,miniBatchSize);%另外,谭。分数= tanh(dlY1 + dlY2);scores =重塑(scores, numHiddenUnits, numFeatures*miniBatchSize);%完全连接,softmax。注意权重=完全连接(分数、权重SV、biasV、,“数据格式”“CB”);attentionWeights =重塑(attentionWeights 1 numFeatures miniBatchSize);attentionWeights = softmax (attentionWeights,“数据格式”“SCB”);%的上下文。contextVector=注意力权重。*特征;contextVector=压缩(和(contextVector,2));终止

嵌入函数

嵌入函数将一个索引数组映射到一个嵌入向量序列。

作用Z =嵌入(X,权重)将输入重塑为向量[N,T]=尺寸(X,1:2);X=重塑(X,N*T,1);%嵌入矩阵的索引Z = weights(:, X);%通过分离批次和序列维度重塑输出Z=重塑(Z,[],N,T);终止

特征提取功能

提取图像特征函数将经过训练的dlnetwork对象、输入图像、图像缩放的统计信息和执行环境,并返回dlarray包含从预训练网络中提取的特征。

作用dlX = extractImageFeatures (dlnet X, inputMin、inputMax executionEnvironment)%调整大小并重新缩放。inputSize=dlnet.Layers(1).inputSize(1:2);X=imresize(X,inputSize);X=rescale(X,-1,1,“InputMin”,inputMin,“InputMax”,输入最大值);%转换为dlarray。dlX=dlX阵列(X,“SSCB”);%转换为gpuArray。如果(executionEnvironment = =“汽车”&&canUseGPU)| |执行环境==“gpu”dlX=gpuArray(dlX);终止%提取特征并重塑形状。dlX=预测(dlnet,dlX);sz=大小(dlX);numFeatures=sz(1)*sz(2);inputsizencoder=sz(3);miniBatchSize=sz(4);dlX=重塑(dlX,[numFeatures inputsizencoder miniBatchSize]);终止

批处理创建函数

createBatch函数将一小批数据、标记化字幕、预训练网络、用于图像重缩放的统计信息、字编码和执行环境作为输入,并返回与提取的图像特征和字幕相对应的一小批数据以供训练。

作用[dlX,dlT]=createBatch(X,documents,dlnet,inputMin,inputMax,enc,executionEnvironment)dlX=extractImageFeatures(dlnet,X,inputMin,inputMax,executionEnvironment);%将文档转换为单词索引序列。T = doc2sequence (enc、文档“PaddingDirection”“对”“PaddingValue”,enc.NumWords+1);T=cat(1,T{:});%将小批量数据转换为dlarray。dlT=dlT阵列(T);%如果在GPU上进行训练,则将数据转换为gpuArray。如果(executionEnvironment = =“汽车”&&canUseGPU)| |执行环境==“gpu”dlT = gpuArray (dlT);终止终止

编码器模型函数

模型编码器函数接受一系列激活作为输入dlX并将其通过完全连接的操作和ReLU操作。对于完全连接的操作,仅对通道维度进行操作。若要仅跨通道维度应用完全连接的操作,请将其他通道展平为单个维度,并使用“数据格式”选择权完全连接函数。

作用dlY = modelEncoder(dlX,parametersEncoder) [numFeatures,inputSizeEncoder,miniBatchSize] = size(dlX); / /输入参数%完全连接权重=参数sencoder.fc.权重;偏差=参数SENCODER.fc.偏差;嵌入尺寸=尺寸(重量,1);dlX=permute(dlX[2 1 3]);dlX=重塑(dlX、InputSizenCoder、numFeatures*miniBatchSize);dlY=完全连接(dlX、重量、偏差、,“数据格式”“CB”);dlY=重塑(dlY,嵌入尺寸,numFeatures,miniBatchSize);% ReLU海底= relu(海底);终止

译码器模型函数

模型解码器函数以单个时间步长作为输入dlX,解码器模型参数、编码器的特征和网络状态,并返回下一时间步的预测、更新的网络状态和注意权重。

作用[dlY,state,attentionWeights]=模型解码器(dlX,参数编码器,功能,状态)hiddenState=state.gru.hiddenState;%注意weights1 = parametersDecoder.attention.Weights1;bias1 = parametersDecoder.attention.Bias1;weights2 = parametersDecoder.attention.Weights2;bias2 = parametersDecoder.attention.Bias2;weightsV = parametersDecoder.attention.WeightsV;biasV = parametersDecoder.attention.BiasV;[contextVector, attentionWeights] = attention(hiddenState,features,weights1,bias1,weights2,bias2,weightsV,biasV);%嵌入权重=参数decoder.emb.weights;dlX=嵌入(dlX,权重);%连接dlY=cat(1,上下文向量,dlX);%格勒乌inputWeights = parametersDecoder.gru.InputWeights;recurrentWeights = parametersDecoder.gru.RecurrentWeights;偏见= parametersDecoder.gru.Bias;[dlY, hiddenState] = gru(dlY, hiddenState, inputwights, recurrentwights, bias,)“数据格式”“CBT”);%更新状态state.gru.HiddenState=HiddenState;%完全连接重量= parametersDecoder.fc1.Weights;偏见= parametersDecoder.fc1.Bias;海底= fullyconnect(海底,重量、偏见,“数据格式”“CB”);%完全连接权重=参数decoder.fc2.weights;偏差=参数decoder.fc2.bias;Dy=完全连接(Dy,权重,偏差,“数据格式”“CB”);终止

模型梯度

模型梯度函数将编码器和解码器参数作为输入,编码器具有dlX,以及目标标题dlT,并返回编码器和解码器参数相对于损耗、损耗和预测的梯度。

作用[梯度编码器,梯度编码器,丢失,dlYPred]=...modelGradients(parametersEncoder,parametersDecoder,dlX,dlT)miniBatchSize=大小(dlX,3);sequenceLength=大小(dlT,2)-1;vocabSize=大小(parametersDecoder.emb.Weights,2);%模型编码器功能=型号编码器(dlX,参数编码器);%初始化状态numHiddenUnits=大小(参数编码器注意权重1,1);状态=结构;state.gru.HiddenState=dlarray(零([numHiddenUnits miniBatchSize],“单一”));dlYPred=dlarray(零([vocabSize miniBatchSize sequenceLength],“喜欢”dlX));损失= dlarray(单(0));padToken = vocabSize;对于t = 1:sequenceLength decoderInput = dlT(:,t);dlYReal = dlT (:, t + 1);[dlYPred (:,:, t)状态]= modelDecoder (decoderInput, parametersDecoder、特征、状态);mask = dlYReal ~= padToken;loss = loss + sparseCrossEntropyAndSoftmax(dlYPred(:,:,t),dlYReal,mask);终止%计算梯度[gradientsEncoder,gradientsDecoder]=dlgradient(丢失,参数sEncoder,参数sDecoder);终止

稀疏交叉熵和Softmax损失函数

sparseCrossEntropyAndSoftmax将预测作为输入德利,相应的目标dlT,和序列填充掩码,并应用softmax函数并返回交叉熵损失。

作用loss = sparseCrossEntropyAndSoftmax(dlY, dlT, mask) miniBatchSize = size(dlY, 2);%Softmax。dlY=softmax(dlY,“数据格式”“CB”);找到与目标单词对应的行。idx = sub2ind(size(dlY), dlT', 1:miniBatchSize);海底=海底(idx);%从零开始。d = max(d, 1 -8);%掩饰的损失。损失=对数(DY)。*掩码';损失=-总和(损失,“全部”)。/ miniBatchSize;终止

束搜索功能

beamSearch函数将图像特征作为输入dlX,波束索引、编码器和解码器网络的参数、字编码和最大序列长度,并使用波束搜索算法返回图像的标题词。

作用[words,attentionScores]=波束搜索(dlX,波束索引,参数编码器,参数编码器,...enc,maxNumWords)%模型尺寸numFeatures=size(dlX,1);numHiddenUnits=size(parameters-coder.attention.weights 1,1);%提取特征功能=型号编码器(dlX,参数编码器);%初始化状态状态=结构;state.gru.HiddenState=dlarray(零([numHiddenUnits 1],“喜欢”dlX));%初始化的候选人候选者=结构;候选者.State=状态;候选者.Words=;候选人。分数= 0;候选人。AttentionScores = dlarray(0 ([numFeatures maxNumWords],“喜欢”,dlX));candidates.StopFlag=false;t=0;%重复单词虽然t%循环候选人对于i=1:numel(候选人)%预测停止令牌时停止生成如果候选人(i).停止标志持续终止%候选人详情状态=候选人(i)。状态;单词=候选人(i)。单词;分数=候选人(i)。分数;注意力分数=候选人(i)。注意力分数;%预测下一个标记decoderInput=word2ind(enc,words(end));[dlYPred,state,attentionScores(:,t)]=模型解码器(decoderInput,参数编码器,功能,状态);dlYPred=softmax(dlYPred,“数据格式”“CB”);[scoresTop,idxTop]=maxk(提取数据(dlYPred),beamIndex);idxTop=gather(idxTop);%循环预测对于j=1:beamIndex-candidate=struct;candidateWord=ind2word(enc,idxTop(j));candidateScore=scoresTop(j);如果候选词==candidate.StopFlag=true;注意分数(:,t+1:end)=[];其他的candidate.StopFlag=false;终止candidates.State=State;candidates.Words=[Words candidateWord];candidates.Score=Score+log(candidateScore);candidates.AttentionScores=AttentionScores;candidatesNew=[candidatesNew candidates];终止终止找到最优秀的候选人[~, idx] = maxk ([candidatesNew.Score], beamIndex);候选人= candidatesNew (idx);%当所有候选人都有停止标记时停止预测如果全部([candidates.stopfag])打破终止终止获得最佳候选人单词=候选词(1)。单词(2:end-1);注意力分数=候选人(1)。注意力分数;终止

Glorot权重初始化函数

initializeGlorot函数根据Glorot初始化生成权重数组。

作用权重=初始值为Lorot(numOut,numIn)varWeights=sqrt(6/(numIn+numOut));权重=varWeights*(2*rand([numOut,numIn]),“单一”) - 1);终止

另见

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

相关话题