主要内容

列车网络与自定义训练循环

这个例子展示了如何设置一个自定义训练循环并行训练网络。在这个例子中,平行的工人训练部分整体mini-batch。如果你有一个GPU,然后训练在GPU上没有发生。在培训期间,DataQueue对象MATLAB将培训进展信息发送回客户端。

加载数据集

负载数字数据集和创建一个图像数据存储的数据集。将数据存储到训练和测试数据存储在一个随机的方式。创建一个augmentedImageDatastore包含了训练数据。

digitDatasetPath = fullfile (matlabroot,“工具箱”,“nnet”,“nndemos”,“nndatasets”,“DigitDataset”);imd = imageDatastore (digitDatasetPath,“IncludeSubfolders”,真的,“LabelSource”,“foldernames”);[imdsTrain, imdsTest] = splitEachLabel (imd, 0.9,“随机”);inputSize = [28 28 1];augimdsTrain = augmentedImageDatastore (inputSize (1:2), imdsTrain);

确定训练集的不同的类。

类=类别(imdsTrain.Labels);numClasses =元素个数(类);

定义网络

定义你的网络体系结构,让它变成一个层图使用layerGraph函数。这个网络体系结构包括一批标准化层,跟踪数据的均值和方差的统计数据集。当并行训练,结合统计数据从所有的工人在每个迭代步骤,以确保网络状态反映了整个mini-batch。否则,网络状态可以发散在工人。如果你是递归神经网络训练状态(RNNs),例如,使用序列数据分割成更小的序列来训练网络包含LSTM或格勒乌层,你还必须管理的工人之间的状态。

层= [imageInputLayer ([28 28 1],“名字”,“输入”,“归一化”,“没有”20岁的)convolution2dLayer (5“名字”,“conv1”)batchNormalizationLayer (“名字”,“bn1”)reluLayer (“名字”,“relu1”20岁的)convolution2dLayer (3“填充”,1“名字”,“conv2”)batchNormalizationLayer (“名字”,“bn2”)reluLayer (“名字”,“relu2”20岁的)convolution2dLayer (3“填充”,1“名字”,“conv3”)batchNormalizationLayer (“名字”,“bn3”)reluLayer (“名字”,“relu3”)fullyConnectedLayer (numClasses“名字”,“俱乐部”));lgraph = layerGraph(层);

创建一个dlnetwork对象的层图。dlnetwork培训对象允许使用自定义循环。

dlnet = dlnetwork (lgraph)
dlnet = dlnetwork属性:层:[11×1 nnet.cnn.layer.Layer]连接:[10×2表]可学的:[14×3表]状态:[6×3表]InputNames:{“输入”}OutputNames:{“俱乐部”}初始化:1

设置并行环境

确定gpu可用于MATLAB使用canUseGPU函数。

  • 如果有可用的gpu,然后火车在gpu上。创建一个尽可能多的工人gpu并行池。

  • 如果没有可用的gpu,然后火车cpu。创建一个平行池与默认的工人数量。

如果canUseGPU executionEnvironment =“图形”;numberOfGPUs = gpuDeviceCount (“可用”);池= parpool (numberOfGPUs);其他的executionEnvironment =“cpu”;池= parpool;结束
开始平行池(parpool)使用“本地”概要文件…连接到平行池(工人数量:4)。

得到工人的数量在并行池。后来在这个例子中,根据这个数字除以工作负载。

N = pool.NumWorkers;

火车模型

指定培训选项。

numEpochs = 20;miniBatchSize = 128;速度= [];

GPU训练,推荐的做法是加大mini-batch大小线性与GPU的数量,为了保持每个GPU的工作负载恒定。更多的相关建议,看看深度学习与MATLAB在多个gpu

如果executionEnvironment = =“图形”miniBatchSize = miniBatchSize。* N结束
miniBatchSize = 512

计算每个工人的mini-batch大小除以总体mini-batch大小均匀的工人。在第一个工人分配剩余。

workerMiniBatchSize =地板(miniBatchSize。/ repmat (1, N));剩余= miniBatchSize - sum (workerMiniBatchSize);workerMiniBatchSize = workerMiniBatchSize +[1(剩余)0 (N-remainder)]
workerMiniBatchSize =1×4128 128 128 128

这个网络包含批量标准化层跟踪数据的均值和方差的网络培训。因为每个工作进程的一部分每个mini-batch在每个迭代中,均值和方差必须聚合所有工人。的指数的均值和方差状态参数批量标准化层网络国家财产。

batchNormLayers = arrayfun (@ (l) isa (l,“nnet.cnn.layer.BatchNormalizationLayer”),dlnet.Layers);batchNormLayersNames =字符串({dlnet.Layers (batchNormLayers) . name});状态= dlnet.State;isBatchNormalizationStateMean = ismember (state.Layer batchNormLayersNames) &状态。参数= =“TrainedMean”;isBatchNormalizationStateVariance = ismember (state.Layer batchNormLayersNames) &状态。参数= =“TrainedVariance”;

初始化培训进展阴谋。

图lineLossTrain = animatedline (“颜色”[0.85 0.325 0.098]);ylim([0正])包含(“迭代”)ylabel (“损失”网格)

