自动驾驶之-MATLAB环境下基于深度学习的目标检测(停车标志检测)

发布于:2022-11-29 ⋅ 阅读:(204) ⋅ 点赞:(0)

深度学习,一个大号的,现代的,黑箱的,信号/图像处理器,本文程序运行环境为MATLAB R2018A。

本文简要讲解如何使用深度学习(R-CNN网络)来训练一个停车标志检测器。R-CNN是一种目标检测框架,使用卷积神经网络(CNN)对图像中的区域进行分类。R-CNN 目标检测器不使用滑动窗口对每个区域进行分类,而是仅处理可能包含目标的区域,因此降低了CNN 的计算成本。为了说明如何训练 R-CNN 停车标志检测器,本文使用迁移学习方法,因此预训练的网络已经学习到了丰富的图像特征,只需要对权重进行小幅调整来微调网络。

迁移学习的优点是减少了训练所需的图像数量和训练时间。首先,使用CIFAR-10数据集对CNN进行预训练,该数据集具有50,000张训练图像。然后,仅使用41个训练图像对预训练的CNN进行微调以进行停车标志检测。如果不预先训练CNN,训练停车标志检测器将需要更多的图像。

注意:本例需要计算机视觉工具箱、图像处理工具箱、神经网络工具箱以及统计和机器学习工具箱。

下载CIFAR-10图像数据

下载CIFAR-10数据集,数据集包含 50,000 张图像。每个图像是一个 32x32 RGB的图像

加载CIFAR-10训练数据和测试数据

[trainingImages,trainingLabels,testImages,testLabels] = helperCIFAR10Data.load(cifar10Data);
size(trainingImages)

ans = 1×4

          32          32           3       50000

CIFAR-10有10个图像类别

numImageCategories = 10;
categories(trainingLabels)

ans = 10x1 cell array

{'airplane' }

{'automobile'}

{'bird' }

{'cat' }

{'deer' }

{'dog' }

{'frog' }

{'horse' }

{'ship' }

{'truck' }

展示部分训练图片

figure
thumbnails = trainingImages(:,:,:,1:100);
montage(thumbnails)

创建卷积神经网络 (CNN)

CNN 由一系列层组成,其中每层定义一个特定的计算。神经网络工具箱提供了逐层设计 CNN 的功能,在本文中,用到了以下层:

· imageInputLayer - Image input layer

· convolutional2dLayer - 2D convolution layer for Convolutional Neural Networks

· reluLayer - Rectified linear unit (ReLU) layer

· maxPooling2dLayer - Max pooling layer

· fullyConnectedLayer - Fully connected layer

· softmaxLayer - Softmax layer

· classificationLayer - Classification output layer for a neural network

为 32x32x3的CIFAR-10图像创建输入层

[height, width, numChannels, ~] = size(trainingImages);
imageSize = [height width numChannels];
inputLayer = imageInputLayer(imageSize)

接下来定义网络的中间层。中间层由卷积、ReLU(整流线性单元)和池化层的重复块组成,这3层构成了卷积神经网络的核心构建块。卷积层定义了滤波器的权重,这些权重在网络训练过程中进行更新。ReLU层为网络添加了非线性,使网络可以近似非线性函数,将图像像素映射到图像的语义内容。池化层对数据进行下采样。在多层网络中,应谨慎使用池化层,避免在网络中过早地对数据进行下采样。

卷积层参数

filterSize = [5 5];
numFilters = 32;
middleLayers = [
 
%第一个卷积层有32个5x5x3大小的滤波器
convolution2dLayer(filterSize, numFilters, 'Padding', 2)
% 添加ReLU层:
reluLayer()
% 接下来是具有3x3空间池化区域的最大池化图层,这将对数据进行下采样:从32x32降维到15x15。
maxPooling2dLayer(3, 'Stride', 2)
% 重复3个核心层,完成网络的中间部分
convolution2dLayer(filterSize, numFilters, 'Padding', 2)
reluLayer()
maxPooling2dLayer(3, 'Stride',2)
convolution2dLayer(filterSize, 2 * numFilters, 'Padding', 2)
reluLayer()
maxPooling2dLayer(3, 'Stride',2)
]

middleLayers =

9x1 Layer array with layers:

1 '' Convolution 32 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

2 '' ReLU ReLU

3 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

