主要内容

导入预训练的ONNX YOLO v2对象检测器

这个例子展示了如何导入一个预先训练的ONNX™(开放神经网络交换),你只看一次(YOLO) v2[1]目标检测网络,用于检测目标。导入网络后,可以使用GPU编码器将其部署到嵌入式平台™ 或者使用迁移学习和Trainyolov2oObject检测器

下载ONNX YOLO v2 Network

下载与预培训的Tiny YOLO v2网络相关的文件。

pretrainedURL =“https://ssd.mathworks.com/金宝appsupportfiles/vision/deeplearning/models/yolov2/tiny_yolov2.tar”; 预训练网=“yolov2Tiny.tar”如果~存在(pretrainedNetTar“文件”)disp('下载预训练网络(58mb)…');websave (pretrainedNetTar pretrainedURL);终止
正在下载预训练网络(58 MB)。。。

提取YOLO v2网络

卸载下载的文件以提取微型YOLO v2网络。加载“Model.onnx”模型从tiny_yolov2文件夹,这是一个预先训练在PASCAL VOC数据集上的ONNX YOLO v2网络。该网络可以检测来自20个不同类别的对象[4]

onnxfiles=untar(pretrainedNetTar);预训练网=“tiny_yolov2 / Model.onnx”

导入ONNX YOLO v2图层

使用importONNXLayers命令功能,导入下载的网络。

lgraph = importONNXLayers (pretrainedNet,“重要性”,真正的);
警告:导入的层没有输出层,因为ONNX文件没有指定网络的输出层类型。在添加输出层之前,这些层是不可训练的。要么向导入的层添加一个输出层,要么在importONNXLayers调用中使用'OutputLayerType'指定输出层类型。

在本例中,您向导入的层添加了一个输出层,因此可以忽略此警告。的添加YOLO v2变换和输出层第节显示如何将YOLO v2输出层以及YOLO v2转换层添加到导入的层。

本例中的网络不包含不受支持的层。金宝app注意,如果要导入的网络不支持层,该函数将它们作为占位符层导入。金宝app在使用导入的网络之前,必须替换这些层。有关替换占位符层的更多信息,请参见findPlaceholderLayers(深度学习工具箱)

定义YOLO v2锚定框

YOLO v2使用预定义的锚盒来预测对象位置。导入网络中使用的锚盒在Tiny YOLO v2网络配置文件中定义[5].ONNX锚是根据最终卷积层的输出大小定义的,最终卷积层是13乘13。使用锚yolov2ObjectDetector,将锚盒的大小调整为网络输入的大小,即416 × 416。锚箱yolov2ObjectDetector必须在[高,宽]中指定。

onnxAnchors = [1.08, 1.19;3.42、4.41;6.63、11.38;9.42、5.11;16.62、10.52);inputSize = lgraph.Layers (1,1) .InputSize (1:2);lastActivationSize =(13、13);upScaleFactor = inputSize. / lastActivationSize;anchorBoxesTmp = upScaleFactor。* onnxAnchors;anchorBoxes = [anchorBoxesTmp (:, 2), anchorBoxesTmp (: 1)];

重新排序检测层权重

为了有效的处理,您必须重新排序导入网络中最后一个卷积层的权值和偏差,以获得以下安排中的激活yolov2ObjectDetector需要。yolov2ObjectDetector预计最后一层卷积的feature map的125个通道,排列如下:

  • 通道1至5-五个锚的IoU值

  • 频道6至10 - X值为五个锚

  • 频道11至15 - 5个锚点的Y值

  • 通道16到20 -五个锚的宽度值

  • 频道21至25 -五个锚的高度值

  • 频道26至30 - 5个主播的1级概率值

  • 通道31至35-五个锚的2级概率值

  • 通道121至125-五个锚的20级概率值

然而,在大小为13×13的最后一个卷积层中,激活的安排不同。特征图中的25个通道中的每一个对应于:

  • 通道1-X值

  • 通道2 - Y值

  • 通道3 -宽度值

  • 频道4 -高度值

  • 通道5-IoU值

  • 通道6 -第一类概率值

  • 通道7 -第2类概率值

  • 通道25-20级概率值

使用支持函数金宝apprearrangeONNXWeights,以重新排序导入网络中最后一个卷积层的权值和偏差,并获得所需格式的激活yolov2ObjectDetector

权重=lgraph.Layers(结束,1)。权重;偏差=lgraph.Layers(结束,1)。偏差;layerName=lgraph.Layers(end,1).Name;Numanchorboxs=大小(onnxAnchors,1);[modWeights,modBias]=重新排列nxWeights(权重,偏差,数值框);

将引入的网络中最后一层卷积层的权值和偏差替换为使用重排序权值和偏差的新卷积层。

filterSize=大小(modWeights,[12]);numFilters=大小(modWeights,4);ModRecolution8=卷积2dLayer(filterSize,numFilters,...“名字”layerName,“偏见”modBias,“重量”,modWeights);lgraph=替换层(lgraph,“卷积8”,模型8);

添加YOLO v2变换和输出层

YOLO v2检测网络需要YOLO v2转换层和YOLO v2输出层。创建这两个层,将它们串联堆叠,并将YOLO v2转换层连接到最后一个卷积层。

CLASSNAME=TinyyOlov2类;layersToAdd=[YOLOV2传输层(Numanchorboxs,“名字”“约洛夫2型转化”);yolov2OutputLayer (anchorBoxes“班级”一会,“名字”“yolov2Output”); ]; lgraph=添加层(lgraph,layersToAdd);lgraph=连接层(lgraph,layerName,“约洛夫2型转化”);

ElementwiseAffineLayer在导入的网络中复制所执行的预处理步骤yolov2ObjectDetector.因此,删除ElementwiseAffineLayer从导入的网络。

yoloScaleLayerIdx =找到(...arrayfun (@ (x) isa (x,'nnet.onnx.layer.ElementwiseAffineLayer'),...lgraph.Layers);如果~ isempty (yoloScaleLayerIdx)对于i=1:size(yoloScaleLayerIdx,1)layerNames{i}=lgraph.Layers(yoloScaleLayerIdx(i,1),1).Name;终止lgraph = removeLayers (lgraph layerNames);lgraph = connectLayers (lgraph,“Input_image”“卷积”);终止

创建YOLO v2对象检测器

使用assembleNetwork函数并使用yolov2ObjectDetector作用

净= assembleNetwork (lgraph)
net=DAG网络,具有以下属性:层:[34×1 nnet.cnn.layer.layer]连接:[33×2表]输入名称:{'Input_image'}输出名称:{'yolov2Output'}
yolov2Detector = yolov2ObjectDetector(净)
yolov2Detector = yolov2ObjectDetector with properties: ModelName: 'importedNetwork' Network: [1×1 DAGNetwork] TrainingImageSize: [416 416] AnchorBoxes: [5×2 double] ClassNames:[飞机自行车鸟船瓶子巴士汽车猫椅子牛餐台狗马摩托车人盆栽植物羊沙发火车电视监视器]

使用导入的YOLO v2探测器检测对象

使用导入的检测器检测测试图像中的对象。显示结果。

I=imread(“高速公路,巴布亚新几内亚”);%将图像转换为BGR格式。Ibgr=cat(3,I(:,:,3),I(:,:,2),I(:,:,1));[b框,分数,标签]=detect(yolov2Detector,Ibgr);detectedImg=insertObjectAnnotation(I,“矩形”bboxes,分数);图imshow (detectedImg);

金宝app支持功能

函数[modWeights, modBias] = rearrangeONNXWeights(重量、偏见、numAnchorBoxes)rearrangeONNXWeights重新排列导入YOLO的权重和偏差%yolov2ObjectDetector要求的v2网络。Numanchorboxs是标量%值,该值包含用于对权重和权重进行重新排序的定位数%的偏见。执行以下功能:% *提取与IoU、框和类相关的权重和偏差。% *按照yolov2ObjectDetector的预期对提取的权重和偏差重新排序。%*将它们组合并重塑为原始尺寸。weightsize=大小(权重);biasSize=大小(偏差);sizeOfPredictions=biasSize(3)/numanchorboxs;%根据预测和锚的大小重塑权重。reshapedWeights =重塑(重量、刺激(weightsSize (1:3)), sizeOfPredictions, numAnchorBoxes);%提取与IoU、框和类相关的权重。weightsIou = reshapedWeights (: 5:);1:4, weightsBoxes = reshapedWeights (::);weightsClasses = reshapedWeights(::, 6:结束);%按要求组合提取参数的权重% yolov2ObjectDetector。重新排序的重量=类别(2,重量,重量箱,重量等级);置换权重=置换(重新排序权重[1 3 2]);%将新权重重塑为原始大小。modWeights =重塑(permutedWeights weightsSize);重塑与预测和锚的大小有关的偏差。reshapedBias =重塑(偏见,sizeOfPredictions numAnchorBoxes);%提取与IoU、框和类相关的偏差。: biasIou = reshapedBias(5日);: biasBoxes = reshapedBias (1:4);biasClasses = reshapedBias(6:最后,);%根据Yolov2Object Detector的要求,组合提取参数的偏差。reorderedBias =猫(1 biasIou biasBoxes biasClasses);permutedBias = permute(reorderedBias,[2 1]);%将新的偏差重塑为原始大小。modBias =重塑(permutedBias biasSize);终止函数类= tinyYOLOv2Classes ()返回与预训练的ONNX微小YOLO v2对应的类名%网络。%微型YOLO v2网络在Pascal VOC数据集上进行预训练,%包含来自20个不同类的图像。类= [...“飞机”“自行车”“鸟”“船”“瓶子”“公共汽车”“汽车”...“猫”“椅子”“奶牛”“diningtable”“狗”“马”“摩托车”...“人”“盆栽植物”“羊”“沙发”“火车”“tvmonitor”];终止

参考文献

雷蒙德,约瑟夫和阿里·法哈迪。“YOLO9000:更好、更快、更强。”2017 IEEE计算机视觉与模式识别会议(CVPR), 6517-25。火奴鲁鲁,HI: IEEE, 2017。https://doi.org/10.1109/CVPR.2017.690。

[2] “微型YOLO v2型号。”https://github.com/onnx/models/tree/master/vision/object_detection_segmentation/tiny-yolov2

[3] “Tiny YOLO v2型号许可证。”https://github.com/onnx/onnx/blob/master/LICENSE

Everingham, Mark, Luc Van Gool, Christopher K. I. Williams, John Winn和Andrew Zisserman。“Pascal视觉对象类(VOC)挑战”。计算机工程与应用,2018,(5):514 - 514。2(2010年6月):303-38。https://doi.org/10.1007/s11263 - 009 - 0275 - 4。

[5]“yolov2-tiny-voc.cfg”https://github.com/pjreddie/darknet/blob/master/cfg/yolov2-tiny-voc.cfg