主要内容

生成INT8深入学习网络代码树莓π

这个例子以前命名的代码生成量化深度学习网络覆盆子π”。

这个例子为一个卷积生成c++代码优化深层神经网络通过量化权重,偏见,和卷积的激活层8位整数数据类型。量化是通过提供校准执行的结果文件产生的校准(深度学习工具箱)函数codegen命令。

代码生成不支持量化深度产生的神经网络万博1manbetx数字转换(深度学习工具箱)函数。

深度学习使用神经网络包含许多处理层的体系结构,包括卷积层。深度学习模型通常工作在大的带安全标签的数据集。对这些模型进行推理计算密集型,消耗大量的内存。神经网络使用内存来存储输入数据,参数(权重),激活每一层的输入通过网络传播。深在MATLAB神经网络训练使用单精度浮点数据类型。即使网络小需要大量的内存和硬件来执行这些浮点算术运算。这些限制可以抑制部署深度学习模型的设备计算能力较低,规模较小的内存资源。通过使用低精度存储重量和激活,你可以减少网络的内存需求。

您可以使用深度学习工具箱与深度学习工具箱模型量化库支持包减少内存占用的深层神经网络通过量化权重,偏见,和激活卷积层8位整数数据类型。万博1manbetx然后,您可以使用MATLAB编码器™来生成这个网络优化的代码。生成的代码利用手臂®处理器SIMD通过使用手臂计算库。生成的代码可以集成到你的项目源代码,静态或动态库,或可执行文件,您可以部署到各种手臂CPU平台如覆盆子π™。

这个例子展示了如何生成c++代码使用手臂的卷积神经网络计算库和执行推理计算在8位整数。

这个例子不支持在线MATLAB。万博1manbetx

第三方的先决条件

示例:使用SqueezeNet分类图像

在本例中,您使用MATLAB编码器生成optmized c++代码为深卷积神经网络和图像进行分类。生成的代码执行推理计算卷积层使用8位整数数据类型。这个例子使用了pretrainedsqueezenet(深度学习工具箱)卷积神经网络。

SqueezeNet已经训练了1000年ImageNet数据集包含的图像对象类别。网络已经学会丰富广泛的图像特征表示。网络需要一个图像作为输入和输出图像中对象的标签一起为每个对象的类别的概率。

这个例子包含四个步骤:

  1. 修改SqueezeNet神经网络分类图像的一个小子集包含五个对象类别使用转移学习。

  2. 使用校准功能锻炼与样本输入网络收集范围信息产生校准结果文件。

  3. 生成网络的优化代码通过使用codegen命令和校准的结果文件。生成的代码运行在覆盆子π通过公益诉讼执行目标。

  4. 执行生成的公益诉讼墨西哥人覆盆子π。

将学习使用SqueezeNet

对一组新的图像进行分类,必须调整pretrained SqueezeNet卷积神经网络通过学习转移。迁移学习,取pretrained网络和使用它作为一个起点,学习新的任务。微调网络通过学习转移通常比训练一个网络快得多,也更容易与随机初始化权重从零开始。您可以快速学习功能转移到一个新的任务通过使用较少的训练图像。

负荷训练数据

解压缩和加载新的图像作为图像数据存储。的imageDatastore函数自动标签图像基于文件夹的名字和存储数据作为ImageDatastore对象。图像数据存储可以存储大量图像数据,包括数据,并不适合在内存中,有效地阅读批图像卷积神经网络在训练。

解压缩(“MerchData.zip”);imd = imageDatastore (“MerchData”,“IncludeSubfolders”,真的,“LabelSource”,“foldernames”);[imdsTrain, imdsValidation] = splitEachLabel (imd, 0.7,“随机”);numTrainImages =元素个数(imdsTrain.Labels);idx = randperm (numTrainImages 4);img = imtile (imd,“帧”,idx);图imshow (img)标题(“从训练数据集随机图像”);

图包含一个坐标轴对象。坐标轴对象与标题随机图像从训练数据集包含一个类型的对象的形象。

负载Pretrained网络

加载pretrained SqueezeNet网络。

网= squeezenet;

的对象包含了DAGNetwork对象。第一层是图像输入层,接受输入的图像大小227 - 227 - 3,3是颜色通道的数量。使用analyzeNetwork(深度学习工具箱)函数显示一个交互式可视化的网络架构,来检测网络中的错误和问题,并显示详细信息网络层。层信息包括层激活的大小和可学的参数,可学的参数的总数,复发性层的状态参数的大小。

inputSize = net.Layers (1) .InputSize;analyzeNetwork(净);

