使用并行和 GPU 计算的浅层神经网络 |
您所在的位置:网站首页 › matlab神经网络训练代码 › 使用并行和 GPU 计算的浅层神经网络 |
使用并行和 GPU 计算的浅层神经网络 注意 对于深度学习,自动支持并行和 GPU 计算。您可以使用 trainnet 和 trainNetwork 函数来训练卷积神经网络(CNN、ConvNet)或长短期记忆网络(LSTM 或 BiLSTM 网络),并使用 trainingOptions 选择执行环境(CPU、GPU、多 GPU 和并行)。 并行训练或在 GPU 上的训练需要 Parallel Computing Toolbox™。有关使用 GPU 和以并行方式进行深度学习的详细信息,请参阅在并行运行的 CPU、GPU 上和云上使用大数据进行深度学习。 并行机制模式神经网络本质上是并行算法。多核 CPU、图形处理单元 (GPU) 以及具有多个 CPU 和 GPU 的计算机集群都可以利用这种并行机制。 Parallel Computing Toolbox 在与 Deep Learning Toolbox™ 结合使用时支持神经网络训练和仿真利用各种并行机制模式。 例如,以下是标准单线程训练和仿真会话: [x, t] = bodyfat_dataset; net1 = feedforwardnet(10); net2 = train(net1, x, t); y = net2(x);您可以在此会话中并行执行的两个步骤是:调用 train 和隐式调用 sim(其中网络 net2 作为函数被调用)。 在 Deep Learning Toolbox 中,您可以将任何数据(如前面示例代码中的 x 和 t)划分到各采样中。如果 x 和 t 各只包含一个样本,则不存在并行关系。但是,如果 x 和 t 包含成百上千或成千上万个样本,则并行机制既可以提高速度,又可以求解更大的问题。 分布式计算通过使用 MATLAB® Parallel Server™,Parallel Computing Toolbox 支持神经网络训练和仿真在单台 PC 上的多个 CPU 内核上运行,或在一个网络的多台计算机的多个 CPU 上运行。 使用多个内核可以加快计算速度。如果求解问题所使用的数据集太大而无法放入一台计算机的内存中,则可以使用多台计算机来求解问题。问题大小仅受限于所有计算机上可用的内存总量。 要管理集群配置,请通过 MATLAB 主页选项卡上的环境菜单中的并行 > Manage Cluster Profiles 使用 Cluster Profile Manager。 要使用默认集群配置文件(通常是本地 CPU 内核)打开 MATLAB 工作进程池,请使用以下命令: pool = parpoolStarting parallel pool (parpool) using the 'Processes' profile ... connected to 4 workers.当 parpool 运行时,它会显示池中可用的工作进程数量。确定工作进程数量的另一种方法是查询池: pool.NumWorkers 4现在您可以在所有工作进程中按样本拆分数据的情况下训练和仿真神经网络。为此,请将 train 和 sim 参数 'useParallel' 设置为 'yes'。 net2 = train(net1,x,t,'useParallel','yes') y = net2(x,'useParallel','yes')使用 'showResources' 参数来验证计算是否跨多个工作进程运行。 net2 = train(net1,x,t,'useParallel','yes','showResources','yes'); y = net2(x,'useParallel','yes','showResources','yes');MATLAB 指示使用了哪些资源。例如: Computing Resources: Parallel Workers Worker 1 on MyComputer, MEX on PCWIN64 Worker 2 on MyComputer, MEX on PCWIN64 Worker 3 on MyComputer, MEX on PCWIN64 Worker 4 on MyComputer, MEX on PCWIN64当调用 train 和 sim 时,它们会在训练和仿真之前将输入矩阵或元胞数组数据划分为分布式合成值。当 sim 计算出合成值时,会先将此输出转换回相同的矩阵或元胞数组形式,再将其返回。 但是,如果出现以下情况,您可能需要手动执行此数据划分: 问题大小对主机来说太大。通过按顺序手动定义合成值的元素,可定义更大的问题。 众所周知,有些工作进程所在的计算机比其他计算机速度更快或内存更多。在分配数据时,您可以使每个工作进程处理不同数量的样本。这称为负载平衡。 以下代码按顺序创建一系列随机数据集,并将它们保存到各个单独文件中: pool = gcp; for i=1:pool.NumWorkers x = rand(2,1000); save(['inputs' num2str(i)],'x'); t = x(1,:) .* x(2,:) + 2 * (x(1,:) + x(2,:)); save(['targets' num2str(i)],'t'); clear x t end由于数据是按顺序定义的,因此您定义的总数据集可以大于可放入主机内存中的数据量。计算机内存一次只能容纳该数据集的一部分。 现在,您可以按顺序在多个并行工作进程上加载数据集,并基于合成数据训练和仿真网络。当使用合成数据调用 train 或 sim 时,'useParallel' 参数会自动设置为 'yes'。在使用合成数据时,请在训练前使用 configure 函数手动配置网络的输入和输出,以匹配数据集之一。 xc = Composite; tc = Composite; for i=1:pool.NumWorkers data = load(['inputs' num2str(i)],'x'); xc{i} = data.x; data = load(['targets' num2str(i)],'t'); tc{i} = data.t; clear data end net2 = configure(net1,xc{1},tc{1}); net2 = train(net2,xc,tc); yc = net2(xc);要转换 sim 返回的合成输出,您可以访问它的每个元素,如果担心内存限制,可以单独访问。 for i=1:pool.NumWorkers yi = yc{i} end如果您不担心内存限制,请将合成值合并为一个本地值。 y = {yc{:}};当进行负载平衡时,会发生相同的过程,但不是每个数据集都有相同数量的样本(在前面的示例中为 1000 个),而是可以调整样本数以最好地利用工作进程主机的内存和速度差异。 不要求每个工作进程都有数据。如果合成值的元素 i 未定义,则计算中将不使用工作进程 i。 单 GPU 计算随着每代新产品的发展,GPU 卡的内核数量、内存大小和速度效率都在快速增长。视频游戏长期受益于改进的 GPU 性能。现在,这些卡足够灵活,可以执行一般的数值计算任务,例如训练神经网络。 有关最新 GPU 要求的信息,请参阅 Parallel Computing Toolbox 的网页;或者查询 MATLAB 以确定您的 PC 是否有支持的 GPU。此函数返回系统中 GPU 的数量: count = gpuDeviceCountcount = 1如果结果是一个或多个,您可以通过索引查询每个 GPU 的特征。这包括它的名称、多处理器的数量、每个多处理器的 SIMDWidth 以及总内存。 gpu1 = gpuDevice(1)gpu1 = CUDADevice with properties: Name: 'NVIDIA RTX A5000' Index: 1 ComputeCapability: '8.6' SupportsDouble: 1 DriverVersion: 11.6000 ToolkitVersion: 11.2000 MaxThreadsPerBlock: 1024 MaxShmemPerBlock: 49152 (49.15 KB) MaxThreadBlockSize: [1024 1024 64] MaxGridSize: [2.1475e+09 65535 65535] SIMDWidth: 32 TotalMemory: 25553076224 (25.55 GB) AvailableMemory: 25153765376 (25.15 GB) MultiprocessorCount: 64 ClockRateKHz: 1695000 ComputeMode: 'Default' GPUOverlapsTransfers: 1 KernelExecutionTimeout: 0 CanMapHostMemory: 1 DeviceSupported: 1 DeviceAvailable: 1 DeviceSelected: 1利用 GPU 的最简单方法是指定在参数 'useGPU' 设置为 'yes'('no' 为默认值)的情况下调用 train 和 sim。 net2 = train(net1,x,t,'useGPU','yes') y = net2(x,'useGPU','yes')如果 net1 具有默认的训练函数 trainlm,您会看到一条警告,指出 GPU 计算不支持雅可比矩阵训练,仅支持梯度训练。因此,训练函数自动更改为梯度训练函数 trainscg。为避免出现该通知,您可以在训练前指定该函数: net1.trainFcn = 'trainscg';要验证训练和仿真是否在 GPU 设备上进行,请要求显示计算机资源: net2 = train(net1,x,t,'useGPU','yes','showResources','yes') y = net2(x,'useGPU','yes','showResources','yes')以上每行代码都输出以下资源摘要: Computing Resources: GPU device #1, GeForce GTX 470当任一输入参数是 gpuArray 时,许多 MATLAB 函数会自动在 GPU 上执行。通常情况下,您可以使用 gpuArray 和 gather 函数在 GPU 之间来回移动数组。然而,为了在 GPU 上高效进行神经网络计算,需要转置矩阵和填充列以使每列中的第一个元素在 GPU 内存中正确对齐。Deep Learning Toolbox 提供一个名为 nndata2gpu 的特殊函数,它可将数组移至 GPU 上并对其进行适当的组织: xg = nndata2gpu(x); tg = nndata2gpu(t);现在,您可以使用已在 GPU 上转换的数据来训练和仿真网络,而不必指定 'useGPU' 参数。然后使用补充函数 gpu2nndata 转换生成的 GPU 数组并将其返回给 MATLAB。 在使用 gpuArray 数据进行训练之前,必须使用 configure 函数,用常规的 MATLAB 矩阵手动配置网络的输入和输出: net2 = configure(net1,x,t); % Configure with MATLAB arrays net2 = train(net2,xg,tg); % Execute on GPU with NNET formatted gpuArrays yg = net2(xg); % Execute on GPU y = gpu2nndata(yg); % Transfer array to local workspace在 GPU 和其他可能需要部署神经网络的硬件上,通常情况下指数函数 exp 不是用硬件实现的,而是用软件库实现的。这可能减慢使用 tansig sigmoid 传递函数的神经网络的运行速度。另外还有 Elliot sigmoid 函数,其表达式不包括对任何更高阶函数的调用: (equation) a = n / (1 + abs(n))在训练前,网络的 tansig 层可转换为 elliotsig 层,如下所示: for i=1:net.numLayers if strcmp(net.layers{i}.transferFcn,'tansig') net.layers{i}.transferFcn = 'elliotsig'; end end现在,训练和仿真可能在 GPU 上更快,部署硬件更简单。 分布式 GPU 计算分布式计算和 GPU 计算可以结合使用,以在单台计算机上的多个 CPU 和/或 GPU 上运行计算,或使用 MATLAB Parallel Server 在集群上的多个 CPU 和/或 GPU 上运行计算。 要使用这种计算方式,最简单的方法是通过由您使用的集群配置文件确定的并行池,指定 train 和 sim 来执行此操作。在这种情况下,特别推荐使用 'showResources' 选项,以验证是否采用预期的硬件: net2 = train(net1,x,t,'useParallel','yes','useGPU','yes','showResources','yes') y = net2(x,'useParallel','yes','useGPU','yes','showResources','yes')这些代码行使用并行池中所有可用的工作进程。每个独占 GPU 都有一个对应的工作进程使用此 GPU,而其他工作进程作为 CPU 工作。在某些情况下,只使用 GPU 可能会更快。例如,如果一台计算机有三个 GPU,每个 GPU 有四个工作进程,由 GPU 加速的三个工作进程可能会被第四个 CPU 工作进程限制速度。在这些情况下,您可以指定 train 和 sim 仅使用具有独占 GPU 的工作进程。 net2 = train(net1,x,t,'useParallel','yes','useGPU','only','showResources','yes') y = net2(x,'useParallel','yes','useGPU','only','showResources','yes')与简单的分布式计算一样,分布式 GPU 计算可以受益于手动创建的合成值。通过自己定义合成值,您可以指示要使用哪些工作进程、为每个工作进程分配多少样本以及哪些工作进程使用 GPU。 例如,如果您有四个工作进程,而只有三个 GPU,则您可以为 GPU 工作进程定义更大的数据集。此处,对每个合成元素使用不同样本加载来创建一个随机数据集: numSamples = [1000 1000 1000 300]; xc = Composite; tc = Composite; for i=1:4 xi = rand(2,numSamples(i)); ti = xi(1,:).^2 + 3*xi(2,:); xc{i} = xi; tc{i} = ti; end您现在可以指定 train 和 sim 使用三个可用的 GPU: net2 = configure(net1,xc{1},tc{1}); net2 = train(net2,xc,tc,'useGPU','yes','showResources','yes'); yc = net2(xc,'showResources','yes');为了确保前三个工作进程使用 GPU,手动将每个工作进程的合成元素转换为 gpuArray。每个工作进程在并行执行的 spmd 模块中执行此变换。 spmd if spmdIndex |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |