主要内容

多输出列车网络

这个例子展示了如何训练具有多个输出的深度学习网络,这些输出预测手写数字的标签和旋转角度。

要使用多个输出训练网络,必须使用自定义训练循环来训练网络。

负荷训练数据

digitTrain4DArrayData函数加载图像、它们的数字标签和它们从垂直方向旋转的角度。创建一个arrayDatastore对象,然后使用结合函数创建包含所有培训数据的单个数据存储。提取类名和非离散响应数。

[XTrain, YTrain anglesTrain] = digitTrain4DArrayData;dsXTrain = arrayDatastore (XTrain,“IterationDimension”,4); dsYTrain=arrayDatastore(YTrain);dsAnglesTrain=arrayDatastore(anglesTrain);dsTrain=联合收割机(dsXTrain、dsYTrain、dsAnglesTrain);classNames=类别(YTrain);numClasses=numel(类名);numObservations=numel(YTrain);

查看培训数据中的一些图像。

idx=randperm(numObservations,64);I=imtile(XTrain(:,:,:,idx));图imshow(I)

定义深度学习模型

定义以下预测标签和旋转角度的网络。

  • 带有16个5 × 5滤波器的卷积-批数- relu块。

  • 两个卷积-batchnorm- relu块,每个块有32个3 × 3滤波器。

  • 前两个块周围的跳过连接,包含32个1乘1卷积的卷积batchnorm ReLU块。

  • 使用“添加”合并跳过连接。

  • 对于分类输出,具有大小为10(类数)的完全连接操作和softmax操作的分支。

  • 对于回归输出,具有大小为1(响应数)的完全连接操作的分支。

将主要图层块定义为图层图。

层=[imageInputLayer([28 1],“正常化”“没有”“名字”“在”)卷积2层(5,16,“填充”“一样”“名字”“conv1”)批处理规范化层(“名字”“bn1”) reluLayer (“名字”“relu1”)卷积2层(3,32,“填充”“一样”“步”2.“名字”“conv2”)批处理规范化层(“名字”“bn2”) reluLayer (“名字”“relu2”)卷积2层(3,32,“填充”“一样”“名字”“conv3”)批处理规范化层(“名字”“bn3”) reluLayer (“名字”“relu4”) additionLayer (2“名字”“添加”) fullyConnectedLayer (numClasses“名字”“fc1”) softmaxLayer (“名字”“softmax”));lgraph = layerGraph(层);

添加跳过连接。

层=[卷积2层(1,32,“步”2.“名字”“康斯基普”)批处理规范化层(“名字”“bnSkip”) reluLayer (“名字”“reluSkip”));lgraph = addLayers (lgraph层);lgraph = connectLayers (lgraph,“relu1”“康斯基普”);lgraph = connectLayers (lgraph,“reluSkip”“添加/ in2”);

为回归添加完全连接的图层。

层= fullyConnectedLayer (1,“名字”“fc2”);lgraph=添加层(lgraph,层);lgraph=连接层(lgraph,“添加”“fc2”);

在图中查看层图。

图形绘图(lgraph)

创建一个数据链路网络对象从图层图中删除。

dlnet = dlnetwork (lgraph)
dlnet = dlnetwork with properties: Layers: [17×1 nnet.cnn.layer.Layer] Connections: [17×2 table] Learnables: [20×3 table] State: [8×3 table] InputNames: {'in'} OutputNames: {'softmax' 'fc2'}

定义模型渐变函数

创建函数模型梯度,它接受作为输入的数据链路网络对象dlnet,一小批输入数据dlX有相应的目标T1T2分别包含标签和角度,并返回损失相对于可学习参数、更新网络状态和相应损失的梯度。

指定培训选项

指定训练选项。使用128的小批量训练30个历元。

numEpochs=30;miniBatchSize=128;

在一个情节中想象训练的进展。

情节=“培训进度”

列车模型

使用小型批处理队列处理和管理图像的小批量。对于每个小批量:

  • 使用自定义小批量预处理功能preprocessMiniBatch(在本例的最后定义)一次性对类标签进行编码。

  • 使用标注标签格式化图像数据“SSCB”(空间、空间、通道、批次)。默认情况下小型批处理队列对象将数据转换为dlarray具有底层类型的对象仅有一个的。请勿向类别标签或角度添加格式。

  • 如果GPU可用,则在GPU上进行训练。默认情况下小型批处理队列对象将每个输出转换为gpuArray如果GPU可用。使用GPU需要并行计算工具箱™ 和支持的GPU设备。有关支持的设备的信息,请参阅金宝appGPU版金宝app本支持(并行计算工具箱)

mbq=小型批处理队列(dsTrain,...“MiniBatchSize”,小批量,...“MiniBatchFcn”@preprocessData,...“MiniBatchFormat”,{“SSCB”});

使用自定义训练循环训练模型。对于每个历元,洗牌数据并循环小批量数据。在每次迭代结束时,显示训练进度。对于每个小批量:

  • 使用以下方法评估模型坡度和损失:德尔费瓦尔模型梯度函数。

  • 使用阿达木酯函数。

初始化训练进度图。

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

初始化Adam的参数。

