主要内容

在GPU上运行自定义训练循环和并行

你可以加快您的自定义训练循环通过运行在GPU并行使用多个GPU,或集群。

建议使用GPU火车或多个GPU。如果你只使用单个CPU或多个CPU没有GPU。cpu通常要慢得多,gpu进行训练和推理。通常运行在一个单独的GPU提供了更好的性能比运行在多个CPU核心。

请注意

这一主题演示如何执行定制培训gpu,并行,在云上。学习并行使用简单和GPU工作流trainNetwork函数,看到这些主题:

使用GPU或平行的选项需要并行计算工具箱™。使用GPU还需要支持GPU设备。万博1manbetx支持设备的信息,请参阅万博1manbetxGPU计算的需求(并行计算工具箱)。还需要使用远程集群MATLAB®并行服务器™

列车网络GPU

默认情况下,自定义训练循环在CPU上运行。您可以执行自动分化使用dlgradientdlfeval在GPU数据在GPU。运行自定义训练循环在GPU上,把你的数据gpuArray(并行计算工具箱)在培训对象。

您可以使用minibatchqueue在训练管理你的数据。minibatchqueue自动为培训准备数据,包括定制的预处理和转换数据dlarraygpuArray对象。默认情况下,minibatchqueue返回所有mini-batch变量在GPU上如果有一个可用。你可以选择哪些变量返回GPU上使用OutputEnvironment财产。

为例,展示了如何使用minibatchqueue火车在GPU上看到列车网络的使用自定义训练循环

或者,您可以手动转换您的数据gpuArray对象内的训练循环。

容易地指定执行环境,创建变量executionEnvironment包含两“cpu”,“图形”,或“汽车”

executionEnvironment =“汽车”

培训期间,阅读mini-batch后,检查执行环境的选择和转换数据gpuArray如果有必要的话)。的canUseGPU函数检查可用的gpu。

如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”X = gpuArray (X);结束

火车单一网络并行

当你并行训练,每个工人列车网络同时使用mini-batch的一部分。这种行为意味着你必须结合梯度,每次迭代后损失和状态参数根据mini-batch加工的每个工人的比例。

你可以训练你的本地机器上并行或远程集群上,例如,在云。开始一个平行池使用所需的资源和工人之间的数据分区。培训期间,结合梯度、损失和国家每一次迭代后,可学的参数对每个工人在同步更新。为例,展示了如何执行并行的定制培训,明白了列车网络与自定义训练循环

设置并行环境

建议使用GPU火车或多个GPU。如果你只使用单个CPU或多个CPU没有GPU。cpu通常要慢得多,gpu进行训练和推理。通常运行在一个单独的GPU提供了更好的性能比运行在多个CPU核心。

培训之前设置并行环境。开始一个平行使用所需的资源池。训练使用多个gpu,开始尽可能多的工人提供gpu并行池。MATLAB分配一个不同的GPU每个工人。

如果您使用的是你的本地机器上,使用canUseGPUgpuDeviceCount(并行计算工具箱)是否你有可用的gpu。例如,检查你的gpu的可用性,并开始一个平行池可用gpu和尽可能多的工人。

如果canUseGPU executionEnvironment =“图形”;numberOfGPUs = gpuDeviceCount (“可用”);池= parpool (numberOfGPUs);其他的executionEnvironment =“cpu”;池= parpool;结束

如果您正在运行的代码使用远程集群,例如,一个集群在云中,开始一个平行的池和尽可能多的工人每台机器的gpu的数量乘以数量的机器。

在选择特定的gpu的更多信息,见选择特定的gpu用于培训

指定Mini-Batch大小和分区的数据

培训期间指定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培训对象自动准备数据,包括定制的预处理和转换数据dlarraygpuArray对象。创建一个minibatchqueue使用分区的数据存储对象每个工人。设置MiniBatchSize财产mini-batch大小计算出每个工人。

每个训练迭代开始时,使用spmdReduce(并行计算工具箱)函数来检查所有工人minibatchqueue对象可以返回数据。如果任何工人用完的数据,停止训练。如果整个mini-batch大小并不完全数的整除工人和你不丢弃部分mini-batches,一些工人可能在其他人之前的数据。

