利用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);
lgraph = 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深度学习容器中训练神经网络来加速深度学习应用程序,该容器旨在充分利用高性能NVIDIAGPU。下一步,下载代码并在MATLAB中的awsp3实例上亲自尝试。
利用NVIDIA-NGC中的MATLAB容器加速语义分割的更多相关文章
- 利用NVIDIA NGC的TensorRT容器优化和加速人工智能推理
利用NVIDIA NGC的TensorRT容器优化和加速人工智能推理 Optimizing and Accelerating AI Inference with the TensorRT Contai ...
- Amazon SageMaker和NVIDIA NGC加速AI和ML工作流
Amazon SageMaker和NVIDIA NGC加速AI和ML工作流 从自动驾驶汽车到药物发现,人工智能正成为主流,并迅速渗透到每个行业.但是,开发和部署AI应用程序是一项具有挑战性的工作.该过 ...
- 用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割
用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割 Accelerating Medical Image Segmentation with NVIDIA Tensor ...
- 利用UltraScale和UltraScale+FPGA和MPSOC加速DSP设计生产力
利用UltraScale和UltraScale+FPGA和MPSOC加速DSP设计生产力 Accelerating DSP Design Productivity with UltraScale an ...
- C++ STL中的常用容器浅谈
STL是C/C++开发中一个非常重要的模板,而其中定义的各种容器也是非常方便我们大家使用.下面,我们就浅谈某些常用的容器.这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点.STL中 ...
- Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
基于Spring-4.3.7.RELEASE Spring的配置不仅仅局限在XML文件,同样也可以使用Java代码来配置.在这里我使用XML配置文件的方式来粗略地讲讲WebApplicationCon ...
- c#中的Unity容器
DIP是依赖倒置原则:一种软件架构设计的原则(抽象概念).依赖于抽象不依赖于细节 IOC即为控制反转(Inversion of Control):传统开发,上端依赖(调用/指定)下端对象,会有依赖,把 ...
- 教你如何修改运行中的docker容器的端口映射
在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当docker start运行容器后并没有提供一个-p选项或设 ...
- 深入解析C++ STL中的常用容器
转载:http://blog.csdn.net/u013443618/article/details/49964299 这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点.STL中的 ...
随机推荐
- Think5之删除单条数据功能
//删除单条学员信息 public function deleteStu(Request $request){ $stu_id = $request->param('id'); $result ...
- Tomcat容器、JSP和Servlet
目录 JSP Tomcat.JSP和Servlet JSP JSP全名为Java Server Pages,其根本是一个简化的Servlet设计.JSP技术有点类似ASP技术,它是在传统的HTML网页 ...
- RHCE7 认证之学习笔记
-------------------------------------------------------------------------------------------初始化:两台服务器 ...
- Intel汇编语言程序设计学习-第四章 数据传送、寻址和算术运算-下
4.3 和数据相关的操作符和伪指令 操作符和伪指令并非机器可执行的指令,相反,它们是由汇编器进行解释的.开发者可以使用一系列的MASM操作符或伪指令获取数据的地址以及大小等特征信息: OFFSET操 ...
- 【python】Leetcode每日一题-设计停车系统
[python]Leetcode每日一题-设计停车系统 [题目描述] 请你给一个停车场设计一个停车系统.停车场总共有三种不同大小的车位:大,中和小,每种尺寸分别有固定数目的车位. 请你实现 Parki ...
- 使用docker-compose.yml快速搭建Linux/Mac开发/生产环境
传送门 点击进入Github,https://github.com/ovim/dockerfiles 简单介绍 Dockerfiles 搭建基础公用环境包,方便使用,支持业务不断的提升而需要一些软件的 ...
- 一、Github+Pycharm基础
GitHub为版本管理工具 常用的版本管理工具:本地化版本管理系统.集中式版本管理系统SVN.分布式版本管理系统 一.安装git(自行百度) 二.文件操作与分支管理基础 1.版本控制系统分类 集中化版 ...
- windows桌面图标及任务管理栏丢失
背景环境: 卸载某些软件,如Auto CAD 2011 之后,会出现桌面图标和任务栏丢失的现象,某些重要文件没有保存或者不能注销及重启的动作 1:按组合键Ctrl+Shift+Esc,键调出任务管理器 ...
- app.json文件配置
pages 页面路径的存放列表 通过手写页面路径可以在对应目录下自动创建对应文件 "pages": [ "pages/demo3/demo3", "p ...
- [DB] MySQL 索引分类
按数据结构 B树索引 数据位于叶子节点,到任何一个叶子节点的距离相同,一般不超过3-4层 B+树索引:每个叶子节点除了数据还存放前后叶子节点的指针,方便快速检索,是InnoDB采用的索引结构 Hash ...