trailingAvg = [];trailingAvgSq = [];

火车模型。

迭代=0;开始=tic;%环游各个时代。历元=1:numEpochs%洗牌数据。洗牌(兆贝可)%小批量循环hasdata(mbq)iteration=iteration+1;[dlX,dlY1,dlY2]=next(mbq);%使用dlfeval和%模型梯度函数。[gradient,state,loss] = dlfeval(@modelGradients, dlnet, dlX, dlY1, dlY2);dlnet。=状态;%使用Adam优化器更新网络参数。[dlnet, trailingAvg trailingAvgSq] = adamupdate (dlnet、渐变...trailingAvg trailingAvgSq,迭代);%显示训练进度。如果情节= =“培训进度”D =持续时间(0,0,toc(开始),“格式”“hh:mm:ss”); 添加点(lineLossTrain、迭代、双(聚集(提取数据(丢失)))标题(“时代:”+时代+”,过去:“+ drawnow字符串(D))结束结束结束

测试模型

通过将测试集上的预测与真实标签和角度进行比较,检验模型的分类精度。使用控件管理测试数据集小型批处理队列对象的设置与训练数据相同。

[XTest,Y1Test,anglesTest]=digitTest4DArrayData;dsXTest=arrayDatastore(XTest,“IterationDimension”,4); dsYTest=阵列数据存储(Y1Test);dsAnglesTest=arrayDatastore(anglesTest);dsTest=联合收割机(dsXTest、dsYTest、dsAnglesTest);mbqTest=minibatchqueue(dsTest,...“MiniBatchSize”,小批量,...“MiniBatchFcn”@preprocessData,...“MiniBatchFormat”,{“SSCB”});

要预测验证数据的标签和角度,请在小批量上循环并使用预测函数。存储预测的类和角度。比较预测的和真实的类和角度,并存储结果。

classesPredictions = [];anglesPredictions = [];classCorr = [];angleDiff = [];%在小批量上循环。hasdata(mbqTest)%读取小批量数据。[dlXTest,dlY1Test,dlY2Test]=next(mbqTest);%使用predict函数进行预测。[dlY1Pred, dlY2Pred] =预测(dlnet dlXTest,“产出”,[“softmax”“取得”]);%确定预测类。Y1PredBatch=onehotdecode(dlY1Pred,classNames,1);classesPredictions=[classesPredictions Y1PredBatch];Dermine预测角度批处理数据(批处理数据=预预测);%比较预测类和真实类Y1Test = onehotdecode (dlY1Test一会1);classCorr = [classCorr Y1PredBatch == Y1Test];%比较预测角度和真实角度angleDiffBatch=Y2PredBatch-dlY2Test;angleDiff=[angleDiff提取数据(收集(angleDiffBatch));结束

评估分类准确度。

准确度=平均值(classCorr)
精度= 0.9814

评估回归精度。

angleRMSE=sqrt(平均值(angleDiff.^2))
垂钓者=仅有一个的7.7431

查看一些图像及其预测。以红色显示预测的角度,以绿色显示正确的标签。

idx=randperm(大小(XTest,4),9);图i=1:9子批次(3,3,i)i=XTest(:,:,:,idx(i));imshow(i)保持在…上sz=尺寸(I,1);偏移量=sz/2;角度预测(idx(I));绘图(偏移量*[1-tand(thetaPred)1+tand(thetaPred)],[sz 0],“r——”)磁测=角度测试(idx(i));绘图(偏移量*[1-tand(磁测)1+tand(磁测)],[sz 0],“g——”)持有label=string(classesPredictions(idx(i));头衔(”的标签:“+标签)结束

模型梯度函数

模型梯度函数,作为输入数据链路网络对象dlnet,一小批输入数据dlX有相应的目标T1T2分别包含标签和角度,并返回损失相对于可学习参数、更新网络状态和相应损失的梯度。

函数[梯度,状态,损失]=模型梯度(dlnet,dlX,T1,T2)[dlY1,dlY2,状态]=正向(dlnet,dlX,“产出”,[“softmax”“取得”])损失率=交叉熵(dlY1,T1);损失率=均方误差(dlY2,T2);损失率=损失率+0.1*损失率;梯度=dlgradient(损失率,dlnet.Learnables);结束

小批量预处理函数

preprocessMiniBatch函数使用以下步骤预处理数据:

  1. 从传入的单元格数组中提取图像数据并连接到一个数字数组中。将图像数据连接到第四个维度上,为每个图像添加了第三个维度,用作单通道维度。

  2. 从传入的单元数组中提取标签和角度数据,并分别沿第二维度连接到分类数组和数字数组中。

  3. 一次性将分类标签编码为数字数组。编码到第一个维度会生成一个与网络输出形状匹配的编码数组。

函数[X,Y,角度]=预处理数据(XCell,YCell,angleCell)%从单元格中提取图像数据并连接猫(X = 4,伊势亚{:});%从单元格中提取标签数据并连接Y =猫(2,YCell {:});%从单元格中提取角度数据并连接角=猫(2,angleCell {:});%一个热编码标签Y=onehotcode(Y,1);结束

另请参阅

|||||||||||

相关话题