写你的代码在一个培训spmd(并行计算工具箱)块,这样每个工人的训练循环执行。

%洗牌数据存储。augimdsTrain = shuffle (augimdsTrain);spmd%分区数据存储。workerImds =分区(augimdsTrain N spmdIndex);%使用分区创建一个minibatchqueue对象数据存储在每个工人。workerMbq = minibatchqueue (workerImds,MiniBatchSize = workerMiniBatchSize (spmdIndex),MiniBatchFcn = @preprocessMiniBatch);时代= 1:numEpochs%重置和洗牌mini-batch队列在每个工人。洗牌(workerMbq);% mini-batches循环。spmdReduce (@and hasdata (workerMbq))%的定制培训循环结束结束结束

总梯度

确保网络每个工人可以从所有的数据,而不仅仅是工人的数据,总梯度和使用聚合的梯度来更新网络上每个工人。

例如,假设您正在训练网络使用模型损失函数modelLoss。你的训练循环包含的代码评估损失,渐变,统计每个工人workerXworkerT预测和目标响应每个工人,分别。

[workerLoss, workerGradients workerState] = dlfeval (@modelLoss,净,workerX workerT);

总梯度,用加权和。定义一个helper函数和梯度。

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

在训练循环,使用dlupdate应用函数的梯度可学的参数。

workerGradients。值= dlupdate (@aggregateGradients workerGradients.Value, {workerNormalizationFactor});

总损失和准确性

找到网络损耗和准确性,例如,在培训监控进展,把它们总损失的值在所有的工人和准确性。通常,聚合值的总和值在每个工人的比例加权mini-batch每个工人使用。总损失和每次迭代精度,计算每个工人的加权因子和使用spmdPlus(并行计算工具箱)对每个工人求和的值。

workerNormalizationFactor = workerMiniBatchSize (spmdIndex)。/ miniBatchSize;损失= spmdPlus (workerNormalizationFactor * extractdata (dlworkerLoss));精度= spmdPlus (workerNormalizationFactor * extractdata (dlworkerAccuracy));

总统计

如果您的网络包含层追踪你的训练数据的统计,如批量标准化层,那么你必须总统计每个训练迭代后所有工人。聚合的统计确保网络学习统计代表整个训练集。

您可以识别层包含统计数据前培训。例如,找到相关的层使用dlnetwork对象与批量标准化层。

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”;
定义一个helper函数总统计数据。批标准化层跟踪输入数据的均值和方差。你可以在所有的工人总平均使用加权平均。方差计算聚合 年代 c 2 ,用这个方程。

年代 c 2 = 1 j = 1 N j ( 年代 j 2 + ( x ¯ j x ¯ c ) 2 ) ,

在哪里N工人总数,是在mini-batch观测的总数,j观察上处理的数量吗jth工人, 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;结束

在训练循环,使用辅助函数来更新批的状态组合的均值和方差归一化层。

网。状态= aggregateState (workerState workerNormalizationFactor,isBatchNormalizationStateMean isBatchNormalizationStateVariance);

阴谋的结果在训练

绘制结果在训练,从工人发送数据到客户端使用DataQueue(并行计算工具箱)对象。

情节培训进展,集情节“训练进步”。否则,设置情节“没有”

情节=“训练进步”;

在培训之前执行这些步骤:

  • 初始化TrainingProgressMonitor对象跟踪和网络的损失。因为计时器开始创建监视器时,立即创建对象之前的训练循环。

  • 初始化一个DataQueue对象发送一个工人的国旗当你单击停止训练停止按钮。

  • 初始化一个DataQueue对象在客户端接收数据从工人们在训练。

  • 使用afterEach(并行计算工具箱)调用displayTrainingProgress函数每次一个工人将数据发送给客户端。

R2023a:情节训练进展之前,创建一个animatedline对象,而不是初始化TrainingProgressMonitor对象和使用addpoints函数内displayTrainingProgress函数来更新animatedline

