使用自动多 GPU 支持训练网络
此示例说明如何使用自动并行支持在本地计算机上使用多个 GPU 进行深度学习训练。
训练深度学习网络通常需要几个小时或几天的时间。借助并行计算,您可以使用多个 GPU 加快训练速度。要了解有关并行训练选项的详细信息,请参阅Scale Up Deep Learning in Parallel, on GPUs, and in the Cloud。
要求
在运行此示例之前,您必须将 CIFAR-10 数据集下载到本地计算机。要下载 CIFAR-10 数据集,请使用 downloadCIFARToFolders
函数,此函数作为支持文件包含在此示例中。要访问此文件,请以实时脚本形式打开此示例。使用以下代码将该数据集下载到您的当前目录。如果您已有 CIFAR-10 的本地副本,则可以略过本节。
directory = pwd; [locationCifar10Train,locationCifar10Test] = downloadCIFARToFolders(directory);
Downloading CIFAR-10 data set...done. Copying CIFAR-10 to folders...done.
加载数据集
使用 imageDatastore
对象加载训练和测试数据集。在以下代码中,确保数据存储的位置指向本地计算机中的 CIFAR-10。
imdsTrain = imageDatastore(locationCifar10Train, ... IncludeSubfolders=true, ... LabelSource="foldernames"); imdsTest = imageDatastore(locationCifar10Test, ... IncludeSubfolders=true, ... LabelSource="foldernames");
要使用增强的图像数据训练网络,请创建 augmentedImageDatastore
对象。使用随机平移和水平翻转。数据增强有助于防止网络过拟合和记忆训练图像的具体细节。
imageSize = [32 32 3]; pixelRange = [-4 4]; imageAugmenter = imageDataAugmenter( ... RandXReflection=true, ... RandXTranslation=pixelRange, ... RandYTranslation=pixelRange); augmentedImdsTrain = augmentedImageDatastore(imageSize,imdsTrain, ... DataAugmentation=imageAugmenter);
定义网络架构和训练选项
为 CIFAR-10 数据集定义一个网络架构。为了简化代码,使用对输入进行卷积的卷积块。池化层对空间维度进行下采样。
blockDepth = 4; % blockDepth controls the depth of a convolutional block. netWidth = 32; % netWidth controls the number of filters in a convolutional block. layers = [ imageInputLayer(imageSize) convolutionalBlock(netWidth,blockDepth) maxPooling2dLayer(2,Stride=2) convolutionalBlock(2*netWidth,blockDepth) maxPooling2dLayer(2,Stride=2) convolutionalBlock(4*netWidth,blockDepth) averagePooling2dLayer(8) fullyConnectedLayer(10) softmaxLayer];
指定训练选项。
通过将执行环境设置为 "
multi-gpu"
,使用多个 GPU 训练网络。当您使用多个 GPU 时,就增加了可用的计算资源。根据 GPU 的数量扩大小批量大小,以保持每个 GPU 上的工作负载不变。在此示例中,GPU 的数量是两个。根据小批量大小缩放学习率。在 GPU 上进行训练需要 Parallel Computing Toolbox™ 许可证和受支持的 GPU 设备。有关受支持设备的信息,请参阅GPU 计算要求 (Parallel Computing Toolbox)。使用学习率调度,以随着训练的进行降低学习率。
打开训练进度图可在训练过程中获得可视化的反馈数据。
numGPUs = gpuDeviceCount("available")
numGPUs = 4
miniBatchSize = 256*numGPUs; initialLearnRate = 1e-1*miniBatchSize/256; options = trainingOptions("sgdm", ... ExecutionEnvironment="multi-gpu", ... % Turn on automatic multi-gpu support. InitialLearnRate=initialLearnRate, ... % Set the initial learning rate. MiniBatchSize=miniBatchSize, ... % Set the MiniBatchSize. Verbose=false, ... % Do not send command line output. Plots="training-progress", ... % Turn on the training progress plot. Metrics="accuracy", ... L2Regularization=1e-10, ... MaxEpochs=60, ... Shuffle="every-epoch", ... ValidationData=imdsTest, ... ValidationFrequency=floor(numel(imdsTrain.Files)/miniBatchSize), ... LearnRateSchedule="piecewise", ... LearnRateDropFactor=0.1, ... LearnRateDropPeriod=50);
训练网络及其分类使用
使用 trainnet
函数训练神经网络。对于分类,使用交叉熵损失。
net = trainnet(augmentedImdsTrain,layers,"crossentropy",options);
对测试图像进行分类。要使用多个观测值进行预测,请使用 minibatchpredict
函数。要将预测分数转换为标签,请使用 scores2label
函数。minibatchpredict
函数自动使用 GPU(如果有)。否则,该函数使用 CPU。
classes = categories(imdsTest.Labels); scores = minibatchpredict(net,imdsTest); Y = scores2label(scores,classes);
确定网络的准确度。
accuracy = sum(Y==imdsTest.Labels)/numel(imdsTest.Labels)
accuracy = 0.8879
自动多 GPU 支持可以利用多个 GPU 来加快网络训练速度。下图显示在具有四个 NVIDIA© TITAN Xp GPU 的 Linux 计算机上,GPU 的数量对整个训练时间的加速情况。
定义辅助函数
定义一个函数,以便在网络架构中创建卷积模块。
function layers = convolutionalBlock(numFilters,numConvLayers) layers = [ convolution2dLayer(3,numFilters,Padding="same") batchNormalizationLayer reluLayer]; layers = repmat(layers,numConvLayers,1); end
另请参阅
trainnet
| trainingOptions
| dlnetwork
| imageDatastore