对196种车型分类

转自:

http://blog.csdn.net/Mr_Curry/article/details/53160914?locationNum=4&fps=1
http://blog.csdn.net/mr_curry/article/details/53286562


利用Matlab自带的深度学习工具进行车辆区域检测与车型识别【福利-内附源码与数据库】(一)


前言

Okay……最近事情比较多,博客也发的少,所以决定搞一次大新闻。本此的博客详细记录了我使用Matlab进行车辆区域检测(R-CNN)与车型识别(AlexNet)的过程。并且内包含了训练数据集、测试数据集以及源码。 
训练数据集是使用的斯坦福大学的一个车型数据库,内含196种不同的车型。写到这里我真的很想吐槽一下这个数据库里面的奥迪车系:很多黑白的图片啊喂!!! 做训练的时候AlexNet数据输入维度是3啊喂!!!害的我自己找了很多图片啊!!!….

环境

测试环境: 
硬件: 
Intel i5-4590 
GTX 980 
软件: 
Matlab R2016b(只有这个版本才实现了RCNN…)

数据集的下载

嗯。一上来就发福利: 
原始数据集,内含train/test:http://pan.baidu.com/s/1miTn9jy 
我规整后的数据集,将图片变换为227*227,并且对少量黑白图片进行了替换:http://pan.baidu.com/s/1pKIbQiB 
接下来的这个是每一张图片所对应的车型标注文件:http://pan.baidu.com/s/1nuOR7PR

在Matlab中下载AlexNet

AlexNet是2012年ImageNet大赛的冠军。它一共有8层,其中了5个卷积层,2层全连接和一层分类,如果使用其对一张图片进行前向传播,那么最后输出的这张图片属于1000种物体中哪一个的概率。 
我这里对AlexNet在Matlab中进行了定义,这是我的代码和网络结构:

function [AlexLayer,opts]=MakeAlexLayer
inputLayer = imageInputLayer([227 227 3],'Name','Input');

middleLayers = [
convolution2dLayer([11 11], 96,'NumChannels',3,'Stride',4,'Name','conv1','Padding',0)
reluLayer('Name','relu1')
crossChannelNormalizationLayer(5,'Name','norm1')
maxPooling2dLayer(3, 'Stride', 2,'Name','pool1','Padding',0)

convolution2dLayer([5 5], 256, 'NumChannels',48,'Padding', 2,'Name','conv2','Stride',1)
reluLayer('Name','relu2')
crossChannelNormalizationLayer(5,'Name','norm2')
maxPooling2dLayer(3, 'Stride',2,'Name','pool2','Padding',0)

convolution2dLayer([3 3], 384, 'NumChannels',256,'Padding', 1,'Name','conv3','Stride',1)
reluLayer('Name','relu3')

convolution2dLayer([3 3], 384,'NumChannels',192, 'Padding', 1,'Name','conv4','Stride',1)
reluLayer('Name','relu4')

convolution2dLayer([3 3], 256, 'NumChannels',192,'Padding', 1,'Name','conv5','Stride',1)
reluLayer('Name','relu5')
maxPooling2dLayer(3, 'Stride',2,'Name','pool5','Padding',0)
];

finalLayers = [
fullyConnectedLayer(4096,'Name','fc6')
reluLayer('Name','relu6')
%caffe中有这一层
dropoutLayer(0.5,'Name','dropout6')

fullyConnectedLayer(4096,'Name','fc7')
reluLayer('Name','relu7')
%caffe中有这一层
dropoutLayer(0.5,'Name','dropout7')

%196种车
fullyConnectedLayer(196,'Name','fc8')
softmaxLayer('Name','softmax')
classificationLayer('Name','classification')
];

AlexLayer=[inputLayer
    middleLayers
    finalLayers];

opts = trainingOptions('sgdm', ...
    'Momentum', 0.9, ...
    'InitialLearnRate', 0.001, ...
    'LearnRateSchedule', 'piecewise', ...
    'MaxEpochs', 500, ...
    'MiniBatchSize', 100, ...
    'Verbose', true);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

