主要内容

使用模型函数更新批处理归一化统计

这个例子展示了如何在一个定义为函数的网络中更新网络状态。

批处理规范化操作规范化小批处理中的每个输入通道。为了加快卷积神经网络的训练并降低对网络初始化的敏感性,在卷积和非线性(如ReLU层)之间使用批量归一化操作。

在训练过程中,批处理归一化操作首先对每个通道的激活进行归一化,方法是减去小批均值并除以小批标准差。然后,操作将输入移动一个可学习的偏移量β然后用一个可学习的比例因子来缩放γ

当您使用训练过的网络对新数据进行预测时,批处理归一化操作使用训练过的数据集均值和方差而不是小批均值和方差对激活进行归一化。

要计算数据集统计信息,必须使用持续更新状态跟踪小批量统计信息。

如果在模型函数中使用批标准化操作,则必须定义训练和预测的行为。例如,可以指定布尔选项溺爱控制模型是使用小批量统计进行训练还是使用数据集统计进行预测。

来自模型函数的这段示例代码展示了如何应用批处理规范化操作,并在培训期间仅更新数据集统计信息。

如果doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance);%更新状态state.batchnorm1。TrainedMean = TrainedMean;state.batchnorm1。TrainedVariance = TrainedVariance;其他的Dy=批次标准(Dy、偏移、比例、训练平均值、训练方差);终止

负荷训练数据

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

[XTrain,YTrain,anglesTrain]=数字列车4ArrayData;dsXTrain=arrayDatastore(XTrain,“迭代维度”4);dsYTrain = arrayDatastore (YTrain);dsAnglesTrain = arrayDatastore (anglesTrain);dsTrain =结合(dsXTrain dsYTrain dsAnglesTrain);一会=类别(YTrain);numClasses =元素个数(类名);numResponses =大小(anglesTrain, 2);numObservations =元素个数(YTrain);

从训练数据中查看一些图像。

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

定义深度学习模型

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

  • 具有16个5×5滤波器的卷积块。

  • 两个卷积batchnorm块的一个分支,每个块有32个3×3的滤波器,每个滤波器之间有一个ReLU运算

  • 带有带有32个1 × 1卷积的卷积-批norm块的跳过连接。

  • 使用加法和ReLU操作组合两个分支

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

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

定义和初始化模型参数和状态

定义每个操作的参数并将其包含在结构中。使用parameters.OperationName.ParameterName在哪里参数是结构,O名称操作的名称(例如“conv1”)和参数名是参数的名称(例如,“权重”)。

创建一个结构参数包含模型参数。使用草签草签分别是示例函数。使用草签初始化例子函数,分别。

要使用批处理规范化层执行训练和推断,还必须管理网络状态。在预测之前,必须指定从训练数据派生的数据集平均值和方差。创建结构状态包含状态参数。批处理规范化统计信息不能为空dlarray对象。使用功能。

初始化示例函数作为支持文件附加到本示例中。万博1manbetx

初始化第一个卷积层的参数。

filterSize=[5];numChannels=1;numFilters=16;sz=[filterSize numChannels numFilters];numOut=prod(filterSize)*numFilters;nummin=prod(filterSize)*numFilters;parameters.conv1.Weights=initializeGlorot(sz,numOut,nummin);parameters.conv1.Bias=initializeZeros([numFilters 1]);

初始化第一批标准化层的参数和状态。

parameters.batchnorm1。Offset = initializeZeros([numFilters 1]);parameters.batchnorm1。Scale = initializeOnes([numFilters 1]);state.batchnorm1。TrainedMean = 0 (numFilters 1“单一”);state.batchnorm1。TrainedVariance = 1 (numFilters 1“单一”);

初始化第二个卷积层的参数。

filterSize = [3 3];numChannels = 16;numFilters = 32;sz = [filterSize numChannels numFilters];numOut = prod(filterSize) * numFilters;numIn = prod(filterSize) * numFilters;parameters.conv2。重量= initializeGlorot(深圳、numOut numIn);parameters.conv2。Bias = initializeZeros([numFilters 1]);

初始化第二批标准化层的参数和状态。

parameters.batchnorm2.Offset=initializeZeros([numFilters 1]);parameters.batchnorm2.Scale=initializeons([numFilters 1]);state.batchnorm2.TrainedMean=零(numFilters,1,“单一”); state.batchnorm2.TrainedVariance=个(numFilters,1,“单一”);

初始化第三卷积层的参数。

filterSize = [3 3];numChannels = 32;numFilters = 32;sz = [filterSize numChannels numFilters];numOut = prod(filterSize) * numFilters;numIn = prod(filterSize) * numFilters;parameters.conv3。重量= initializeGlorot(深圳、numOut numIn);parameters.conv3。Bias = initializeZeros([numFilters 1]);

初始化第三批标准化层的参数和状态。

parameters.batchnorm3。Offset = initializeZeros([numFilters 1]);parameters.batchnorm3。Scale = initializeOnes([numFilters 1]);state.batchnorm3。TrainedMean = 0 (numFilters 1“单一”);state.batchnorm3。TrainedVariance = 1 (numFilters 1“单一”);

初始化跳过连接中卷积层的参数。

filterSize = [1 1];numChannels = 16;numFilters = 32;sz = [filterSize numChannels numFilters];numOut = prod(filterSize) * numFilters;numIn = prod(filterSize) * numFilters;parameters.convSkip.Weights = initializeGlorot(深圳、numOut numIn);parameters.convSkip.Bias = initializeZeros([numFilters 1]);

在跳过连接中初始化批处理规范化层的参数和状态。

parameters.batchnormSkip.Offset=initializeZeros([numFilters 1]);parameters.batchnormSkip.Scale=initializeons([numFilters 1]);state.batchnormSkip.TrainedMean=零([numFilters 1]),“单一”);state.batchNormalskip.TrainedVariance=个([numFilters 1],“单一”);

初始化与分类输出相对应的完全连接层的参数。

sz=[numClasses 6272];numOut=numClasses;numIn=6272;parameters.fc1.Weights=初始值groot(sz,numOut,numIn);parameters.fc1.Bias=initializeZeros([numclass 1]);

初始化与回归输出相对应的完全连接层的参数。

sz = [numResponses 6272]; / /numOut = numResponses;numIn = 6272;parameters.fc2。重量= initializeGlorot(深圳、numOut numIn);parameters.fc2。Bias = initializeZeros([numResponses 1]);

查看状态的结构。

状态
状态=带字段的结构:BatchNormal1:[1×1结构]BatchNormal2:[1×1结构]BatchNormal3:[1×1结构]BatchNormalSkip:[1×1结构]

查看服务器的状态参数批次标准1操作。

state.batchnorm 1
ans=带字段的结构:培训平均值:[16×1个]培训差异:[16×1个]

定义模型函数

创建函数模型,它计算前面描述的深度学习模型的输出。

功能模型将模型参数作为输入参数,输入数据dlX,国旗溺爱,它指定模型是返回用于训练的输出还是用于预测的输出,以及网络状态状态。网络输出标签预测、角度预测和更新的网络状态。

定义模型梯度函数

创建函数modelGradients,列在示例的末尾,它接受一小批输入数据作为输入dlX与相应的目标T1T2分别包含标签和角度,并返回损耗相对于可学习参数的梯度、更新后的网络状态和相应的损耗。

指定培训选项

指定培训选项。

numEpochs = 20;miniBatchSize = 128;情节=“训练进步”;

列车模型

使用自定义训练循环训练模型。使用minibatchqueue处理和管理小批量图像。为每个mini-batch:

  • 使用自定义小批量预处理功能预处理小批量(在本例末尾定义)对类标签进行热编码。

  • 使用尺寸标签格式化图像数据“SSCB”(spatial, spatial, channel, batch)。默认情况下,minibatchqueue对象将数据转换为dlarray具有基础类型的对象。不要向类标签或角度添加格式。

  • 在可用的GPU上进行训练。默认情况下,minibatchqueue对象将每个输出转换为gpuArray如果有可用的GPU。使用GPU需要并行计算工具箱™和支持的GPU设备。万博1manbetx有关支持的设备的信息,请参见万博1manbetxGPU支万博1manbetx持情况(并行计算工具箱)

兆贝可= minibatchqueue (dsTrain,...“MiniBatchSize”miniBatchSize,...“MiniBatchFcn”@preprocessMiniBatch,...“MiniBatchFormat”,{“SSCB”,'',''});

对于每个epoch,洗牌数据并在小批数据上循环。在每个纪元的末尾,展示训练的进展情况。为每个mini-batch:

  • 评估模型梯度和损失使用dlfevalmodelGradients作用

  • 使用以下命令更新网络参数:adamupdate作用

初始化Adam解算器的参数。

trailingAvg=[];trailingAvgSq=[];

初始化培训进度图。

