这个例子展示了如何设置一个自定义训练循环并行训练网络。在这个例子中,平行的工人训练部分整体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
通过使用下一个
函数。
计算梯度和网络的损失在每个工人通过调用dlfeval
在modelGradients
函数。的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”));
从预测分数,找到类与得分最高的马克斯
函数。在你这样做之前,提取的数据dlarray
与extractdata
函数。
[~,idx] = max (extractdata (dlYPredScores), [], 1);YPred =类(idx);
获得模型的分类精度,比较测试集上的预测和真正的标签。
精度=意味着(YPred = =次)
精度= 0.8960
的preprocessMiniBatch
函数进行预处理的mini-batch预测和标签使用以下步骤:
确定mini-batch观测的数量
使用预处理的图像preprocessMiniBatchPredictors
函数。
从传入单元阵列提取标签数据和连接到一个直言沿着二维数组。
一个炎热的分类标签编码成数字数组。编码的第一个维度产生一个相匹配的形状编码阵列网络输出。
函数[X, Y, numObs] = preprocessMiniBatch(伊势亚,YCell) numObs =元素个数(YCell);%预处理预测。X = preprocessMiniBatchPredictors(伊势亚);%从细胞中提取标签数据和连接。Y =猫(2,YCell{1:结束});%一个炎热的编码标签。Y, Y = onehotencode (1);结束
的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
,u
seextractdata
。
函数梯度= aggregateGradients (dlgradients因素)梯度= extractdata (dlgradients);梯度= gplus(因子*渐变)公关;结束
定义一个函数,它聚合了所有工人的网络状态。网络状态包含训练一批标准化数据的数据集。因为每个工人只看到一部分mini-batch,聚合网络状态,以便统计是统计所有数据的代表。对于每个mini-batch,合并后的平均计算的加权平均平均在每个迭代的工人。合并后的方差是按照下列公式计算:
在哪里 工人总数, 是在mini-batch观测的总数, 观察上处理的数量吗 th工人, 和 均值和方差的统计计算,工人,然后呢 合并意味着所有工人。
函数状态= 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;结束
dlarray
|dlnetwork
|sgdmupdate
|dlupdate
|dlfeval
|dlgradient
|crossentropy
|softmax
|向前
|预测