更新批规范化统计使用模型的功能
这个例子展示了如何在网络更新网络状态定义为一个函数。
一批标准化操作规范化mini-batch每个输入通道。加快培训卷积神经网络,减少网络初始化敏感的缺点,使用批处理规范化操作之间的隆起和非线性,如ReLU层。
在训练,首先批规范化操作规范化每个通道的激活减去mini-batch均值和除以mini-batch标准差。然后,操作转换输入可学的抵消β可学的比例因子和尺度γ。
当你使用一个训练有素的网络进行预测新数据,批量标准化操作使用训练数据集的均值和方差的mini-batch均值和方差标准化激活。
计算数据集的统计数据,你必须跟踪mini-batch统计数据通过使用一个不断更新的状态。
如果你使用批处理标准化业务模型函数,那么你必须定义的行为训练和预测。例如,您可以指定一个布尔选项doTraining
控制模型使用是否mini-batch统计培训或数据集统计预测。
这个例子的代码从一个模型函数显示了如何应用一批标准化操作和更新只有在训练数据集的统计数据。
如果doTraining [Y, trainedMean, trainedVariance] = batchnorm (Y,抵消,规模、trainedMean trainedVariance);%更新状态state.batchnorm1。TrainedMean = TrainedMean;state.batchnorm1。TrainedVariance = TrainedVariance;其他的Y = batchnorm (Y,抵消,规模、trainedMean trainedVariance);结束
负荷训练数据
的digitTrain4DArrayData
函数加载图片,他们的数字标签,他们从垂直旋转角度。创建一个arrayDatastore
对象的图像、标签和角度,然后使用结合
函数来生成一个单一的数据存储,其中包含所有的训练数据。提取的类名称和数量非离散响应。
[XTrain, TTrain anglesTrain] = digitTrain4DArrayData;dsXTrain = arrayDatastore (XTrain IterationDimension = 4);dsTTrain = arrayDatastore (TTrain);dsAnglesTrain = arrayDatastore (anglesTrain);dsTrain =结合(dsXTrain dsTTrain dsAnglesTrain);一会=类别(TTrain);numClasses =元素个数(类名);numResponses =大小(anglesTrain, 2);numObservations =元素个数(TTrain);
从训练数据查看一些图像。
idx = randperm (numObservations, 64);我= imtile (XTrain (:,:,:, idx));图imshow(我)
定义深度学习模型
定义以下网络预测这两个标签和旋转角度。
一块convolution-batchnorm-ReLU 16 5-by-5过滤器。
两个convolution-batchnorm街区的一个分支与ReLU操作之间进行32 3 x3的过滤器
跳过连接与convolution-batchnorm块32 1×1的隆起。
结合两个分支使用添加了ReLU操作
回归的输出,一个分支完全连接操作的大小是1(响应)的数量。
分类输出,一个分支的完全连接操作10码(类)的数量和softmax操作。
定义并初始化模型参数和状态
为每个操作定义的参数,包括结构。使用格式parameters.OperationName.ParameterName
在哪里参数
阿,是结构体perationName
是操作的名称(例如“conv1”)和ParameterName
参数的名称(例如,“权重”)。
创建一个结构体参数
包含模型参数。初始化可学的层使用的重量和偏见initializeGlorot
和initializeZeros
例子函数,分别。初始化批量标准化抵消和尺度参数initializeZeros
和initializeOnes
例子函数,分别。
使用批处理执行培训和推理归一化层,你还必须管理网络状态。预测之前,您必须指定数据集训练数据的均值和方差。创建一个结构体状态
包含状态参数。批处理不能正常化统计数据dlarray
对象。初始化批量标准化训练有素的均值和方差州使用训练0
和的
函数,分别。
初始化实例函数附加到这个例子作为支持文件。金宝app
初始化参数第一卷积层。
filterSize = 5 [5];numChannels = 1;numFilters = 16;深圳= [filterSize numChannels numFilters];numOut =刺激(filterSize) * numFilters;numIn =刺激(filterSize) * numFilters;parameters.conv1。重量= initializeGlorot(深圳、numOut numIn);parameters.conv1。偏见= initializeZeros ([numFilters 1]);
初始化参数和第一批国家正常化层。
parameters.batchnorm1。抵消= initializeZeros ([numFilters 1]);parameters.batchnorm1。规模= initializeOnes ([numFilters 1]);state.batchnorm1。TrainedMean = initializeZeros ([numFilters 1]);state.batchnorm1。TrainedVariance = initializeOnes ([numFilters 1]);
第二个卷积层初始化参数。
filterSize = 3 [3];numChannels = 16;numFilters = 32;深圳= [filterSize numChannels numFilters];numOut =刺激(filterSize) * numFilters;numIn =刺激(filterSize) * numFilters;parameters.conv2。重量= initializeGlorot(深圳、numOut numIn);parameters.conv2。偏见= initializeZeros ([numFilters 1]);
初始化参数和国家第二批的归一化层。
parameters.batchnorm2。抵消= initializeZeros ([numFilters 1]);parameters.batchnorm2。规模= initializeOnes ([numFilters 1]);state.batchnorm2。TrainedMean = initializeZeros ([numFilters 1]);state.batchnorm2。TrainedVariance = initializeOnes ([numFilters 1]);
初始化参数回旋的第三层。
filterSize = 3 [3];numChannels = 32;numFilters = 32;深圳= [filterSize numChannels numFilters];numOut =刺激(filterSize) * numFilters;numIn =刺激(filterSize) * numFilters;parameters.conv3。重量= initializeGlorot(深圳、numOut numIn);parameters.conv3。偏见= initializeZeros ([numFilters 1]);
初始化参数和国家第三批标准化层。
parameters.batchnorm3。抵消= initializeZeros ([numFilters 1]);parameters.batchnorm3。规模= initializeOnes ([numFilters 1]);state.batchnorm3。TrainedMean = initializeZeros ([numFilters 1]);state.batchnorm3。TrainedVariance = initializeOnes ([numFilters 1]);
初始化参数中的卷积层跳过连接。
filterSize = [1];numChannels = 16;numFilters = 32;深圳= [filterSize numChannels numFilters];numOut =刺激(filterSize) * numFilters;numIn =刺激(filterSize) * numFilters;parameters.convSkip。重量= initializeGlorot(深圳、numOut numIn);parameters.convSkip。偏见= initializeZeros ([numFilters 1]);
初始化参数和状态的批量标准化层跳过连接。
parameters.batchnormSkip。抵消= initializeZeros ([numFilters 1]);parameters.batchnormSkip。规模= initializeOnes ([numFilters 1]);state.batchnormSkip。TrainedMean = initializeZeros ([numFilters 1]);state.batchnormSkip。TrainedVariance = initializeOnes ([numFilters 1]);
初始化参数相对应的完全连接层分类的输出。
深圳= [numClasses 6272];numOut = numClasses;numIn = 6272;parameters.fc1。重量= initializeGlorot(深圳、numOut numIn);parameters.fc1。偏见= initializeZeros ([numClasses 1]);
初始化参数相对应的完全连接层回归的输出。
深圳= [numResponses 6272];numOut = numResponses;numIn = 6272;parameters.fc2。重量= initializeGlorot(深圳、numOut numIn);parameters.fc2。偏见= initializeZeros ([numResponses 1]);
视图的结构状态。
状态
状态=结构体字段:batchnorm1:(1×1结构)batchnorm2: [1×1 struct] batchnorm3: [1×1 struct] batchnormSkip: [1×1 struct]
查看状态参数batchnorm1
操作。
state.batchnorm1
ans =结构体字段:TrainedMean: [16×1 dlarray] TrainedVariance: [16×1 dlarray]
定义模型函数
创建函数模型
上市的例子,计算前面描述的深度学习模型的输出。
这个函数模型
取模型作为输入参数参数
输入数据,国旗doTraining
,它指定是否返回输出培训或预测的模型,和网络状态状态
。网络输出标签的预测,预测的角度,更新网络状态。
定义模型损失函数
创建函数modelLoss
上市的例子,需要mini-batch作为输入的输入数据与相应的目标T1
和T2
分别包含标签和角度,并返回损失,损失的梯度对可学的参数,并更新网络状态。
指定培训选项
指定培训选项。
numEpochs = 20;miniBatchSize = 128;
火车模型
火车模型使用自定义训练循环。使用minibatchqueue
处理和管理mini-batches图像。为每个mini-batch:
使用自定义mini-batch预处理功能
preprocessMiniBatch
(在这个例子中定义)一个炎热的编码类标签。格式的图像数据维度标签
“SSCB”
(空间、空间、通道、批)。默认情况下,minibatchqueue
把数据转换为对象dlarray
对象与基本类型单
。没有格式添加到类标签或角度。火车在GPU如果一个是可用的。默认情况下,
minibatchqueue
将每个输出转换为对象gpuArray
如果一个GPU是可用的。使用GPU需要并行计算工具箱™和支持GPU设备。金宝app支持设备的信息,请参阅金宝appGPU计算的需求(并行计算工具箱)。
兆贝可= minibatchqueue (dsTrain,…MiniBatchSize = MiniBatchSize,…MiniBatchFcn = @preprocessMiniBatch,…MiniBatchFormat = [“SSCB””“”“]);
对于每一个时代,洗牌和遍历mini-batches数据的数据。在每个时代,显示培训进展。为每个mini-batch:
评估损失和梯度模型使用
dlfeval
和modelLoss
函数。更新网络参数使用
adamupdate
函数。
亚当的初始化参数解算器。
trailingAvg = [];trailingAvgSq = [];
初始化培训进展阴谋。
图C = colororder;lineLossTrain = animatedline(颜色= C (2:));ylim([0正])包含(“迭代”)ylabel (“损失”网格)在
火车模型。
迭代= 0;开始=抽搐;%循环时期。为时代= 1:numEpochs%洗牌数据。洗牌(兆贝可)%循环mini-batches而hasdata(兆贝可)迭代=迭代+ 1;[X, T1, T2] =下一个(兆贝可);%损失评估模型,使用dlfeval和渐变和状态% modelLoss函数。(损失、渐变、状态)= dlfeval (@modelLoss、参数X, T1, T2,状态);%更新使用亚当优化网络参数。(参数、trailingAvg trailingAvgSq) = adamupdate(参数、渐变…trailingAvg trailingAvgSq,迭代);%显示培训进展。D =持续时间(0,0,toc(开始),格式=“hh: mm: ss”);=双重损失(损失);addpoints (lineLossTrain、迭代、失去)标题(”时代:“+时代+”,过去:“+ drawnow字符串(D))结束结束
测试模型
测试模型的分类精度通过比较测试集上的预测与真正的标签和角度。管理测试数据集使用minibatchqueue
作为训练数据对象使用相同的设置。
[XTest, T1Test anglesTest] = digitTest4DArrayData;dsXTest = arrayDatastore (XTest IterationDimension = 4);dst = arrayDatastore (T1Test);dsAnglesTest = arrayDatastore (anglesTest);dst =结合(dsXTest dsTTest dsAnglesTest);mbqTest = minibatchqueue (dst,…MiniBatchSize = MiniBatchSize,…MiniBatchFcn = @preprocessMiniBatch,…MiniBatchFormat = [“SSCB””“”“]);
预测的标签和角度验证数据,使用modelPredictions
函数,列出的例子。函数返回预测类和角度,以及与真实值进行比较。
[classesPredictions, anglesPredictions classCorr angleDiff] = modelPredictions(参数、状态、mbqTest类名);
评估分类精度。
精度=意味着(classCorr)
精度= 0.9824
回归精度进行评估。
angleRMSE =√意味着(angleDiff ^ 2))
angleRMSE =单7.9194
视图的一些图片和他们的预测。显示预测的角度在绿色红色和正确的角度。
idx = randperm(大小(XTest, 4), 9);图为i = 1:9次要情节(3 3 i) i = XTest (:,:,:, idx(我));imshow (I)在深圳=大小(我,1);抵消= sz / 2;thetaPred = anglesPredictions (idx (i));情节(抵消* [1-tand (thetaPred) 1 +罐内(thetaPred)], [sz 0],“r——”)thetaValidation = anglesTest (idx (i));情节(抵消* [1-tand (thetaValidation) 1 +罐内(thetaValidation)], [sz 0],“g——”)举行从标签=字符串(classesPredictions (idx (i)));标题(”的标签:“+标签)结束
模型函数
这个函数模型
取模型作为输入参数参数
,输入数据X
的国旗doTraining
,它指定是否返回输出培训或预测模型,和网络状态状态
。函数返回标签的预测,预测的角度,更新网络状态。
函数(Y1、Y2、状态)=模型(参数X, doTraining状态)%卷积重量= parameters.conv1.Weights;偏见= parameters.conv1.Bias;Y = dlconv (X,重量、偏见、填充= 2);%批正常化,ReLU抵消= parameters.batchnorm1.Offset;规模= parameters.batchnorm1.Scale;trainedMean = state.batchnorm1.TrainedMean;trainedVariance = state.batchnorm1.TrainedVariance;如果doTraining [Y, trainedMean, trainedVariance] = batchnorm (Y,抵消,规模、trainedMean trainedVariance);%更新状态state.batchnorm1。TrainedMean = TrainedMean;state.batchnorm1。TrainedVariance = TrainedVariance;其他的Y = batchnorm (Y,抵消,规模、trainedMean trainedVariance);结束Y = relu (Y);%卷积,批正常化(跳过连接)重量= parameters.convSkip.Weights;偏见= parameters.convSkip.Bias;YSkip = dlconv (Y,重量、偏见、步幅= 2);抵消= parameters.batchnormSkip.Offset;规模= parameters.batchnormSkip.Scale;trainedMean = state.batchnormSkip.TrainedMean;trainedVariance = state.batchnormSkip.TrainedVariance;如果doTraining [YSkip、trainedMean trainedVariance] = batchnorm (YSkip、抵消、规模、trainedMean trainedVariance);%更新状态state.batchnormSkip。TrainedMean = TrainedMean;state.batchnormSkip。TrainedVariance = TrainedVariance;其他的YSkip = batchnorm (YSkip、抵消、规模、trainedMean trainedVariance);结束%卷积重量= parameters.conv2.Weights;偏见= parameters.conv2.Bias;Y = dlconv (Y,重量、偏见、填充= 1,跨步= 2);%批正常化,ReLU抵消= parameters.batchnorm2.Offset;规模= parameters.batchnorm2.Scale;trainedMean = state.batchnorm2.TrainedMean;trainedVariance = state.batchnorm2.TrainedVariance;如果doTraining [Y, trainedMean, trainedVariance] = batchnorm (Y,抵消,规模、trainedMean trainedVariance);%更新状态state.batchnorm2。TrainedMean = TrainedMean;state.batchnorm2。TrainedVariance = TrainedVariance;其他的Y = batchnorm (Y,抵消,规模、trainedMean trainedVariance);结束Y = relu (Y);%卷积重量= parameters.conv3.Weights;偏见= parameters.conv3.Bias;Y = dlconv (Y,重量、偏见、填充= 1);%批正常化抵消= parameters.batchnorm3.Offset;规模= parameters.batchnorm3.Scale;trainedMean = state.batchnorm3.TrainedMean;trainedVariance = state.batchnorm3.TrainedVariance;如果doTraining [Y, trainedMean, trainedVariance] = batchnorm (Y,抵消,规模、trainedMean trainedVariance);%更新状态state.batchnorm3。TrainedMean = TrainedMean;state.batchnorm3。TrainedVariance = TrainedVariance;其他的Y = batchnorm (Y,抵消,规模、trainedMean trainedVariance);结束%,ReLUY = YSkip + Y;Y = relu (Y);%完全连接,softmax(标签)重量= parameters.fc1.Weights;偏见= parameters.fc1.Bias;日元= fullyconnect (Y,重量,偏差);日元= softmax (Y1);%完全连接(角度)重量= parameters.fc2.Weights;偏见= parameters.fc2.Bias;Y2 = fullyconnect (Y,重量,偏差);结束
损失函数模型
的modelLoss
函数模型参数作为输入,mini-batch的输入数据X
与相应的目标T1
和T2
分别包含标签和角度,并返回损失,损失的梯度对可学的参数,并更新网络状态。
函数(损失、渐变、状态)= modelLoss(参数X, T1, T2,状态)doTraining = true;(Y1、Y2、状态)=模型(参数X, doTraining状态);lossLabels = crossentropy (Y1, T1);lossAngles = mse (Y2, T2);损失= lossLabels + 0.1 * lossAngles;梯度= dlgradient(损失、参数);结束
模型的预测函数
的modelPredictions
函数模型参数、网络状态minibatchqueue
的输入数据兆贝可
网络课程,并返回遍历所有数据的预测模型minibatchqueue
使用模型
函数与doTraining
选项设置为假
。函数返回预测类和角度,以及与真实值进行比较。类,比较是一个向量的1和0代表正确的和不正确的预测。角度,比较预测角之间的差异和真正的价值。
函数[classesPredictions, anglesPredictions classCorr angleDiff] = modelPredictions(参数、状态、兆贝可类)doTraining = false;classesPredictions = [];anglesPredictions = [];classCorr = [];angleDiff = [];而hasdata(兆贝可)[X, T1, T2] =下一个(兆贝可);%使用模型函数进行预测。(Y1, Y2) =模型(参数X, doTraining状态);%确定预测类。Y1PredBatch = onehotdecode (Y1、类1);classesPredictions = [classesPredictions Y1PredBatch];% Dermine预测角度Y2PredBatch = extractdata (Y2);anglesPredictions = [anglesPredictions Y2PredBatch];%比较预测和真正的类日元= onehotdecode (T1、类1);classCorr = [classCorr Y1PredBatch = = Y1);%比较预测和真正的角度angleDiffBatch = Y2PredBatch - T2;angleDiff = [angleDiff extractdata(收集(angleDiffBatch))];结束结束
Mini-Batch预处理功能
的preprocessMiniBatch
使用以下步骤:预处理数据函数
提取图像数据从传入单元阵列和连接到一个数字数组。连接图像数据在四维空间增加了一个三维图像,作为单通道尺寸。
从传入细胞提取标签和角度数据数组和连接到一个分类数组和一个数字数组,分别。
一个炎热的分类标签编码成数字数组。编码的第一个维度产生一个相匹配的形状编码阵列网络输出。
函数[X, T,角]= preprocessMiniBatch (dataX、人数(dataAngle)%从细胞中提取图像数据和连接猫(X = 4, dataX {:});%从细胞中提取标签数据和连接猫(T = 2,人数({});%从细胞中提取角数据和连接角=猫(2,dataAngle {:});%一个炎热的编码标签T = onehotencode (T, 1);结束
另请参阅
dlarray
|sgdmupdate
|dlfeval
|dlgradient
|fullyconnect
|dlconv
|softmax
|线性整流函数(Rectified Linear Unit)
|batchnorm
|crossentropy
|minibatchqueue
|onehotencode
|onehotdecode