如果阴谋==“训练进步”figure lineosstrain = animatedline(“颜色”,[0.85 0.325 0.098]); ylim([0 inf])xlabel(“迭代”)伊拉贝尔(“损失”网格)终止

训练模型。

迭代= 0;开始=抽搐;%循环纪元。对于时代= 1:numEpochs%洗牌数据。洗牌(mbq)%循环小批虽然Hasdata (mbq) iteration = iteration + 1;[dlX, dlY1 dlY2] =下一个(兆贝可);%使用dlfeval和% modelGradients函数。[gradient,state,loss] = dlfeval(@modelGradients, parameters, dlX, dlY1, dlY2, state);%使用Adam优化器更新网络参数。(参数、trailingAvg trailingAvgSq) = adamupdate(参数、渐变...trailingAvg,trailingAvgSq,迭代);%显示培训进度。如果阴谋==“训练进步”D=持续时间(0,0,toc(开始),“格式”,“hh: mm: ss”);addpoints (lineLossTrain、迭代、双(收集(extractdata(损失))))标题(”时代:“+纪元+,已过:+字符串(D)现在开始终止终止终止

测试模型

通过将测试集上的预测与真实标签和角度进行比较,测试模型的分类精度。使用minibatchqueue对象具有与训练数据相同的设置。

[XTest, Y1Test anglesTest] = digitTest4DArrayData;dsXTest = arrayDatastore (XTest,“迭代维度”4);dsYTest = arrayDatastore (Y1Test);dsAnglesTest = arrayDatastore (anglesTest);dst =结合(dsXTest dsYTest dsAnglesTest);mbqTest = minibatchqueue (dst,...“MiniBatchSize”miniBatchSize,...“MiniBatchFcn”@preprocessMiniBatch,...“MiniBatchFormat”,{“SSCB”,'',''});

要预测验证数据的标签和角度,请使用modelPredictions函数,列在示例末尾。该函数返回预测的类和角度,以及与真值的比较。

[classesPredictions, anglesPredictions classCorr angleDiff] = modelPredictions(参数、状态、mbqTest类名);

评估分类精度。

精度=意味着(classCorr)
精度=0.9840

评估回归的准确性。

angleRMSE =√意味着(angleDiff ^ 2))
angleRMSE =6.3669

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

idx = randperm(大小(XTest, 4), 9);数字对于i = 1:9 subplot(3,3,i) i = XTest(:,:,:,idx(i));imshow (I)深圳=大小(我,1);抵消= sz / 2;thetaPred = anglesPredictions (idx (i));情节(抵消* [1-tand (thetaPred) 1 +罐内(thetaPred)], [sz 0],“r——”) = anglesTest(idx(i));情节(抵消* [1-tand (thetaValidation) 1 +罐内(thetaValidation)], [sz 0],“g——”)持有标签=字符串(classesPredictions (idx (i)));标题(“标签:”+标签)终止

模型函数

功能模型将模型参数作为输入参数,输入数据dlX,国旗溺爱,它指定模型是否返回用于训练或预测的输出,以及网络状态状态。该函数返回标签的预测、角度的预测和更新后的网络状态。

作用[dlY1,dlY2,状态]=模型(参数,dlX,点训练,状态)%卷积权重=parameters.conv1.weights;bias=parameters.conv1.bias;dlY=dlconv(dlX,权重,bias,“填充”,2);%批处理规范化,ReLUoffset=parameters.batchnorm1.offset;比例=参数。1。比例;trainedMean=state.batchNormal.trainedMean;trainedVariance=state.BatchNormal.trainedVariance;如果doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance);%更新状态state.batchnorm1。TrainedMean = TrainedMean;state.batchnorm1。TrainedVariance = TrainedVariance;其他的Dy=批次标准(Dy、偏移、比例、训练平均值、训练方差);终止dlY=relu(dlY);%卷积、批量标准化(跳过连接)权重=parameters.convSkip.weights;bias=parameters.convSkip.bias;dlYSkip=dlconv(dlY,权重,bias,“大步走”,2); offset=parameters.batchnormSkip.offset;scale=parameters.batchnormSkip.scale;trainedMean=state.batchNormalSkip.trainedMean;trainedVariance=state.batchNormalSkip.trainedVariance;如果doTraining [dlskip,trainedMean,trainedVariance] = batchnorm(dlskip,offset,scale,trainedMean,trainedVariance);%更新状态state.BatchNormalSkip.TrainedMean=TrainedMean;state.BatchNormalSkip.TrainedVariance=TrainedVariance;其他的dlYSkip = batchnorm (dlYSkip、抵消、规模、trainedMean trainedVariance);终止%卷积权重=parameters.conv2.weights;偏差=参数。2。偏差;dlY=dlconv(dlY、重量、偏差、,“填充”,1,“大步走”,2);%批处理规范化,ReLUoffset=parameters.batchnorm2.offset;比例=参数。2。比例;trainedMean=state.batchNormal2.trainedMean;trainedVariance=state.batchnorm2.trainedVariance;如果doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance);%更新状态state.batchnorm2。TrainedMean = TrainedMean;state.batchnorm2。TrainedVariance = TrainedVariance;其他的Dy=批次标准(Dy、偏移、比例、训练平均值、训练方差);终止dlY=relu(dlY);%卷积重量= parameters.conv3.Weights;偏见= parameters.conv3.Bias;海底= dlconv(海底,重量、偏见,“填充”,1);%批正常化offset=parameters.3.offset;比例=参数。3。比例;trainedMean=state.batchNormal3.trainedMean;trainedVariance=state.batchNormal3.trainedVariance;如果doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance);%更新状态state.batchnorm3。TrainedMean = TrainedMean;state.batchnorm3。TrainedVariance = TrainedVariance;其他的Dy=批次标准(Dy、偏移、比例、训练平均值、训练方差);终止%, ReLUly = dlskip + ly;dlY=relu(dlY);%完全连接,softmax(标签)重量= parameters.fc1.Weights;偏见= parameters.fc1.Bias;dlY1 = fullyconnect(海底,重量、偏见);dlY1 = softmax (dlY1);完全连接(角度)重量= parameters.fc2.Weights;偏见= parameters.fc2.Bias;dlY2 = fullyconnect(海底,重量、偏见);终止

模型梯度函数

这个modelGradients函数将模型参数作为输入,即输入数据的一小批dlX与相应的目标T1T2分别包含标签和角度,并返回损耗相对于可学习参数的梯度、更新后的网络状态和相应的损耗。

作用[gradient,state,loss] = modelGradients(parameters,dlX,T1,T2,state) doTraining = true;[dlY1、dlY2] =模型(参数、dlX doTraining、状态);lossLabels = crossentropy (dlY1, T1);lossAngles = mse (dlY2, T2);loss = lossLabels + 0.1*lossAngles;梯度= dlgradient(损失、参数);终止

模型的预测函数

这个modelPredictions函数取模型参数、网络状态、aminibatchqueue的输入数据mbq类中的所有数据进行迭代,返回模型预测minibatchqueue使用模型函数与溺爱选项设置为错误的。该函数返回预测的类和角度,以及与真实值的比较。对于类,比较是一个由1和0组成的向量,表示正确和错误的预测。对于角度,比较是预测的角度与真实值的差值。

作用[classesPredictions,anglesPredictions,classCorr,angleDiff] = modelPredictions(parameters,state,mbq,classes) doTraining = false;classesPredictions = [];anglesPredictions = [];classCorr = [];angleDiff = [];虽然hasdata(mbq) [dlX,dlY1,dlY2] = next(mbq);%使用模型函数进行预测。[dlY1Pred, dlY2Pred] =模型(参数、dlX doTraining、状态);%确定预测的类。Y1PredBatch = onehotdecode (dlY1Pred类1);classesPredictions = [classesPredictions Y1PredBatch];%真皮预测角Y2PredBatch = extractdata (dlY2Pred);anglesPredictions = [anglesPredictions Y2PredBatch];%比较预测的和真实的类Y1=onehotdecode(dlY1,类,1);classCorr=[classCorr Y1PredBatch==Y1];比较预测的和真实的角度angleDiffBatch = Y2PredBatch - dlY2;angleDiff = [angleDiff extractdata(gather(angleDiffBatch))];终止终止

Mini-Batch预处理功能

这个预处理小批量函数使用以下步骤对数据进行预处理:

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

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

  3. 一种是将分类标签编码为数字数组。编码到第一维将生成一个编码数组,该数组与网络输出的形状相匹配。

作用(X, Y,角)= preprocessMiniBatch(伊势亚、YCell angleCell)%从单元格提取图像数据并连接X=cat(4,XCell{:});%从单元格中提取标签数据并连接Y=cat(2,YCell{:});%从单元格提取角度数据并连接角度=cat(2,角度单元格{:});%一次性编码标签Y, Y = onehotencode (1);终止

另见

||||||||||||

相关的话题