你可以加快您的自定义训练循环运行在GPU,使用多个GPU并行,或集群。
建议使用GPU火车或多个GPU。如果你只使用单个CPU或多个CPU没有GPU。cpu通常要慢得多,gpu进行训练和推理。通常运行在一个单独的GPU提供了更好的性能比运行在多个CPU核心。
请注意
这个话题向您展示了如何执行定制培训gpu,并行,在云上。学习并行和GPU工作流使用trainNetwork
功能,请参见:
使用GPU或平行的选项需要并行计算工具箱™。使用GPU还需要支持GPU设备。金宝app支持设备的信息,请参阅金宝appGPU的金宝app支持版本(并行计算工具箱)。还需要使用远程集群MATLAB®并行服务器™。
默认情况下,自定义训练循环在CPU上运行。自动区分使用dlgradient
和dlfeval
金宝app运行在GPU上的支持当你的数据在GPU。运行自定义训练循环GPU,简单地将数据转换成gpuArray
(并行计算工具箱)在培训。
您可以使用minibatchqueue
在训练管理你的数据。minibatchqueue
自动为培训准备数据,包括定制的预处理和转换数据dlarray
和gpuArray
。默认情况下,minibatchqueue
返回所有mini-batch变量在GPU上如果有一个可用。你可以选择哪些变量返回GPU上使用OutputEnvironment
财产。
一个例子,演示如何使用minibatchqueue
火车在GPU上看到列车网络的使用自定义训练循环。
或者,你可以手动转换数据gpuArray
培训内循环。
容易地指定执行环境,创建变量executionEnvironment
包含两“cpu”
,“图形”
,或“汽车”
。
executionEnvironment =“汽车”
培训期间,阅读mini-batch后,检查执行环境的选择和转换数据gpuArray
如果有必要的话)。的canUseGPU
函数检查可用的gpu。
如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”dlX = gpuArray (dlX);结束
当你并行训练,每个工人列车网络同时使用mini-batch的一部分。这意味着您必须将渐变,损失,和任何状态参数在每次迭代之后,根据mini-batch加工的每个工人的比例。
你可以训练你的本地机器上并行,或远程集群上,例如,在云。开始一个平行池所需的资源和工人之间的数据分区。培训期间,结合梯度、损失和国家每一次迭代后,可学的参数对每个工人在同步更新。为一个例子,演示如何执行并行的定制培训,明白了列车网络与自定义训练循环
建议使用GPU火车或多个GPU。如果你只使用单个CPU或多个CPU没有GPU。cpu通常要慢得多,gpu进行训练和推理。通常运行在一个单独的GPU提供了更好的性能比运行在多个CPU核心。
设置并行环境之前,您想要使用的培训。开始一个平行使用所需的资源池。培训使用多个gpu,开始尽可能多的工人提供gpu并行池。为获得最佳性能,MATLAB自动分配一个不同的GPU每个工人。
如果您使用的是你的本地机器上,您可以使用canUseGPU
和gpuDeviceCount
(并行计算工具箱)确定如果你有可用的gpu。例如,检查可用性的gpu,开始一个平行的池和尽可能多的工人可用的gpu,使用以下代码:
如果canUseGPU executionEnvironment =“图形”;numberOfGPUs = gpuDeviceCount (“可用”);池= parpool (numberOfGPUs);其他的executionEnvironment =“cpu”;池= parpool;结束
如果您正在运行使用远程集群,例如,一个集群在云中,开始一个平行的池和尽可能多的工人每台机器的gpu的数量乘以数量的机器。
在选择特定的gpu的更多信息,见选择特定的gpu用于培训。
指定您想要使用的mini-batch大小在训练。GPU训练,推荐的做法是加大mini-batch大小线性与GPU的数量,为了保持每个GPU的工作负载恒定。例如,如果您正在训练一个GPU使用mini-batch大小为64,和你想扩大培训四个相同类型的GPU,可以mini-batch大小增加到256个,这样每个GPU处理64观察每迭代。
您可以使用下面的代码来扩大mini-batch大小工人的数量,N
是工人的数量在你的平行池。
如果executionEnvironment = =“图形”miniBatchSize = miniBatchSize。* N结束
如果你想使用一个mini-batch大小不是整除的工人数量在你平行池,然后分发其余工人。
workerMiniBatchSize =地板(miniBatchSize。/ repmat (1, N));剩余= miniBatchSize - sum (workerMiniBatchSize);workerMiniBatchSize = workerMiniBatchSize +[1(剩余)0 (N-remainder)]
开始时的训练,转移你的数据。分区数据,每个工人都有访问mini-batch的一部分。分区数据存储,使用分区
函数。
您可以使用minibatchqueue
管理数据在每个工人培训。minibatchqueue
自动为培训准备数据,包括定制的预处理和转换数据dlarray
和gpuArray
。每个工人使用分区上创建一个minibatchqueue数据存储。设置MiniBatchSize
财产使用mini-batch大小计算出每个工人。
每个训练迭代开始时,使用共和党
(并行计算工具箱)函数来检查所有工人minibatchqueue
对象可以返回数据。如果任何工人用完的数据,停止训练。如果你的整体mini-batch大小并不完全数的整除工人和你不抛弃部分mini-batches,一些工人可能在其他人之前的数据。
写你的代码在一个培训spmd
(并行计算工具箱)块,每个工人的训练循环执行。
spmd%重置和洗牌数据存储。重置(augimdsTrain);augimdsTrain = shuffle (augimdsTrain);%分区数据存储。workerImds =分区(augimdsTrain N labindex);%使用分区创建minibatchqueue数据存储在每个工人workerMbq = minibatchqueue (workerImds,…“MiniBatchSize”workerMiniBatchSize (labindex),…“MiniBatchFcn”,@preprocessMiniBatch);…为时代= 1:numEpochs%重置和洗牌minibatchqueue每个工人。洗牌(workerMbq);%在mini-batches循环。而共和党(@and hasdata (workerMbq))%的定制培训循环…结束…结束结束
确保网络每个工人可以从所有的数据,而不仅仅是工人的数据,总梯度和使用聚合的梯度来更新网络上每个工人。
例如,假设您正在训练网络dlnet
使用模型梯度函数modelGradients
。你的训练循环包含以下代码来评估梯度,损失,对每个工人和统计:
[workerGradients, dlworkerLoss workerState] = dlfeval (@modelGradients、dlnet dlworkerX, workerY);
dlworkerX
和workerY
每个工人的预测和真正的反应,分别。
总梯度,用加权和。定义一个helper函数和梯度。
函数梯度= aggregateGradients (dlgradients因素)梯度= extractdata (dlgradients);梯度= gplus(因子*渐变)公关;结束
在训练循环,使用dlupdate
应用函数的梯度可学的参数。
workerGradients。值= dlupdate (@aggregateGradients workerGradients.Value, {workerNormalizationFactor});
找到网络损耗和准确性,例如,在培训监控进展,把它们总损失的值在所有的工人和准确性。通常,聚合值的总和值在每个工人,加权的比例mini-batch用于每个工人。总损失和每次迭代精度,计算每个工人的加权因子和使用gplus
(并行计算工具箱)对每个工人求和的值。
workerNormalizationFactor = workerMiniBatchSize (labindex)。/ miniBatchSize;损失= gplus (workerNormalizationFactor * extractdata (dlworkerLoss));精度= gplus (workerNormalizationFactor * extractdata (dlworkerAccuracy));
如果您的网络包含层追踪你的训练数据的统计,如批量标准化层,那么你必须总统计每个训练迭代后所有工人。这样做确保了网络学习统计数据代表的整个训练集。
您可以识别层包含统计信息之前培训。例如,如果您使用的是dlnetwork
与批量标准化层,您可以使用下面的代码来找到相关的层。
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”;
N工人总数,米是在mini-batch观测的总数,米j观察上处理的数量吗jth工人, 和 均值和方差的统计计算,工人,然后呢 是聚合所有工人。
函数状态= 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;结束
在训练循环,使用辅助函数来更新批的状态组合的均值和方差归一化层。
dlnet。状态= aggregateState (workerState workerNormalizationFactor,…isBatchNormalizationStateMean isBatchNormalizationStateVariance);
如果你想把结果在训练,你可以从员工到客户端发送数据使用DataQueue
对象。
很容易地指定情节应该打开或关闭,创建变量情节
包含两“训练进步”
或“没有”
。
情节=“训练进步”;
在培训之前,初始化DataQueue
和动画线使用animatedline
函数。
如果情节= =“训练进步”图lineLossTrain = animatedline (“颜色”[0.85 0.325 0.098]);ylim([0正])包含(“迭代”)ylabel (“损失”网格)在结束
DataQueue
对象。使用afterEach
helper函数displayTrainingProgress
每次从工人到客户端发送的数据。Q = parallel.pool.DataQueue;displayFcn = @ (x) displayTrainingProgress (x, lineLossTrain);afterEach (Q, displayFcn);
displayTrainingProgress
helper函数包含用于添加的代码点动画线和显示培训时代和持续时间。函数displayTrainingProgress(数据行)addpoints(线、双(数据(3))、双(数据(2)))D =时间(0,0,(4)数据,“格式”,“hh: mm: ss”);标题(”时代:“(1)+ +数据”,过去:“+ drawnow字符串(D))结束
内部培训循环,每个时代的结束时,使用DataQueue
将工人的训练数据发送到客户机。在每个迭代中,每个工人的累积损失是相同的,所以你可以发送数据从一个工人。
%显示培训进展信息。如果labindex = = 1数据=[时代损失迭代toc (start)];发送(Q,收集(数据));结束
并行训练多个网络,开始一个平行池所需的资源和使用parfor
(并行计算工具箱)训练一个网络在每个工人。
你可以在本地运行或使用远程集群。使用远程集群需要MATLAB并行服务器。关于集群资源管理的更多信息,请参阅发现集群和集群配置文件使用(并行计算工具箱)。如果您有多个gpu和想排除一些培训,您可以选择您所使用的gpu来训练。在选择特定的gpu的更多信息,见选择特定的gpu用于培训。
您可以修改网络或训练参数对每个工人并行执行参数扫描。例如,在网络
是一个数组的dlnetwork
对象,您可以使用下面的代码形式训练多个不同的网络使用相同的数据。
parpool (“本地”,numNetworks);parforidx = 1: numNetworks迭代= 0;速度= [];%的人均分配一个网络dlnet =网络(idx)%循环时期。为时代= 1:numEpochs%洗牌数据。洗牌(兆贝可);%在mini-batches循环。而hasdata(兆贝可)迭代=迭代+ 1;%的定制培训循环…结束结束%将训练网络发送回客户端。trainedNetworks {idx} = dlnet;结束
parfor
完成后,trainedNetworks
包含生成的网络训练的工人。
监控培训的进展工作人员,您可以使用一个DataQueue
发送数据的工人。
很容易地指定情节应该打开或关闭,创建变量情节
包含两“训练进步”
或“没有”
。
情节=“训练进步”;
在培训之前,初始化DataQueue
和动画线使用animatedline
函数。为每个网络创建一个次要情节你训练。
如果情节= =“训练进步”f =图;f。可见= true;为i = 1: numNetworks次要情节(numNetworks 1我)包含(“迭代”);ylabel (“损失”);行(i) = animatedline;结束结束
DataQueue
对象。使用afterEach
helper函数displayTrainingProgress
每次从工人到客户端发送的数据。Q = parallel.pool.DataQueue;displayFcn = @ (x) displayTrainingProgress (x线);afterEach (Q, displayFcn);
displayTrainingProgress
helper函数包含用于添加的代码点的动画线条。函数displayTrainingProgress(数据行)addpoints(行(1)双(数据(4)),双(数据(3)))D =时间(0,0,(5)的数据,“格式”,“hh: mm: ss”);标题(”时代:“+(2)+数据”,过去:“+ drawnow字符串(D))limitratenocallbacks结束
在训练循环,在每次迭代结束时,使用DataQueue
将工人的训练数据发送到客户机。发送parfor
循环索引以及培训信息,点添加到每个工人正确的线。
%显示培训进展信息。data = [idx时代损失迭代toc(开始)];发送(Q,收集(数据));
您可以使用实验经理定制培训循环并行运行。你可以同时运行多个路径,或运行一个审判一次使用并行资源。
同时运行多个试验使用一个为每个审判并行工作,设置自定义训练实验支持使用并行选择之前运行实验。
每次运行单个试验使用多个平行的工人,定义你的并行环境实验培训功能和使用spmd
并行块来训练网络。更多信息在培训一个网络与一个定制的循环,明白了火车单一网络并行。
有关培训的更多信息并行使用实验管理器,看看使用实验管理器并行训练。
parfor
(并行计算工具箱)|parfeval
(并行计算工具箱)|gpuArray
(并行计算工具箱)|dlarray
|dlnetwork