Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

将深度学习批处理作业发送到集群

此示例说明如何将深度学习训练批处理作业发送到集群,以便您可以在训练过程中继续工作或者关闭 MATLAB®。

训练深度神经网络通常需要几个小时或几天的时间。为了高效利用时间,您可以以批处理作业的形式训练神经网络,并在得出结果后从集群中获取结果。您可以在进行计算时继续在 MATLAB 中工作,或者关闭 MATLAB,稍后使用 Job Monitor 获得结果。您可以选择在训练过程中监控作业,并且在作业完成后,您可以获取经过训练的网络并比较其准确度。

要求

您需要配置集群并将数据上传到云,才能运行此示例。在 MATLAB 中,您可以直接通过 MATLAB 桌面在云中创建集群。在主页选项卡上,在 Parallel 菜单中,选择 Create and Manage Clusters。在 Cluster Profile Manager 中,点击 Create Cloud Cluster。您也可以使用 MathWorks Cloud Center 来创建和访问计算集群。有关详细信息,请参阅 Cloud Center 快速入门。对于此示例,请确保在 MATLAB 主页选项卡的 Parallel > Select Parallel Environment 中,将您所需的云集群设置为默认并行环境。然后,将您的数据上传到 Amazon S3 存储桶并直接从 MATLAB 中使用它。此示例使用已存储在 Amazon S3 中的 CIFAR-10 数据集的副本。有关说明,请参阅在 AWS 中使用深度学习数据

提交批处理作业

您可以使用 batch (Parallel Computing Toolbox) 函数将函数或脚本作为批处理作业发送到集群。默认情况下,集群会分配一个工作进程来执行作业的内容。如果增加工作进程能使作业中的代码受益,例如,代码包括自动并行支持或 parfor 循环,您可以通过使用 batch 函数的 Pool 名称-值参数来指定更多工作进程。

默认情况下,当您将批处理作业作为脚本提交时,工作区变量会从客户端复制到工作进程。为了避免将工作区变量复制到工作进程,请将批处理作业作为函数提交。

在此示例中,trainNetworkFcn 作为支持文件提供。该函数使用给定的小批量大小训练单个网络,并返回经过训练的网络及其准确度。要对各个小批量大小执行参数扫描,请将该函数作为批处理作业发送到集群四次,并为每个作业指定不同的小批量大小。将函数作为批处理作业发送时,指定函数的输出数目和输入参数。

c = parcluster;
miniBatchSize = [64 128 256 512];
numBatchJobs = numel(miniBatchSize);

for idx=1:numBatchJobs
    job(idx) = batch(c,"trainNetworkFcn",2,{idx,miniBatchSize(idx)});
end

在不同批处理作业中训练每个网络而不是在同一批处理作业中并行训练所有网络,这样可以避免在集群中启动并行池所需的开销,且方便使用作业监控程序单独观察每个网络计算的进度。

您可以向集群提交更多作业。如果集群因运行其他作业而不可用,则您提交的任何新作业会处于排队状态,直到集群变为可用。

监控训练进度

您可以通过检查 Job Monitor 来查看集群中作业的当前状态。在主页选项卡的环境部分中,选择 Parallel > Monitor Jobs 以打开 Job Monitor。

runningJobs.png

您可以选择通过将运行批处理作业的工作进程中的数据发送到 MATLAB 客户端来详细监控训练的进度。在 trainNetworkFcn 中,在每次迭代后调用输出函数 sendTrainingProgress 以将当前迭代和训练准确度添加到 ValueStore (Parallel Computing Toolbox) 中。一个 ValueStore 存储一个特定作业拥有的数据,每个数据条目由值和对应的键组成。

function sendTrainingProgress(info)

    if info.State == "iteration"
        % Get the ValueStore object of the current job.
        store = getCurrentValueStore;
    
        % Store the training results in the job ValueStore object with a unique
        % key.
        key = idx;
        store(key) = struct(iteration=info.Iteration,accuracy=info.TrainingAccuracy);
    end

end

创建用于显示网络的训练准确度的图窗,并为提交的每个作业:

  • 创建一个子图来显示正在训练的网络的准确度。

  • 获取作业的 ValueStore 对象。

  • 指定每次作业向 ValueStore 添加条目时要执行的回调函数。回调函数 updatePlot 在此示例的末尾提供,并绘制网络的当前训练准确度。

figure
for i=1:numBatchJobs
    subplot(2,2,i)
    xlabel("Iteration");
    ylabel("Accuracy (%)");
    ylim([0 100])
    lines(i) = animatedline;

    store{i} = job(i).ValueStore;
    store{i}.KeyUpdatedFcn = @(store,key) updatePlot(lines(i),store(key).iteration,store(key).accuracy);
end

通过编程方式获取结果

将作业提交到集群后,您可以在进行计算时继续在 MATLAB 中工作。如果代码的其余部分依赖于作业的完成,请使用 wait 命令阻止 MATLAB。在本例中,我们等待作业完成。

wait(job(1))

作业完成后,使用 fetchOutputs 函数获取结果。在本例中,获取经过训练的网络及其准确度。

for idx=1:numBatchJobs
    results{idx}=fetchOutputs(job(idx));
end
results{:}
ans=1×2 cell array
    {1×1 SeriesNetwork}    {[0.6644]}

ans=1×2 cell array
    {1×1 SeriesNetwork}    {[0.6824]}

ans=1×2 cell array
    {1×1 SeriesNetwork}    {[0.6482]}

ans=1×2 cell array
    {1×1 SeriesNetwork}    {[0.6398]}

如果关闭 MATLAB,您仍可以在计算进行过程中或计算完成后恢复集群中的作业以获取结果。在关闭 MATLAB 之前,请记下作业 ID,稍后使用 findJob 函数检索该作业。

要检索作业,首先使用 parcluster 函数为集群创建一个集群对象。然后,向 findJob 提供作业 ID。在本例中,作业 ID 是 3。

c = parcluster("MyClusterInTheCloud");
job = findJob(c,ID=3);

删除不再需要的作业。该作业将从 Job Monitor 中删除。

delete(job(1));

要删除提交到特定集群的所有作业,请将与该集群关联的所有作业传递给 delete 函数。

delete(c.Jobs);

使用 Job Monitor 获取结果

在提交批处理作业后,所有计算都在集群中进行,您可以安全地关闭 MATLAB。您可以在另一个 MATLAB 会话中使用 Job Monitor 来检查作业的状态。

在一个作业完成后,您可以从 Job Monitor 中检索结果。在主页选项卡的环境部分中,选择 Parallel > Monitor Jobs 以打开 Job Monitor。然后右键点击一个作业以显示上下文菜单。从该菜单中,您可以:

  • 点击 Show Details 将作业加载到工作区中

  • 通过点击 Fetch Outputs 获取经过训练的网络及其准确度

  • 在完成后,点击 Delete 删除作业

jobContextMenu.png

支持函数

updatePlot 函数向其中一个子图添加点,指示网络的当前训练准确度。该函数接收一个动画线条对象以及网络的当前迭代和准确度。

function updatePlot(line,iteration,accuracy)

addpoints(line,iteration,accuracy);
drawnow limitrate nocallbacks

end

另请参阅

(Parallel Computing Toolbox) | (Parallel Computing Toolbox)

相关示例

详细信息