利用NVIDIA-NGC中的MATLAB容器加速语义分割
利用NVIDIA-NGC中的MATLAB容器加速語義分割
Speeding Up Semantic Segmentation Using MATLAB Container from NVIDIA NGC
使用單一GPU訓練深度學習模式的時代已經一去不復返了。對于計算密集型算法(如語義分割),單個GPU可能需要幾天時間來優化模型。但多GPU硬件很貴。不會再有了;NVIDIA的云上多GPU硬件實例,比如AWS P3,只允許你支付你使用的東西。云實例允許您利用支持Tensor核心的最新一代硬件,以適度的投資實現顯著的性能引導。您可能聽說過設置云實例很困難,但NVIDIA NGC使生活變得更輕松。NGC是用于深度學習、機器學習和HPC的GPU優化軟件的中心。NGC負責所有的管道,因此開發人員和數據科學家可以專注于生成可操作的見解。
這篇文章通過在云實例上使用NVIDIA GPUs和從NGC獲得的用于深入學習的MATLAB容器,走過了加速語義分割的最簡單路徑。首先,我們將解釋語義分割。接下來,我們將使用NGC提供的MATLAB R2018b容器在兩個不同的P3實例上展示在MATLAB中訓練的語義分割模型的性能結果。最后,我們將在MATLAB中介紹一些技巧,這些技巧使深入學習變得容易,并有助于管理內存使用。
What is Semantic Segmentation?
用于深度學習的語義分割算法為圖像中的每個像素分配一個標簽或類別。與傳統的包圍盒方法相比,這種密集的識別方法在某些應用中提供了關鍵的能力。在自動駕駛中,它是標記為“道路”的廣義區域與精確的、像素級的確定道路可行駛表面之間的區別。在醫學成像中,它意味著將矩形區域標記為“癌細胞”與知道細胞的確切形狀和大小之間的區別。
Figure 1. Example of an image with semantic labels for every pixel
我們使用MATLAB對語義分割進行了測試,訓練出一個SegNet模型,該模型具有四個編碼層和四個解碼層的編解碼結構。與該模型相關的數據集是CamVid數據集,它是一個驅動數據集,每個像素都用一個語義類(例如天空、道路、車輛等)標記。與原研究不同的是,我們使用隨機梯度下降法進行訓練,并對預先訓練的VGG-16模型的層和權重進行了預初始化。
Performance Testing Using MATLAB on P3 Instances with NVIDIA GPUs
雖然語義分割是有效的,但它需要付出巨大的計算和內存代價。我們使用AWS P3實例和NGC提供的MATLAB容器運行測試。使用容器需要一個AWS帳戶和一個有效的MATLAB許可證。您可以獲得免費的云使用的試用版MATLAB許可證。Mathworks提供了如何在AWS上設置MATLAB容器的可用說明。
最初的SegNet在2015年的實現花費了大約一周的時間運行在作者使用的Tesla K40上,正如在最初的論文中提到的。下面是在一個p3.2xlarge實例上使用一個V100 NVIDIA GPU在MATLAB中進行語義分割網絡訓練的過程圖。圖2顯示了它花費了大約121分鐘,這比原來的論文要快得多。
接下來,我們使用p3.16xlarge實例上可用的八個V100 NVIDIA gpu執行相同的測試。MATLAB代碼中唯一需要更改的是:將訓練選項參數ExecutionEnvironment設置為multi-gpu。圖3展示了一個訓練圖,顯示這個過程現在花費了37分鐘,比使用p3.2xlarge實例快3.25倍。
Figure 3. Training Progress for SegNet in MATLAB on eight V100 NVIDIA GPUs
性能提升了3.25倍,顯示了最新的NVIDIA多GPU硬件的強大功能,并帶有Tensor內核,使原本“大約一周”的時間縮短至37分鐘。我敢打賭,SegNet的作者們在開發算法的時候,一定希望有這樣的硬件!
Making Deep Learning Easier with MATLAB
現在讓我們深入探討為什么應該使用MATLAB開發深層學習算法,如語義分割。MATLAB包含許多有用的工具和命令,以便于執行深入學習。最有用的MATLAB命令之一是imageDatastore,它允許您有效地管理大量圖像。該命令創建一個數據庫,允許將整個數據集作為單個對象處理。MiniBatchSize參數對于語義分割尤其重要,它決定了每次迭代使用多少圖像。默認值256會占用太多內存進行語義分割,因此我們將該值設置為4。
如imageDataAugmenter函數所示,數據增強代表了MATLAB中另一種強大的深度學習能力。數據擴充通過使用翻譯、旋轉、反射、縮放、裁剪等向網絡提供更多示例來擴展數據集。這有助于提高模型精度。這使用隨機左/右反射的數據增強和正負10像素的X/Y轉換。這種數據擴充被合并到一個pixelLabelDatastore中,這樣每次迭代時操作都會發生,并且避免了不必要的數據集副本。
How We Performed Semantic Segmentation in MATLAB
本節介紹了我們用于上述測試的代碼的關鍵部分。本測試中使用的完整的MATLAB代碼在這里提供。最后一行是訓練的地方。
以下代碼下載數據集并在本地計算機上解壓它。
imageURL = ‘http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/files/701_StillsRaw_full.zip’;
labelURL = ‘http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/LabeledApproved_full.zip’;
outputFolder = fullfile(tempdir,‘CamVid’);
if ~exist(outputFolder, ‘dir’)
mkdir(outputFolder)
labelsZip = fullfile(outputFolder,‘labels.zip’);
imagesZip = fullfile(outputFolder,‘images.zip’);
disp(‘Downloading 16 MB CamVid dataset labels…’);
websave(labelsZip, labelURL);
unzip(labelsZip, fullfile(outputFolder,‘labels’));
disp(‘Downloading 557 MB CamVid dataset images…’);
websave(imagesZip, imageURL);
unzip(imagesZip, fullfile(outputFolder,‘images’));
end
此代碼生成一個臨時文件夾,用于解壓縮實例上的文件。使用容器時,一旦容器關閉,這些文件將丟失。如果您想為數據維護一個一致的位置,您應該將代碼更改為使用S3存儲桶或其他永久位置。
下面的代碼顯示了用于訓練語義分割網絡的來自CamVid數據集的11個類。在原始數據集中,有32個類。
imgDir = fullfile(outputFolder,‘images’,‘701_StillsRaw_full’);
imds = imageDatastore(imgDir);classes = [ “Sky” “Building” “Pole” “Road” “Pavement” “Tree” “SignSymbol” “Fence” “Car” “Pedestrian” “Bicyclist” ];
labelIDs = camvidPixelLabelIDs();labelDir = fullfile(outputFolder,‘labels’);
pxds = pixelLabelDatastore(labelDir,classes,labelIDs);
在下一節中,我們將根據SegNet的分辨率調整CamVid數據的大小,并將數據集劃分為訓練集和測試集。
imageFolder = fullfile(outputFolder,‘imagesResized’,filesep);
imds = resizeCamVidImages(imds,imageFolder);
labelFolder = fullfile(outputFolder,‘labelsResized’,filesep);
pxds = resizeCamVidPixelLabels(pxds,labelFolder); [imdsTrain,imdsTest,pxdsTrain,pxdsTest] = partitionCamVidData(imds,pxds);numTrainingImages = numel(imdsTrain.Files)numTestingImages = numel(imdsTest.Files)
現在讓我們創建一個SegNet網絡。從VGG-16權重開始,調整它們以平衡類權重。
imageSize = [360 480 3];
numClasses = numel(classes);l
graph = segnetLayers(imageSize,numClasses,‘vgg16’);
imageFreq = tbl.PixelCount ./ tbl.ImagePixelCount;
classWeights = median(imageFreq) ./ imageFreq;pxLayer = pixelClassificationLayer(‘Name’,‘labels’,‘ClassNames’,tbl.Name,‘ClassWeights’,classWeights);lgraph = removeLayers(lgraph,‘pixelLabels’);lgraph = addLayers(lgraph, pxLayer);
lgraph = connectLayers(lgraph,‘softmax’,‘labels’);
接下來,選擇培訓選項。MiniBatchSize參數對于語義分割尤其重要,它決定了每次迭代使用多少圖像。默認值256需要太多內存用于語義分段,因此我們將該值設置為4。ExecutionEnvironment選項設置為multi-gpu以使用p3.16xlarge實例上的多個V100 NVIDIA gpu。有關培訓選項的更多詳細信息,請參閱文檔。
options = trainingOptions(‘sgdm’, … ‘Momentum’,0.9, … ‘ExecutionEnvironment’,‘multi-gpu’,… ‘InitialLearnRate’,1e-3, … ‘L2Regularization’,0.0005, … ‘MaxEpochs’,100, … ‘MiniBatchSize’,4 * gpuDeviceCount, … ‘Shuffle’,‘every-epoch’, … ‘Plots’,‘training-progress’,… ‘VerboseFrequency’,2);
MATLAB中用于深度學習的另一個強大功能是imageDataAugmenter,它為網絡提供了更多示例,有助于提高精度。此示例使用隨機左/右反射的數據增強和正負10像素的X/Y轉換。這將合并到一個pixelLabelDatastore中,以便在每次迭代時執行操作,并避免不必要的數據集副本。
augmenter = imageDataAugmenter(‘RandXReflection’,true,… ‘RandXTranslation’,[-10 10],‘RandYTranslation’,[-10 10]);pximds = pixelLabelImageDatastore(imdsTrain,pxdsTrain,… ‘DataAugmentation’,augmenter);
現在我們可以開始訓練了。下一行用于訓練的代碼在p3.16xlarge實例上運行大約需要37分鐘。我們在繪圖窗口中測量訓練所用的時間,以跟蹤訓練進度。請參閱圖2和圖3,查看在p3.2xlarge和p3.16xlarge實例上運行此函數所需的測量時間。
[net, info] = trainNetwork(pximds,lgraph,options);
結論
MATLAB使工程師能夠很容易地訓練深度學習模型,利用NVIDIA
GPU加速訓練過程。使用MATLAB,從單一GPU機器上的訓練切換到多GPU機器只需要一行代碼,如上面最后的代碼片段所示。我們展示了如何通過在NGC上的MATLAB深度學習容器中訓練神經網絡來加速深度學習應用程序,該容器旨在充分利用高性能NVIDIA?GPU。下一步,下載代碼并在MATLAB中的awsp3實例上親自嘗試。
總結
以上是生活随笔為你收集整理的利用NVIDIA-NGC中的MATLAB容器加速语义分割的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NVIDIA Jarvis:一个GPU加
- 下一篇: 适用于Linux 2的Windows子系