发送数据从工人们在训练,创建一个DataQueue对象。使用afterEach建立一个函数,displayTrainingProgress,每次打电话给一个工人发送数据。displayTrainingProgress是一个支持金宝app函数,定义在这个例子中,显示来自于工人的培训进展信息。

Q = parallel.pool.DataQueue;displayFcn = @ (x) displayTrainingProgress (x, lineLossTrain);afterEach (Q, displayFcn);

火车模型使用一个定制的并行循环培训,以下步骤详细。同时在所有的工人执行代码,使用一个spmd块。在spmd块,labindex给出了指数的工人正在执行的代码。

在培训之前,分区数据存储为每个工人使用分区函数。使用分区的数据存储创建一个minibatchqueue在每一个工人。为每个mini-batch:

  • 使用自定义mini-batch预处理功能preprocessMiniBatch(在这个例子中定义)规范化数据,将标签转换为一个炎热的变量进行编码,并确定mini-batch观测的数量。

  • 格式的图像数据维度标签“SSCB”(空间、空间、通道、批)。默认情况下,minibatchqueue把数据转换为对象dlarray对象与基本类型。不格式添加到类的标签或观察的数量。

  • 火车在GPU如果一个是可用的。默认情况下,minibatchqueue将每个输出转换为对象gpuArray如果一个GPU是可用的。使用GPU需要并行计算工具箱™和支持GPU设备。金宝app支持设备的信息,请参阅金宝appGPU的金宝app支持版本(并行计算工具箱)(并行计算工具箱)。

对于每一个时代,重置和洗牌的数据存储重置洗牌功能。每次迭代的时代:

  • 确保所有工人并行数据之前对其进行处理,通过执行全球操作(共和党)的结果hasdata函数。

  • 读的mini-batchminibatchqueue通过使用下一个函数。

  • 计算梯度和网络的损失在每个工人通过调用dlfevalmodelGradients函数。的dlfeval函数评估helper函数modelGradients启用了自动分化modelGradients可以计算梯度的损失以自动方式。modelGradients定义的例子并返回损失和梯度给定一个网络,mini-batch的数据,和真正的标签。

  • 获得整体的损失,总损失的所有工人。这个示例使用交叉熵的损失函数,并累积损失损失的总和。聚合之前,规范每一个损失的比例乘以总体mini-batch工人工作。使用gplus把所有损失加起来,复制结果在工人。

  • 聚合和更新所有工人的渐变,使用dlupdate函数与aggregateGradients函数。aggregateGradients是一个支持金宝app函数定义在这个例子。这个函数使用gplus加在一起,复制梯度在工人,归一化后的比例总体mini-batch每个工人在工作。

  • 聚合网络状态的所有工人使用aggregateState函数。aggregateState是一个支持金宝app函数定义在这个例子。批处理标准化层网络跟踪数据的均值和方差。自完成mini-batch跨多个工人,在每次迭代中进行聚合网络状态,计算出整个minibatch的均值和方差。

  • 计算后最终的渐变,更新的网络可学的参数sgdmupdate函数。

  • 将培训进展信息发送回客户端使用发送函数与DataQueue。只使用一个工人发送数据,因为所有工人都有相同的信息损失。确保数据在CPU上,所以没有GPU的客户机可以访问它,使用收集dlarray在发送之前。

开始=抽搐;spmd%重置和洗牌数据存储。重置(augimdsTrain);augimdsTrain = shuffle (augimdsTrain);%分区数据存储。workerImds =分区(augimdsTrain N labindex);%使用分区创建minibatchqueue数据存储在每个工人workerMbq = minibatchqueue (workerImds 3“MiniBatchSize”workerMiniBatchSize (labindex),“MiniBatchFcn”@preprocessMiniBatch,“MiniBatchFormat”,{“SSCB”,,});workerVelocity =速度;迭代= 0;时代= 1:numEpochs shuffle (workerMbq);%在mini-batches循环。共和党(@and hasdata (workerMbq))迭代=迭代+ 1;%读mini-batch的数据。[dlworkerX, workerY workerNumObservations] =下一个(workerMbq);%评估模型梯度和损失的工人。[workerGradients, dlworkerLoss workerState] = dlfeval (@modelGradients、dlnet dlworkerX, workerY);%的总损失在所有工人。workerNormalizationFactor = workerMiniBatchSize (labindex)。/ miniBatchSize;损失= gplus (workerNormalizationFactor * extractdata (dlworkerLoss));%聚合网络状态的所有工人dlnet。状态= aggregateState (workerState workerNormalizationFactor,isBatchNormalizationStateMean isBatchNormalizationStateVariance);%总梯度对所有工人。workerGradients。值= dlupdate (@aggregateGradients workerGradients.Value, {workerNormalizationFactor});%更新使用个优化网络参数。[dlnet。可学的,workerVelocity] = sgdmupdate (dlnet.Learnables、workerGradients workerVelocity);结束%显示培训进展信息。如果labindex = = 1数据=[时代损失迭代toc (start)];发送(Q,收集(数据));结束结束结束

