主要内容

使用部署到FPGA的YOLO v2进行车辆检测

深度学习是一种强大的机器学习技术,可以用来训练健壮的目标探测器。有几种目标检测技术,包括Faster R-CNN和you only look once (YOLO) v2。

方法训练和部署一个只看一次(YOLO) v2对象检测器dlhdl.Workflow对象。

加载数据集

本例使用一个包含295张图像的小型车辆数据集。这些图像中有许多来自加州理工学院1999年和2001年的汽车数据集,这些数据集在加州理工学院计算视觉学院获得许可使用网站,由Pietro Perona创作。每个图像包含一个或两个已标记的车辆实例。一个小的数据集对于探索YOLO v2训练过程很有用,但在实践中,需要更多标记的图像来训练健壮的检测器。提取车辆图像,加载车辆地面真实数据。

解压vehicleDatasetImages.zipdata =负载(“vehicleDatasetGroundTruth.mat”);vehicleDataset = data.vehicleDataset;

车辆数据存储在两列表格中,其中第一列包含图像文件路径,第二列包含车辆边界框。

%将完整路径添加到本地车辆数据文件夹。vehicleDataset.imageFilename=fullfile(pwd,vehicleDataset.imageFilename);

将数据集分为训练集和测试集。选择60%的数据进行训练,其余数据用于测试经过训练的探测器。

rng(0);ShuffledDices=randperm(高度(车辆数据集));idx=地板(0.6*长度(ShuffledDices));trainingDataTbl=车辆数据集(ShuffledDices(1:idx),:);testDataTbl=车辆数据集(ShuffledDices(idx+1:end),:);

使用imageDatastoreBoxlabeldata商店创建用于在训练和评估期间加载图像和标签数据的数据存储。

imdsTrain = imageDatastore (trainingDataTbl {:,“imageFilename”});bldsTrain = boxLabelDatastore (trainingDataTbl (:,“汽车”));imdsTest = imageDatastore (testDataTbl {:,“imageFilename”});bldsTest = boxLabelDatastore (testDataTbl (:,“汽车”));

组合图像和框标签数据存储。

训练数据=联合收割机(imdsTrain,bldsTrain);测试数据=联合收割机(imdsTest,bldsTest);

创建YOLO v2对象检测网络

YOLO v2对象检测网络由特征提取网络和检测网络两个子网组成。特征提取网络通常是预先训练好的CNN(详情请参见预先训练的深度神经网络).本例使用AlexNet进行特征提取。您还可以使用其他预先训练过的网络,如MobileNet v2或ResNet-18,也可以根据应用程序需求使用。与特征提取网络相比,检测子网络是一个较小的CNN,由几个卷积层和针对YOLO v2的层组成。

使用约洛夫2层功能,创建YOLO v2对象检测网络。的约洛夫2层函数要求您指定几个参数化YOLO v2网络的输入:

  • 网络输入大小

  • 锚箱

  • 特征提取网络

首先,指定网络输入大小和类的数量。在选择网络输入尺寸时,考虑网络本身所需要的最小尺寸、训练图像的尺寸以及在所选尺寸下处理数据所需要的计算代价。在可行的情况下,选择一个与训练图像尺寸相近且大于网络所需输入尺寸的网络输入尺寸。为了减少运行示例的计算成本,指定网络输入大小为224 × 224 × 3,这是运行网络所需的最小大小。

inputSize=[2242243];

定义要检测的对象类的数量。

numClasses=宽度(车辆数据集)-1;

本例中使用的训练图像大于224 x 224,大小不一,因此必须在训练前的预处理步骤中调整图像大小。

接下来,使用估计锚箱函数用于根据训练数据中对象的大小估计锚定框。若要考虑训练前图像的大小调整,请调整训练数据的大小以估计锚定框。使用变换函数对训练数据进行预处理,然后定义锚盒的数量并对锚盒进行估计。利用支持函数将训练数据调整为网络的输入图像大小金宝appyolo_preprocessData,附于本示例。

有关选择锚定框的详细信息,请参见根据训练数据估计锚盒计算机视觉工具箱™) 和用于目标检测的锚盒(计算机视觉工具箱)。

trainingDataForEstimation =变换(trainingData @(数据)yolo_preprocessData(数据、inputSize));numAnchors = 7;[anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingdatafestimation, numAnchors)
anchorBoxes =7×2145 126 91 86 161 132 41 34 67 64 136 111 33 23
平均IOU=0.8651

使用alexnet函数加载预训练模型。

featureExtractionNetwork = alexnet
feature extracactionnetwork = SeriesNetwork with properties: Layers: [25×1 net.cnn.layer. layer] InputNames: {'data'} OutputNames: {'output'}

选择“relu5”作为特征提取层,代替后的各层“relu5”与检测子网一起。该特征提取层输出特征图,该特征图的下采样系数为16。该下采样量是空间分辨率和提取特征强度之间的良好折衷,因为在网络下游提取的特征以空间分辨率为代价编码更强的图像特征离子。