4 '' Convolution 32 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

5 '' ReLU ReLU

6 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

7 '' Convolution 64 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

8 '' ReLU ReLU

9 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

可通过重复这3个基本层来创建更深层次的网络。但是,应减少池化层的数量,以避免过早地对数据进行下采样,在网络早期进行下采样会丢失有用的图像信息。

CNN的最后一层通常由全连接层和softmax层组成。

finalLayers = [
 
%添加一个包含64个输出神经元的全连接层
fullyConnectedLayer(64)
% 添加ReLU层
reluLayer
% 添加最后一个全连接层
fullyConnectedLayer(numImageCategories)
%添加softmax 层和分类层
softmaxLayer
classificationLayer
]

finalLayers =

5x1 Layer array with layers:

1 '' Fully Connected 64 fully connected layer

2 '' ReLU ReLU

3 '' Fully Connected 10 fully connected layer

4 '' Softmax softmax

5 '' Classification Output crossentropyex

将输入层、中间层和最终层组合起来

layers = [
 inputLayer
 middleLayers
 finalLayers
 ]

layers =

15x1 Layer array with layers:

1 '' Image Input 32x32x3 images with 'zerocenter' normalization

2 '' Convolution 32 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

3 '' ReLU ReLU

4 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

5 '' Convolution 32 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

6 '' ReLU ReLU

7 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

8 '' Convolution 64 5x5 convolutions with stride [1 1] and padding [2 2 2 2]

9 '' ReLU ReLU

10 '' Max Pooling 3x3 max pooling with stride [2 2] and padding [0 0 0 0]

11 '' Fully Connected 64 fully connected layer

12 '' ReLU ReLU

13 '' Fully Connected 10 fully connected layer

14 '' Softmax softmax

15 '' Classification Output crossentropyex

初始化卷积层权重

layers(2).Weights = 0.0001 * randn([filterSize numChannels numFilters]);

使用 CIFAR-10 数据训练 CNN

现在定义了网络架构,可以使用 CIFAR-10 训练数据对其进行训练。首先,使用 trainingOptions函数设置网络训练算法。网络训练使用随机梯度下降与动量 (SGDM)算法,初始学习率为 0.001。在训练期间,初始学习速率每 8 个 epoch 降低一次,共运行 40 个 epoch。

注意:训练算法使用 128 个图像的mini-batch,如果使用 GPU 进行训练,由于 GPU 上的内存限制,可能需要减小mini-batch大小。

设置网络训练参数

opts = trainingOptions('sgdm', ...
 'Momentum', 0.9, ...
 'InitialLearnRate', 0.001, ...
 'LearnRateSchedule', 'piecewise', ...
 'LearnRateDropFactor', 0.1, ...
 'LearnRateDropPeriod', 8, ...
 'L2Regularization', 0.004, ...
 'MaxEpochs', 40, ...
 'MiniBatchSize', 128, ...
 'Verbose', true);

使用 trainNetwork函数训练网络

 cifar10Net = trainNetwork(trainingImages, trainingLabels, layers, opts);

验证 CIFAR-10 网络

在网络训练完成后,进行验证以确保训练成功。首先,可视化第一个卷积层的滤波器权重

第一层权重应具有一些明确定义的结构,如果权重看起来仍然是随机的,则表明网络可能需要额外的训练。如上图所示,第一层滤波器已从 CIFAR-10 训练数据中学习到边缘特征。现在使用 CIFAR-10 测试数据来测试网络的分类精度。

YTest = classify(cifar10Net, testImages);

计算准确率

accuracy = sum(YTest == testLabels)/numel(testLabels)

accuracy = 0.7456

加载训练数据

现在网络在CIFAR-10分类任务中运行良好,可以使用迁移学习方法来微调网络以进行停车标志检测。

首先加载停车标志的ground truth数据。

关于ground truth,ground truth是摄影、测量与遥感学领域常用词汇,其解释就是字面意思:地面真值,地面实况;延伸到图像处理、机器学习等其他领域一般表示真实值,正确答案(或正确测量数据)。它是一个正确的基准值,一般用来进行误差估算和效果评价。

加载ground truth数据

data = load('stopSignsAndCars.mat', 'stopSignsAndCars');
stopSignsAndCars = data.stopSignsAndCars;

更新图像文件的路径

visiondata = fullfile(toolboxdir('vision'),'visiondata');
stopSignsAndCars.imageFilename = fullfile(visiondata, stopSignsAndCars.imageFilename);
summary(stopSignsAndCars)

Variables:

imageFilename: 41x1 cell array of character vectors

stopSign: 41x1 cell

carRear: 41x1 cell

carFront: 41x1 cell

训练数据包含在一个表中,该表包含停车标志、车前和后方的图像文件名和 ROI 标签。每个 ROI 标签都是图像中感兴趣目标周围的边界框。为了训练停车标志检测器,只需要停车标志ROI标签,必须移除汽车前部和后部的 ROI 标签:

仅保留图像文件名和停车标志ROI标签

stopSigns = stopSignsAndCars(:, {'imageFilename','stopSign'});

显示一个训练图像和ground truth边界框

I = imread(stopSigns.imageFilename{1});
I = insertObjectAnnotation(I,'Rectangle',stopSigns.stopSign{1},'stop sign','LineWidth',8);
figure
imshow(I)

注意:此数据集中只有 41 个训练图像,仅使用41张图像从头开始训练R-CNN目标检测器是不切实际的,由于停车标志检测器是通过微调在较大数据集上预训练的网络(CIFAR-10 具有 50000 个训练图像)来训练的,因此使用小得多的数据集是较为可行的。

训练R-CNN 停车标志检测器

最后,使用 trainRCNNObjectDetector 函数训练 R-CNN 目标检测器,输入是ground truth表,包含标记的停车标志图像、预训练的 CIFAR-10 网络和训练参数,训练函数会自动将CIFAR-10 网络(10 类)修改为可将图像分类为 2 类的网络:停车标志和背景。

设置训练参数

 options = trainingOptions('sgdm', ...
 'MiniBatchSize', 128, ...
 'InitialLearnRate', 1e-3, ...
 'LearnRateSchedule', 'piecewise', ...
 'LearnRateDropFactor', 0.1, ...
 'LearnRateDropPeriod', 100, ...
 'MaxEpochs', 100, ...
 'Verbose', true);

训练R-CNN目标检测器

 rcnn = trainRCNNObjectDetector(stopSigns, cifar10Net, options, ...
 'NegativeOverlapRange', [0 0.3], 'PositiveOverlapRange',[0.5 1])

测试R-CNN停车标志检测器

读取测试图像

testImage = imread('stopSignTest.jpg');

检测停车标志

[bboxes,score,label] = detect(rcnn,testImage,'MiniBatchSize',128)

detect 函数返目标边界框、检测分数和类别标签,分数范围介于 0 和 1 之间,表示检测的置信度

显示检测结果

[score, idx] = max(score);
bbox = bboxes(idx, :);
annotation = sprintf('%s: (Confidence = %f)', label(idx), score);
outputImage = insertObjectAnnotation(testImage, 'rectangle', bbox, annotation);
figure
imshow(outputImage)

R-CNN检测器中使用的网络也可用于处理整个测试图像

经过训练的网络存储在 R-CNN 检测器中

rcnn.Network

ans =

SeriesNetwork with properties:

Layers: [15x1 nnet.cnn.layer.Layer]

从softmax层中提取激活值

featureMap = activations(rcnn.Network, testImage, 'softmax');

softmax激活值存储在3-D数组中

size(featureMap)

ans = 1×3

43 78 2

第3个维度对应于目标类别

rcnn.ClassNames

ans = 2x1 cell array

{'stopSign' }

{'Background'}

停车标志特征图存储在第一个通道中

stopSignMap = featureMap(:, :, 1);

由于网络中的下采样操作,激活输出的大小小于输入图像,要生成更好的可视化结果,将 stopSignMap 的大小调整为输入图像的大小。

调整stopSignMap大小便于可视化

[height, width, ~] = size(testImage);
stopSignMap = imresize(stopSignMap, [height, width]);

最后可视化特征图

figure
imshow(featureMapOnImage)

测试图像中的停车标志与网络激活中的最大峰值对应,这有助于验证 R-CNN 检测器中使用的 CNN 是否学会了识别停车标志。如果有其他峰值,表明训练需要额外的数据来帮助防止误报

代码

🍞正在为您运送作品详情

本文含有隐藏内容,请 开通VIP 后查看