主要内容

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

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

加载数据集

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

digitDatasetPath = fullfile (toolboxdir (“nnet”),“nndemos”,“nndatasets”,“DigitDataset”);imd = imageDatastore (digitDatasetPath,IncludeSubfolders = true,LabelSource =“foldernames”);[imdsTrain, imdsTest] = splitEachLabel (imd, 0.9,“随机”);inputSize = [28 28 1];augimdsTrain = augmentedImageDatastore (inputSize (1:2), imdsTrain);augimdsTrain = shuffle (augimdsTrain);

确定训练集的不同的类。

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

定义网络

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

层= [imageInputLayer (inputSize正常化=“没有”20)convolution2dLayer (5) batchNormalizationLayer reluLayer convolution2dLayer(3、20、填充= 1)batchNormalizationLayer reluLayer convolution2dLayer(3、20、填充= 1)batchNormalizationLayer reluLayer fullyConnectedLayer (numClasses) softmaxLayer];

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

净= dlnetwork(层)
网= dlnetwork属性:层:[12×1 nnet.cnn.layer.Layer]连接:[11×2表]可学的:[14×3表]状态:[6×3表]InputNames: {“imageinput”} OutputNames: {“softmax”}初始化:1观点总结总结。

设置并行环境

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

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

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

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

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

numWorkers = pool.NumWorkers;

火车模型

指定培训选项。

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

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

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

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

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

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

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

初始化TrainingProgressMonitor对象。因为计时器开始创建监视器对象时,确保你创建对象接近的训练循环。

监控= trainingProgressMonitor (指标=“TrainingLoss”,信息= [“时代”“工人”),包含=“迭代”);

创建一个Dataqueue对象的工人发送一个国旗时停止训练停止按钮点击。

spmdstopTrainingEventQueue = parallel.pool.DataQueue;结束stopTrainingQueue = stopTrainingEventQueue {1};

发送数据从工人们在训练,创建一个DataQueue对象。使用afterEach建立一个函数,displayTrainingProgress,每次打电话给一个工人发送数据。displayTrainingProgress是一个支持万博1manbetx函数,定义在这个例子中,显示更新吗TrainingProgressMonitor对象显示培训进展信息来自于工人和向工人们如果发送一个标志停止按钮被点击。

dataQueue = parallel.pool.DataQueue;displayFcn = @ (x) displayTrainingProgress (x, numEpochs numWorkers、监控stopTrainingQueue);afterEach (dataQueue displayFcn)

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

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

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

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

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

对于每一个时代,洗牌的数据存储洗牌函数。每次迭代的时代:

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

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

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

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

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

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

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

在每个时代后,检查是否停止按钮被点击,发送回客户机使用培训进展信息发送函数与Dataqueue对象。你只需要使用一个工人发送回数据,因为所有的工人都有相同的信息损失。确保数据在CPU和没有GPU的客户机可以访问它,使用收集dlarray之前发送给客户端。当工人们之间的沟通发生在每一个时代,点击停止停止训练结束时,当前的时代。如果你想要的停止按钮来停止训练在每次迭代结束时,您可以检查是否停止按钮被点击,将培训进展信息发送回客户端每次迭代的成本增加通讯开销。

spmd%分区数据存储。workerImds =分区(augimdsTrain numWorkers spmdIndex);%使用分区创建minibatchqueue数据存储在每个工人。workerMbq = minibatchqueue (workerImds 3MiniBatchSize = workerMiniBatchSize (spmdIndex),MiniBatchFcn = @preprocessMiniBatch,MiniBatchFormat = [“SSCB””“”“]);workerVelocity =速度;时代= 0;迭代= 0;stopRequest = false;时代< numEpochs & & ~ stopRequest时代=时代+ 1;洗牌(workerMbq);%在mini-batches循环。spmdReduce (@and hasdata (workerMbq)) & & ~ stopRequest迭代=迭代+ 1;%读mini-batch的数据。[workerX, workerT workerNumObservations] =下一个(workerMbq);%损失评估模型和梯度的工人。[workerLoss, workerGradients workerState] = dlfeval (@modelLoss,净,workerX workerT);%的总损失在所有工人。workerNormalizationFactor = workerMiniBatchSize (spmdIndex)。/ miniBatchSize;损失= spmdPlus (workerNormalizationFactor * extractdata (workerLoss));%聚合网络状态的所有工人。网。状态= aggregateState (workerState workerNormalizationFactor,isBatchNormalizationStateMean isBatchNormalizationStateVariance);%总梯度对所有工人。workerGradients。值= dlupdate (@aggregateGradients workerGradients.Value, {workerNormalizationFactor});%更新使用个优化网络参数。[净,workerVelocity] = sgdmupdate(网,workerGradients, workerVelocity);结束%如果停止按钮被点击停止训练。stopRequest = spmdPlus (stopTrainingEventQueue.QueueLength);%培训进展信息发送给客户端。如果spmdIndex = = 1数据=(迭代时代损失);发送(dataQueue,收集(数据));结束结束结束

测试模型

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

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

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

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

netFinal =净{1};

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

欧美=预测(netFinal dlarray (XTest“SSCB”));

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

[~,idx] = max (extractdata(欧美),[],1);欧美=类(idx);

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

精度=意味着(欧美= = tt)
精度= 0.9070

小批预处理功能

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;结束

损失函数模型

定义一个函数,modelLoss,计算梯度的损失对网络的可学的参数。这个函数计算mini-batch网络输出X向前和计算损失,考虑到目标T,使用交叉熵。当你调用这个函数dlfeval启用自动分化,dlgradient可以计算梯度的自动丧失对可学的。

函数(损失、渐变、状态)= modelLoss(净,X, T) [Y,状态]=前进(净,X);损失= crossentropy (Y, T);梯度= dlgradient(损失、net.Learnables);结束

显示功能培训进展

定义一个函数来显示培训进展信息是否来自于工人和检查停止按钮被点击。如果停止按钮被点击时,国旗被发送到员工表明,培训应该停止。的DataQueue在这个例子中调用这个函数每次工人发送数据。

函数displayTrainingProgress(数据、numEpochs numWorkers、监控stopTrainingQueue)时代=数据(1);损失=数据(2);迭代=数据(3);recordMetrics(监控、迭代TrainingLoss =损失);updateInfo(监视、时代=时代+“的”+ numEpochs,工人= numWorkers);班长。进步= 100 *时代/ numEpochs;如果班长。停止发送(年代topTrainingQueue,true);结束结束

总梯度函数

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

函数梯度= aggregateGradients(渐变因子)梯度= extractdata(梯度);梯度= spmdPlus(因子*渐变);结束

聚合态函数

定义一个函数,它聚合了所有工人的网络状态。网络状态包含训练一批标准化数据的数据集。因为每个工人只看到一部分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 {};%计算结合的意思。* meanVal combinedMean = spmdPlus(因素);%计算结合方差和条款。varTerm =因素。* (varVal + (meanVal combinedMean) ^ 2);%更新状态。stateMeans {j} = combinedMean;stateVariances {j} = spmdPlus (varTerm);结束state.Value (isBatchNormalizationStateMean) = stateMeans;state.Value (isBatchNormalizationStateVariance) = stateVariances;结束

另请参阅

|||||||||

相关的话题