主要内容

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

深度学习是一种强大的机器学习技术,您可以使用它来训练强健的目标检测器。存在几种目标检测技术,包括更快的R-CNN和you only look only one(YOLO)v2。

通过使用工作流程对象。

加载数据集

本例使用了一个包含295幅图像的小型车辆数据集。其中许多图像来自加州理工大学1999年和2001年的数据集,经许可使用,可在加州理工大学计算机视觉中心获得网站,由Pietro Perona创建。每个图像包含一个或两个标记的车辆实例。一个小数据集对于探索YLO v2培训程序非常有用,但在实践中,需要更多标记的图像来培训鲁棒检测器。提取车辆图像并加载车辆地面真实数据。

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

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

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

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

rng (0);shuffledIndices = randperm(高度(vehicleDataset));idx = floor(0.6 * length(shuffledIndices));trainingDataTbl = vehicleDataset (shuffledIndices (1: idx):);testDataTbl = vehicleDataset (shuffledIndices (idx + 1:结束):);

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

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特有的层组成。

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

  • 网络输入大小

  • 锚箱

  • 特征提取网络

首先,指定网络输入的大小和类的数目。在选择网络输入大小时,考虑网络本身所需的最小大小、训练图像的大小以及处理所选大小的数据所产生的计算成本。当可行时,选择与TR大小接近的网络输入大小。正在生成映像,并且大于网络所需的输入大小。若要减少运行示例的计算成本,请指定224-x-224-x-3的网络输入大小,这是运行网络所需的最小大小。

inputSize=[2242243];

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

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

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

接下来,使用estimateAnchorBoxes函数根据训练数据中对象的大小估计锚盒。为了考虑在训练前调整图像的大小,调整用于估计锚盒的训练数据的大小。使用变换函数对训练数据进行预处理,然后定义锚定框的数量并估计锚定框。使用支持函数将训练数据调整为网络的输入图像大小万博1manbetxyolo_preprocessData,附加到本例中。

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

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

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

featureExtractionNetwork = alexnet
featureExtractionNetwork=具有以下属性的系列网络:层:[25×1 nnet.cnn.layer.layer]输入名称:{'data'}输出名称:{'output'}

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

featureLayer =“relu5”

创建YOLO v2对象检测网络。

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

您可以使用分析网络功能或深度学习工具箱™中的深度网络设计器。

如果需要对YOLO v2网络体系结构进行更多控制,请使用Deep network Designer手动设计YOLO v2检测网络。有关更多信息,请参阅设计了一个yolov2检测网络(计算机视觉工具箱)。

数据增加

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

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

augmentedTrainingData =变换(trainingData @yolo_augmentData);

预处理训练数据,训练YOLO v2对象检测器

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

preprocessedTrainingData =变换(augmentedTrainingData @(数据)yolo_preprocessData(数据、inputSize));

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

选择= trainingOptions (“sgdm”...“MiniBatchSize”, 16,...“初始学习率”1 e - 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 = insertObjectAnnotation(我“矩形”bboxes,分数);图imshow (I_new)

负载Pretrained网络

加载预训练网络。

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

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

analyzeNetwork (snet)

创建目标对象

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

hTarget = dlhdl。目标(“Xilinx”“界面”“以太网”);

创建工作流对象

对象的对象工作流程类。指定网络和位流名称。指定保存的预训练序列网络trainedNetNoCar作为网络。确保比特流名称与数据类型和目标FPGA板匹配。在本例中,目标FPGA板是Zynq UltraScale+MPSoC ZCU102板。比特流使用单一数据类型。

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

编译yolov2对象检测器

编撰snet系列网络,运行编译功能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硬件上部署网络,请运行工作流程对象。该函数使用compile函数的输出,利用编程文件对FPGA板进行编程。该函数还可以下载网络权重和偏差。deploy函数检查Xilinx Vivado工具和支持的工具版本。万博1manbetx然后,它开始使用位流对FPGA设备进行编程,并显示进度消息和部署网络所需的时间。

hW.deploy
### FPGA位流编程已经被跳过,因为相同的位流已经加载到目标FPGA上。###加载权值到Conv处理器。### Conv权重加载。现在时间是2020年12月20日15:26:28

加载示例图像和运行预测

在上执行预测函数工作流程对象并显示结果。

[预测,速度]=硬件预测(I_pre,“配置文件”“开”);
###完成写入输入激活。###运行单输入激活。Deep Learning Processor Profiler Performance Results LastFrameLatency(cycles) LastFrameLatency(seconds) FramesNum Total Latency Frames/s ------------- ------------- --------- --------- --------- Network 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 pool2197444 0.00090 conv3 976419 0.00444 conv4 761188 0.00346 conv5 521782 0.00237 yolov2Conv1 660213 0.00300 yolov2Conv2 661162 0.00301 yolov2ClassConv 136816 0.00062 * DL处理器的时钟频率为:220MHz

显示预测结果。

[bboxesn, scoresn, labelsn] = yolo_post_proc(预测,I_pre,锚盒,{)“汽车”}); I_new3=插入对象注释(I,“矩形”、bboxesn scoresn);图imshow (I_new3)