如果情节= =“训练进步”%初始化培训进度监控。监控= trainingProgressMonitor (指标=“TrainingLoss”,信息= [“时代”,“工人”),包含=“迭代”);%初始化一个工人DataQueue对象。spmdstopTrainingEventQueue = parallel.pool.DataQueue;结束stopTrainingQueue = stopTrainingEventQueue {1};%初始化一个DataQueue对象在客户机上。dataQueue = parallel.pool.DataQueue;%叫displayTrainingProgress每次一个工人将数据发送给客户端。displayFcn = @ (x) displayTrainingProgress (x, numEpochs numWorkers、监控stopTrainingQueue);afterEach (dataQueue displayFcn)结束
displayTrainingProgresshelper函数是否更新培训进度窗口和检查停止按钮被点击。如果你点击停止按钮的DataQueue对象指示工人停止训练。
函数displayTrainingProgress(数据、numEpochs numWorkers、监控stopTrainingQueue)%提取时代、迭代和损失数据。时代=数据(1);迭代=数据(2);损失=数据(3);%更新培训进度监控。recordMetrics(监控、迭代TrainingLoss =损失);updateInfo(监视、时代=时代+“的”+ numEpochs,工人= numWorkers);班长。进步= 100 *时代/ numEpochs;%标记发送到工人如果停止按钮被点击。如果班长。停止年代结束(年代来pTrainingQueue,true);结束结束

在训练循环,在每个迭代或时代结束时,检查是否停止按钮被点击,使用DataQueue对象发送培训工人的数据给客户端。在每个迭代中,每个工人的累积损失是相同的,所以你可以发送数据从一个工人。

spmd时代= 0;迭代= 0;stopRequest = false;%准备输入数据和mini-batches。%循环时期。时代< numEpochs & & ~ stopRequest时代=时代+ 1;%重置和洗牌mini-batch队列在每个工人。%在mini-batches循环。spmdReduce (@and hasdata (workerMbq)) & & ~ stopRequest迭代=迭代+ 1;%的定制培训循环。如果情节= =“训练进步”%检查是否停止按钮被点击。stopRequest = spmdPlus (stopTrainingEventQueue.QueueLength);%培训进展信息发送给客户端。如果spmdIndex = = 1数据=(时代迭代损失);发送(dataQueue,收集(数据));结束结束结束结束结束

情节的训练失去网络训练四个平行的工人。

火车并行多个网络

并行训练多个网络,开始一个平行的池和使用parfor(并行计算工具箱)训练一个网络在每个工人。

您可以运行培训本地或远程集群。使用远程集群需要MATLAB并行服务器许可证。关于集群资源管理的更多信息,请参阅发现集群和集群配置文件使用(并行计算工具箱)。如果您有多个gpu和想排除一些训练,你可以选择火车上只有一些gpu。在选择特定的gpu的更多信息,见选择特定的gpu用于培训

您可以修改网络或训练参数对每个工人并行执行参数扫描。例如,如果网络是一个数组的dlnetwork对象,您可以使用这段代码训练多个不同的网络使用相同的数据。后parfor循环完成后,trainedNetworks包含生成的网络训练的工人。

parpool;parforidx = 1: numNetworks迭代= 0;速度= [];%的人均分配一个网络。网=网络(idx)%循环时期。时代= 1:numEpochs%洗牌数据。洗牌(兆贝可);%在mini-batches循环。hasdata(兆贝可)迭代=迭代+ 1;%的定制培训循环。结束结束%将训练网络发送回客户端。trainedNetworks {idx} =净;结束

使用实验管理器并行训练

您可以使用实验经理定制培训循环并行运行。您可以同时运行多个试验或运行单个试验一次使用并行资源。

同时运行多个试验使用一个为每个审判并行工作,设置自定义训练实验和设置模式同时之前运行实验。

一次运行单个试验使用多个平行的工人,定义你的并行环境实验训练函数,使用一个spmd并行块来训练网络,集模式顺序。更多信息在培训一个网络与一个定制的循环,明白了火车单一网络并行定制培训与实验中的多个gpu经理

显示培训策划和跟踪每个试验的进展在实验时,审查结果,点击培训策划

有关培训的更多信息并行使用实验管理器,看看并行使用实验管理器来训练网络

另请参阅

(并行计算工具箱)|(并行计算工具箱)||(并行计算工具箱)||

相关的话题