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

    前言

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

  • 相关阅读:
    JS的IE和FF兼容性问题汇总
    解决flash挡住层的问题
    javascript 代码优化工具 UglifyJS
    理解面向对象
    js中的等号与非等号
    js 的数据类型转换
    js优化 ----js的有序加载
    各浏览器对页面外部资源加载的策略
    js 执行效率
    脚本的加载,解析,与执行
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9412030.html
Copyright © 2011-2022 走看看