取代最后一层

网络的卷积层提取图像特征,最后可学的一层一层和最后的分类使用对输入图像进行分类。这两个层,“conv10”“ClassificationLayer_predictions”SqueezeNet,包含如何结合信息网络特性,提取类概率,损失价值,预测标签。

再培训pretrained网络分类的新图像,用新的替换这两个层层适应新的数据集。你可以手动或使用helper函数findLayersToReplace自动发现这些层。

这是findLayersToReplace辅助功能:

类型findLayersToReplace.m
函数[learnableLayer classLayer] = findLayersToReplace (lgraph) % findLayersToReplace (lgraph)发现单一分类层和%前可学的(完全连接或卷积)层的层lgraph %图。% 2021年版权MathWorks公司如果~ isa (lgraph nnet.cnn.LayerGraph的)错误(参数必须是LayerGraph对象。)结束%源,目的地,和图层名称。src =字符串(lgraph.Connections.Source);dst =字符串(lgraph.Connections.Destination);layerNames =字符串({lgraph.Layers.Name} ');%找到分类层。层图必须有一个%分类层。isClassificationLayer = arrayfun (@ (l)……(isa (l, nnet.cnn.layer.ClassificationOutputLayer) | isa (l ' nnet.layer.ClassificationLayer ')),…lgraph.Layers); if sum(isClassificationLayer) ~= 1 error('Layer graph must have a single classification layer.') end classLayer = lgraph.Layers(isClassificationLayer); % Traverse the layer graph in reverse starting from the classification % layer. If the network branches, throw an error. currentLayerIdx = find(isClassificationLayer); while true if numel(currentLayerIdx) ~= 1 error('Layer graph must have a single learnable layer preceding the classification layer.') end currentLayerType = class(lgraph.Layers(currentLayerIdx)); isLearnableLayer = ismember(currentLayerType, ... ['nnet.cnn.layer.FullyConnectedLayer','nnet.cnn.layer.Convolution2DLayer']); if isLearnableLayer learnableLayer = lgraph.Layers(currentLayerIdx); return end currentDstIdx = find(layerNames(currentLayerIdx) == dst); currentLayerIdx = find(src(currentDstIdx) == layerNames); %#ok end end

使用这个函数来取代最后一层,运行这些命令:

lgraph = layerGraph(净);[learnableLayer, classLayer] = findLayersToReplace (lgraph);numClasses =元素个数(类别(imdsTrain.Labels));newConvLayer = convolution2dLayer (numClasses [1],“WeightLearnRateFactor”,10日,“BiasLearnRateFactor”10“名称”,“new_conv”);lgraph = replaceLayer (lgraph,“conv10”,newConvLayer);newClassificatonLayer = classificationLayer (“名字”,“new_classoutput”);lgraph = replaceLayer (lgraph,“ClassificationLayer_predictions”,newClassificatonLayer);

列车网络的

网络要求所有输入图像大小227 - 227 - 3,但每个图像的图像数据存储大小不一。使用一个增强图像数据存储图像自动调整训练。指定要执行这些额外的增加操作培训图片:随机翻转训练图像的垂直轴,,随便翻译一下30像素水平和垂直。数据增加有助于防止网络过度学习和记忆的训练图像的细节。

pixelRange = 30 [-30];imageAugmenter = imageDataAugmenter (“RandXReflection”,真的,“RandXTranslation”pixelRange,“RandYTranslation”,pixelRange);augimdsTrain = augmentedImageDatastore (inputSize (1:2), imdsTrain,“DataAugmentation”,imageAugmenter);

自动调整验证图像不执行进一步的数据,使用一个增强的图像数据存储不指定任何额外的预处理操作。

augimdsValidation = augmentedImageDatastore (inputSize (1:2), imdsValidation);

指定培训选项。转移学习,防止功能的早期层pretrained网络(传输层的重量)。放慢学习的传输层,设置初始学习速率小值。在前面的步骤中,您的学习速率因素增加卷积层加快学习在新的最后一层。这种组合的学习速率设置导致快速学习只有在新的层和慢学习其他层。当执行转移学习,你不需要训练尽可能多的时代。一个时代是一个完整的培训周期在整个训练数据集。指定mini-batch大小11,这样在每个时代你考虑所有的数据。在训练过程中,每次软件验证网络ValidationFrequency迭代。

选择= trainingOptions (“个”,“MiniBatchSize”11“MaxEpochs”7“InitialLearnRate”2的军医,“洗牌”,“every-epoch”,“ValidationData”augimdsValidation,“ValidationFrequency”3,“详细”、假);

训练网络,包括转移和新层。

netTransfer = trainNetwork (augimdsTrain、lgraph选项);一会= netTransfer.Layers . class(结束);保存(“mySqueezenet.mat”,“netTransfer”);

网络生成校准结果文件

创建一个dlquantizer对象和指定网络。

quantObj = dlquantizer (netTransfer,“ExecutionEnvironment”,“CPU”);

使用校准功能锻炼与样本输入网络收集范围信息。的校准功能锻炼的网络和收集动态范围重量和偏见的卷积和完全连接层的网络和动态范围激活所有层的网络。函数返回一个表。表的每一行包含的范围信息可学的参数优化的网络。

calResults = quantObj.calibrate (augimdsTrain);
尝试校准与主机GPU错误信息:无法找到支持GPU设备。万博1manbetxGPU支持的更多信息,请参阅GPU的支持。万博1manbetx恢复使用主机CPU。
保存(“squeezenetCalResults.mat”,“calResults”);保存(“squeezenetQuantObj.mat”,“quantObj”);

函数产生公益诉讼的墨西哥人

在本例中,您生成代码的入口点函数predict_int8。这个函数使用coder.loadDeepLearningNetwork函数加载一个深度学习模型和构造和设置一个CNN类。然后的入口点函数预测使用的响应预测(深度学习工具箱)函数。

类型predict_int8.m
函数= predict_int8 (netFile)持续mynet;如果isempty (mynet) mynet = coder.loadDeepLearningNetwork (netFile);结束了=预测(mynet);结束

生成一个公益诉讼墨西哥人功能,创建一个配置对象的静态代码库并设置验证模式“公益诉讼”。设置目标语言c++。

cfg = coder.config (“自由”,“是”,真正的);cfg。VerificationMode =“公益诉讼”;cfg。TargetLang =“c++”;

创建一个深度学习ARM计算库配置对象。指定库版本和arm的体系结构。对于这个示例,假设的手臂计算图书馆的覆盆子π20.02.1硬件版本。

dlcfg = coder.DeepLearningConfig (“arm-compute”);dlcfg。ArmComputeVersion =“20.02.1”;dlcfg。ArmArchitecture =v7的;

的属性设置dlcfg为低精度/ INT8推理生成代码。

dlcfg。CalibrationResultFile =“squeezenetQuantObj.mat”;dlcfg。数据类型=“int8”;

6。设置DeepLearningConfig的属性cfgdlcfg

cfg。DeepLearningConfig = dlcfg;

7所示。使用MATLAB支持包树莓π函万博1manbetx数,raspi创建一个连接的覆盆子π。在以下代码中,替换:

  • raspiname覆盆子π的名称

  • 用户名和你的用户名

  • 密码用你的密码

% r = raspi (“raspiname”、“用户名”,“密码”);

8。创建一个coder.Hardware对象树莓π和附加的代码生成配置对象。

% hw =编码器。硬件(覆盆子π);% cfg。硬件= hw;

9。生成一个公益诉讼墨西哥人通过使用函数codegen命令

% codegen配置cfg predict_int8 args {coder.Constant (“mySqueezenet.mat”)的(227227 3 uint8)}

上运行公益诉讼墨西哥人函数生成树莓π

输入图像相同大小的预计将作为输入网络的大小。读到你想要的图片进行分类并调整输入网络的大小。这稍微调整图像的纵横比变化。

% testImage = imread (“MerchDataTest.jpg”);% testImage = imresize (testImage inputSize (1:2));

比较深的预测学习工具箱预测函数和generared公益诉讼墨西哥人的功能predict_int8_pil调用这两个函数,分别输入图像。

% predictScores(: 1) =预测(netTransfer testImage) ';% predictScores (:, 2) = predict_int8_pil (mySqueezenet.mat, testImage);

显示标签及其相关预测概率直方图。

% h =图;% h.Position (3) = 2 * h.Position (3);% ax₁=情节(1、2、1);% ax2 =情节(1、2、2);%的形象(ax₁, testImage);% barh (ax2 predictScores)%包含(ax2,“概率”)% yticklabels (ax2一会)% ax2。XLim = 1.1 [0];% ax2。YAxisLocation = '左';%的传说(Matlab单一,arm-compute 8位整数);% sgtitle(预测使用Squeezenet”)% saveas (gcf SqueeznetPredictionComparison.jpg);%关闭(gcf);imshow (“SqueeznetPredictionComparison.jpg”);

图包含一个坐标轴对象。坐标轴对象包含一个类型的对象的形象。

另请参阅

应用程序

功能

对象

相关的话题