由于数据库太小,loss一直比较高。所以我们还是在网上下载一下人家训练好的网络来微调吧(逃 
地址:http://www.vlfeat.org/matconvnet/models/beta16/

对AlexNet进行Finetune

首先读入这个AlexNet:

AlexNet=helperImportMatConvNet('AlexLayerFromWeb.mat');
  • 1

观察其网络结构:

AlexNet.Layers
  • 1

对196种车型分类_第1张图片
我们要对其进行微调,那么其实前面的卷积层都不用改,要改的就是最后的一个全连接层,要把它改成我们的层。由于车型一共是196种,所以全连接的输出也得改成196,后面再接上一个softmax层和一个classificationLayer,并且定义训练方式:

function [AlexLayer_New , optionsTransfer]=FineTune(AlexNet)
AlexNet_reduce = AlexNet.Layers(1:end-3);
%add
Last3Layers = [
fullyConnectedLayer(196,'Name','fc8','WeightLearnRateFactor',10, 'BiasLearnRateFactor',20)
softmaxLayer('Name','softmax')
classificationLayer('Name','classification')
];
AlexLayer_New=[AlexNet_reduce
    Last3Layers];

optionsTransfer = trainingOptions('sgdm',...
         'MaxEpochs',10,...
         'InitialLearnRate',0.0005,...
         'Verbose',true,'MiniBatchSize', 100);%MiniBatchSize根据显卡内存而定
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

运行:

[AlexLayer_New , optionsTransfer]=FineTune(AlexNet)
  • 1

得到新的网络层级: 
对196种车型分类_第2张图片
Okay,现在我们要开始准备数据了。有两个方式,可以直接下载我的traindata.mat,并且按照里面的路径来放一下cars_train这个文件夹。那么我们就直接可以:

load('traindata.mat')
  • 1

第二种方式,稍微复杂一点。打开我更改后的数据集,自己来做imageDatastore容器。首先解压cars_train_croped(227_227)这个文件夹,然后在Matlab中写入:

traindata=imageDatastore('cars_train_croped(227_227)/','LabelSource','none')
  • 1

对196种车型分类_第3张图片
这个时候是没有Label的。我们的Label在哪里呢?在cars_train_annos.mat中。将其读入:

load 'cars_train_annos.mat';
%annotations.class即为标注信息
traindata.Labels=categorical([annotations.class])
  • 1
  • 2
  • 3

看看是否成功了:

unique(traindata.Labels)%应该输出196个数字,从1-196
  • 1

好的,现在我们可以开始训练!

AlexNet_New=trainNetwork(traindata,AlexLayer_New,optionsTransfer)
  • 1

这是我的结果: 
对196种车型分类_第4张图片 
似乎还不错。 
调用其对图片进行测试,我们需要读入一个车型的文件: 
对196种车型分类_第5张图片
封装一下进行测试的代码:

function test(fileRoad,AlexNet_New,class_names)
testImage=imread(fileRoad);
testImage_=imresize(testImage,[227 227]);
TypeNum=classify(AlexNet_New,testImage_);
TypeName=class_names(TypeNum);
disp(TypeName);
figure;
imshow(testImage);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

对单张图片进行测试:

test('bmw.jpg',AlexNet_New,class_names)
  • 1

结果: 
对196种车型分类_第6张图片
至于这张图片具体型号是什么,我也不知道。反正肯定是宝马嘛。(废话!)

—————————-UPDATE————————————- 
新的demo已经开源: 
http://blog.csdn.net/Mr_Curry/article/details/68921497


利用Matlab自带的深度学习工具进行车辆区域检测与车型识别【福利-内附源码与数据库】(二)




前言

这次的博客主要是关于如何进行车辆区域检测的,因为前段时间要考试了,沉迷学习(逃 没有更新。把代码上传到了Github,有兴趣的同学可以下下来玩一玩。这一次更新了一个GUI界面,当然,是我们Matlab课的小伙伴一起做的~

如何使用R-CNN?

在Matlab中,其实都很简单,一个训练的函数而已,最后生成一个RCNN-Object对象,即为RCNN训练得到的分类器。 
这里直接上我的训练方法吧。一开始用的是上一篇微调后的AlexNet,但是测试的时候(我尼玛那叫一个慢啊)后来使用了cifar10Net,速度有提升,但是效果下降不少。 
首先要明确,cifar10Net是Matlab2016b里面送给你的,你可以直接读取,具体可以看http://www.mathworks.com/examples/matlab-computer-vision/mw/vision_product-DeepLearningRCNNObjectDetectionExample-object-detection-using-deep-learning

 load('rcnnStopSigns.mat','cifar10Net')
  • 1

我们查看网络结构:

cifar10Net.Layers
  • 1

对196种车型分类_第7张图片
只有3个卷积层,总共的层数也少了7层,权重参数肯定是下降了一个数量级,快也是有原因的,效果不太好也是有原因的。 
然后我们要把这个后面的全连接层改成我们自己的fc-rcnn层,如何修改呢?直接上函数就行:

cifar10NetRCNN= trainRCNNObjectDetector(data, cifar10Net, options, ...
    'NegativeOverlapRange', [0 0.2], 'PositiveOverlapRange',[0.7 1])
  • 1
  • 2

训练策略可以参考:

     trainingOptions('sgdm', ...
    'Momentum', 0.9, ...
    'InitialLearnRate', 0.005, ...
    'LearnRateSchedule', 'piecewise', ...
    'LearnRateDropFactor', 0.1, ...
    'LearnRateDropPeriod',128, ...
    'L2Regularization',0.01, ...
    'MaxEpochs', 100, ...
    'MiniBatchSize', 100, ...
    'Verbose', true);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其中这个data,你必须处理成一个table,像这样的格式: 
对196种车型分类_第8张图片 
训练的结果: 
对196种车型分类_第9张图片

结果

这里是一些结果: 
对196种车型分类_第10张图片
对196种车型分类_第11张图片 
对196种车型分类_第12张图片 
对196种车型分类_第13张图片

GUI的演示: 
 

详情请见Github:https://github.com/ChenJoya/Vehicle_Detection_Recognition 
求星星!~~~

———————-UPDATE————————– 
新的demo,详见:





你可能感兴趣的:(对196种车型分类)