测试模型

在列车网络之后,您可以测试其准确性。

负载测试图像到内存使用readall测试数据存储,连接,和规范化。

XTest = readall (imdsTest);XTest =猫(4 XTest {:});XTest =单(XTest)。/ 255;欧美= imdsTest.Labels;

培训完成后,所有工人都有相同的完整训练网络。检索其中的任何一个。

dlnetFinal = dlnet {1};

使用分类图像dlnetwork对象,使用预测函数在一个dlarray

dlYPredScores =预测(dlnetFinal dlarray (XTest“SSCB”));

从预测分数,找到类与得分最高的马克斯函数。在你这样做之前,提取的数据dlarrayextractdata函数。

[~,idx] = max (extractdata (dlYPredScores), [], 1);YPred =类(idx);

获得模型的分类精度,比较测试集上的预测和真正的标签。

精度=意味着(YPred = =次)
精度= 0.8960

小批预处理功能

preprocessMiniBatch函数进行预处理的mini-batch预测和标签使用以下步骤:

  1. 确定mini-batch观测的数量

  2. 使用预处理的图像preprocessMiniBatchPredictors函数。

  3. 从传入单元阵列提取标签数据和连接到一个直言沿着二维数组。

  4. 一个炎热的分类标签编码成数字数组。编码的第一个维度产生一个相匹配的形状编码阵列网络输出。

函数[X, Y, numObs] = preprocessMiniBatch(伊势亚,YCell) numObs =元素个数(YCell);%预处理预测。X = preprocessMiniBatchPredictors(伊势亚);%从细胞中提取标签数据和连接。Y =猫(2,YCell{1:结束});%一个炎热的编码标签。Y, Y = onehotencode (1);结束

Mini-Batch预测预处理功能

preprocessMiniBatchPredictors函数进行预处理mini-batch预测因子的提取图像数据从输入单元阵列和连接到一个数字数组。灰度输入,连接在第四维度添加每个图像的三维空间,作为一个单通道维度。然后规范化的数据。

函数X = preprocessMiniBatchPredictors(伊势亚)%连接。猫(X = 4,伊势亚{1:结束});%正常化。X = X / 255;结束

模型梯度函数

定义一个函数,modelGradients,计算梯度的损失对网络的可学的参数。这个函数计算mini-batch网络输出X向前softmax和计算损失,因为真正的输出,利用交叉熵。当你调用这个函数dlfeval启用自动分化,dlgradient可以计算梯度的自动丧失对可学的。

函数[dlgradients、dlloss] = modelGradients (dlnet dlX,海底)[dlYPred、州]=前进(dlnet dlX);dlYPred = softmax (dlYPred);dlloss = crossentropy (dlYPred、海底);dlgradients = dlgradient (dlloss dlnet.Learnables);结束

显示功能培训进展

定义一个函数来显示来自工人培训进展信息。的DataQueue在这个例子中调用这个函数每次工人发送数据。

函数displayTrainingProgress(数据行)addpoints(线、双(数据(3))、双(数据(2)))D =时间(0,0,(4)数据,“格式”,“hh: mm: ss”);标题(”时代:“(1)+ +数据”,过去:“+ drawnow字符串(D))结束

总梯度函数

定义一个函数,聚合物梯度对所有工人通过添加在一起。gplus加在一起,复制上的所有渐变的工人。添加在一起之前,正常通过乘以一个因素代表的比例总体mini-batch工人工作。检索的内容dlarray,useextractdata

函数梯度= aggregateGradients (dlgradients因素)梯度= extractdata (dlgradients);梯度= gplus(因子*渐变)公关;结束

聚合态函数

定义一个函数,它聚合了所有工人的网络状态。网络状态包含训练一批标准化数据的数据集。因为每个工人只看到一部分mini-batch,聚合网络状态,以便统计是统计所有数据的代表。对于每个mini-batch,合并后的平均计算的加权平均平均在每个迭代的工人。合并后的方差是按照下列公式计算:

年代 c 2 = 1 j = 1 N j ( 年代 j 2 + ( x j - - - - - - x c ) 2 ]

在哪里 N 工人总数, 是在mini-batch观测的总数, j 观察上处理的数量吗 j th工人, x j 年代 j 2 均值和方差的统计计算,工人,然后呢 x c 合并意味着所有工人。

函数状态= aggregateState(状态、因素isBatchNormalizationStateMean isBatchNormalizationStateVariance) stateMeans = state.Value (isBatchNormalizationStateMean);stateVariances = state.Value (isBatchNormalizationStateVariance);j = 1:元素个数(stateMeans) meanVal = stateMeans {};varVal = stateVariances {};%计算结合的意思combinedMean = gplus(因子* meanVal)公关;%计算结合方差和条款varTerm =因素。* (varVal + (meanVal combinedMean) ^ 2);%更新状态stateMeans {j} = combinedMean;stateVariances {j} = gplus (varTerm)公关;结束state.Value (isBatchNormalizationStateMean) = stateMeans;state.Value (isBatchNormalizationStateVariance) = stateVariances;结束

另请参阅

|||||||||

相关的话题