featureLayer =“relu5”;

创建YOLO v2对象检测网络

lgraph=yolov2Layers(输入大小、numclass、锚箱、featureExtractionNetwork、featureLayer);

您可以使用analyzeNetwork函数或深度学习工具箱中的深度网络设计器™.

如果您需要对YOLO v2的网络架构有更多的控制,可以使用“Deep network Designer”手工设计YOLO v2的检测网络。有关更多信息,请参见设计YOLO v2检测网络(计算机视觉工具箱)。

数据扩充

在训练过程中,通过随机变换原始数据来提高网络的精度。通过使用数据增广,您可以向训练数据添加更多的种类,而不必实际增加已标记训练样本的数量。

使用变换通过随机水平翻转图像和相关框标签来增加训练数据的函数。请注意,数据增加不应用于测试和验证数据。理想情况下,测试和验证数据代表原始数据,不进行修改以进行无偏评估。

augmentedTrainingData=转换(trainingData,@yolo_augmentData);

预处理训练数据并训练YOLO v2目标检测器

对增强后的训练数据和验证数据进行预处理,为训练做好准备。

预处理训练数据=转换(增强训练数据,@(数据)yolo_预处理数据(数据,输入大小));

使用trainingOptions用于指定网络培训选项的函数。设置“验证数据”到预处理的验证数据。设置“检查点路径”到一个临时地点。这些设置可在培训过程中保存部分培训的探测器。如果培训被中断,例如断电或系统故障,您可以从保存的检查点恢复培训。

选择= trainingOptions (“个”,...“MiniBatchSize”, 16岁,....“InitialLearnRate”,1e-3,...“MaxEpochs”,20,...“检查点路径”tempdir,...“洗牌”,“从来没有”);

使用Trainyolov2oObject检测器功能,培训YOLO v2对象检测器。

[探测器,信息]= trainYOLOv2ObjectDetector (preprocessedTrainingData、lgraph选项);
************************************************************************* 培训YOLO v2意思对象探测器以下对象类:*车辆培训单CPU。初始化输入数据规范化。|========================================================================================| | 时代| |迭代时间| Mini-batch | Mini-batch |基地学习  | | | | ( hh: mm: ss) | RMSE | |率损失  | |========================================================================================| | 1 | 1 | 00:00:02 | 7.23 | 52.3 | 0.0010 | | 5 |50 | 00:00:43 | 0.99 | 1.0 | 0.0010 | | 10 | 100 | 00:01:24 | 0.77 | 0.6 | 0.0010 | | 14 | 150 | 00:02:03 | 0.64 | 0.4 | 0.0010 | | 19 | 200 | 00:02:41 | 0.57 | 0.3 | 0.0010 | | 20 | 220 | 00:02:55 | 0.58 | 0.3 | 0.0010 | |========================================================================================| Detector training complete. *************************************************************************

作为快速测试,在一个测试图像上运行检测器。确保将图像大小调整为与训练图像相同的大小。

我= imread (testDataTbl.imageFilename {2});我= imresize(我inputSize (1:2));[bboxes,分数]=检测(探测器,I);

显示结果。

I_new=插入对象注释(I,“矩形”bboxes,分数);图imshow (I_new)

负载Pretrained网络

加载预训练网络。

snet = detector.Network;I_pre = yolo_pre_proc(我);

使用analyzeNetwork函数获取有关网络层的信息。

分析网络(snet)

创建目标对象

为您的目标设备创建一个带有供应商名称的目标对象和一个将目标设备连接到主机的接口。接口选项为JTAG(默认)和Ethernet。供应商选项有Intel或Xilinx。通过以太网连接使用已安装的Xilinx Vivado Design Suite对设备进行编程。

hTarget=dlhdl.Target(“Xilinx”,“界面”,“以太网”);

创建工作流对象

创建的对象dlhdl.Workflow类。指定网络和位流名称。指定保存的预训练系列网络trainedNetNoCar随着网络。确保位流名称与目标的数据类型和FPGA板匹配。在本例中,目标FPGA板为Zynq UltraScale+ MPSoC ZCU102板。位流使用单一数据类型。

hW = dlhdl。工作流(“网络”,snet,“比特流”,“zcu102_single”,“目标”hTarget)
hW =带有属性的工作流:Network: [1×1 DAGNetwork] Bitstream: 'zcu102_single' ProcessorConfig: [] Target: [1×1 dlhdl. hW = []目标]

编译YOLO v2对象检测器

来编译斯奈特系列网络,运行编译功能dlhdl.Workflow对象。

dn=hW.compile
###编译用于深入学习FPGA原型的网络…####针对FPGA比特流zcu102#单…###该网络包括以下几层:1“数据”图像输入224×224×3图像与“零中心”归一化(软件层)2“conv1”卷积96 11×11×3卷积与步幅[4]和填充[0 0 0 0 0](硬件层)3“relu1”ReLU ReLU(硬件层)4'norm1'跨通道规格化跨通道规格化每个元素5个通道(硬件层)5'pool1'最大池3×3最大池带跨步[2]和填充[0 0 0 0](硬件层)6'conv2'分组卷积2组128个5×5×48卷积带跨步[1]和填充[2 2 2 2 2 2](硬件层)7'relu2'ReLU ReLU ReLU(硬件层)8'norm2'跨通道规格化跨通道规格化每个元素5个通道(硬件层)9'pool2'最大池3×3最大池带跨步[2]和填充[0 0 0 0](硬件层)10'conv3'卷积384 3×3×256卷积带跨步[1 1]和填充[1 1 1 1 1](硬件层)11'relu3'ReLU ReLU(硬件层)12‘conv4’分组卷积2组192 3×3×192卷积,带跨步[11]和填充[11](硬件层)13‘relu4’ReLU ReLU(硬件层)14‘conv5’分组卷积2组128 3×3×192卷积,带跨步[11]和填充[11](硬件层)15‘relu5’ReLU ReLU(硬件层)16“yolov2Conv1”卷积256 3×3×256卷积带跨步[1]和填充“相同”(硬件层)17“yolov2Batch1”批量归一化带256个通道(硬件层)18“yolov2Relu1”ReLU ReLU(硬件层)19“yolov2Conv2”卷积256 3×3×256卷积带跨步[1]和填充“相同”(硬件层)20“yolov2Batch2”批次标准化批次标准化带有256个通道(硬件层)21“yolov2Relu2”ReLU ReLU(硬件层)22“yolov2ClassConv”卷积42 1×1×256卷积带跨距[1]和填充[0 0 0 0 0 0](硬件层)23“yolov2Transform”YOLO v2转换层。YOLO v2变换层,带有7个锚。(SW层)24'yolov2OutputLayer'YOLO v2输出带有7个锚的YOLO v2输出。(软件层)####优化系列网络:将“nnet.cnn.Layer.BatchNormalizationLayer”融合为“nnet.cnn.Layer.Convolution2DLayer”创建的2个内存区域。跳过:数据编译段:conv1>>yolov2ClassConv。。。编译leg:conv1>>yolov2ClassConv。。。完成跳过:yolov2Transform跳过:yolov2OutputLayer创建计划。。。。。。正在创建计划…完成。正在创建状态表。。。。。正在创建状态表…完成。排放时间表。。。。。我的时间表…完成了。发射状态表。。。。。。。发射状态表…已完成分配外部内存缓冲:偏移量(名称)名称名称偏移量(U)地址地址地址地址地址地址地址地址分配的地址地址地址地址地址地址地址地址分配分配的空间空间(地址)地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址,地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址,地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址地址偏移量“0x03800000”“4.0 MB”“ConvWeightDataOffset”“0x03c00000”“16.0 MB”“EndOffset”“0x04c00000”“总计:76.0 MB”“网络编译完成。
dn=结构体字段:权重:[1×1结构]指令:[1×1结构]寄存器:[1×1结构]同步指令:[1×1结构]

在FPGA上编程Bitstream并下载网络权重

要在Zynq®UltraScale+™MPSoC ZCU102硬件上部署网络,请运行dlhdl.Workflow对象。此函数使用编译函数的输出,使用编程文件对FPGA板进行编程。此函数还下载网络权重和偏差。部署函数检查Xilinx Vivado工具和支持的工具版本。然后使用位流开始对FPGA设备进行编程,并显示progress消息以及部署网络所需的时间。金宝app

hW.deploy
###已跳过FPGA位流编程,因为相同的位流已加载到目标FPGA上。###########加载Conv权重。当前时间为2020年12月20日15:26:28

加载示例图像和运行预测

在上执行predict函数dlhdl.Workflow对象并显示结果。

[预测,速度]=硬件预测(I_pre,“个人资料”,“上”);
###已完成输入激活的编写。####运行单输入激活。深度学习处理器探查器性能结果LastFrameLatency(周期)LastFrameLatency(秒)FRAMESUM总延迟帧数/秒------------------------------网络8615567 0.03916 1 8615567 25.5 conv1 1357049 0.00617 norm1 569406 0.00259 pool1 205869 0.00094 conv2 2207222 0.01003 norm2 360973 0.00164 pool2 197444 0.00090 conv3 976419 0.00444 conv4 761188 0.00346 conv5 521782 0.00237 YOLV2CONV1 660213 0.00300yolov2Conv2 661162 0.00301 yolov2ClassConv 136816 0.00062*DL处理器的时钟频率为:220MHz

显示预测结果。

[bboxesn,scoresn,labelsn]=yolo_post_proc(预测,I_pre,主播{“汽车”});I_new3 = insertObjectAnnotation(我“矩形”,bboxesn,scoresn);图imshow(I_new3)