• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前言

本此的博客详细记录了我使用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

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

对AlexNet进行Finetune

首先读入这个AlexNet:

AlexNet=helperImportMatConvNet(\'AlexLayerFromWeb.mat\');

观察其网络结构:

AlexNet.Layers


我们要对其进行微调,那么其实前面的卷积层都不用改,要改的就是最后的一个全连接层,要把它改成我们的层。由于车型一共是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

运行:

[AlexLayer_New , optionsTransfer]=FineTune(AlexNet)

得到新的网络层级:

Okay,现在我们要开始准备数据了。有两个方式,可以直接下载我的traindata.mat,并且按照里面的路径来放一下cars_train这个文件夹。那么我们就直接可以:

load(\'traindata.mat\')

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

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


这个时候是没有Label的。我们的Label在哪里呢?在cars_train_annos.mat中。将其读入:

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

看看是否成功了:

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

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

AlexNet_New=trainNetwork(traindata,AlexLayer_New,optionsTransfer)

这是我的结果:

似乎还不错。
调用其对图片进行测试,我们需要读入一个车型的文件:

封装一下进行测试的代码:

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

对单张图片进行测试:

test(\'bmw.jpg\',AlexNet_New,class_names)

结果:

至于这张图片具体型号是什么,我也不知道。反正肯定是宝马嘛。(废话!)

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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap