【圖像識(shí)別】基于yolo v2深度學(xué)習(xí)檢測(cè)識(shí)別車輛matlab源碼
前言
Okay……最近事情比較多,博客也發(fā)的少,所以決定搞一次大新聞。本此的博客詳細(xì)記錄了我使用Matlab進(jìn)行車輛區(qū)域檢測(cè)(R-CNN)與車型識(shí)別(AlexNet)的過程。并且內(nèi)包含了訓(xùn)練數(shù)據(jù)集、測(cè)試數(shù)據(jù)集以及源碼。?
訓(xùn)練數(shù)據(jù)集是使用的斯坦福大學(xué)的一個(gè)車型數(shù)據(jù)庫,內(nèi)含196種不同的車型。寫到這里我真的很想吐槽一下這個(gè)數(shù)據(jù)庫里面的奧迪車系:很多黑白的圖片啊喂?。?! 做訓(xùn)練的時(shí)候AlexNet數(shù)據(jù)輸入維度是3啊喂!?。『Φ奈易约赫伊撕芏鄨D片?。。。 ?
環(huán)境
測(cè)試環(huán)境:?
硬件:?
Intel i5-4590?
GTX 980?
軟件:?
Matlab R2016b(只有這個(gè)版本才實(shí)現(xiàn)了RCNN…)
數(shù)據(jù)集的下載
嗯。一上來就發(fā)福利:?
原始數(shù)據(jù)集,內(nèi)含train/test:http://pan.baidu.com/s/1miTn9jy?
我規(guī)整后的數(shù)據(jù)集,將圖片變換為227*227,并且對(duì)少量黑白圖片進(jìn)行了替換:http://pan.baidu.com/s/1pKIbQiB?
接下來的這個(gè)是每一張圖片所對(duì)應(yīng)的車型標(biāo)注文件:http://pan.baidu.com/s/1nuOR7PR
在Matlab中下載AlexNet
AlexNet是2012年ImageNet大賽的冠軍。它一共有8層,其中了5個(gè)卷積層,2層全連接和一層分類,如果使用其對(duì)一張圖片進(jìn)行前向傳播,那么最后輸出的這張圖片屬于1000種物體中哪一個(gè)的概率。?
我這里對(duì)AlexNet在Matlab中進(jìn)行了定義,這是我的代碼和網(wǎng)絡(luò)結(jié)構(gòu):
clear
clc
doTraining = true; % 是否進(jìn)行訓(xùn)練
% 解壓數(shù)據(jù)
% data = load('./data/carDatasetGroundTruth.mat');
% vehicleDataset = data.carDataset; % table型,包含文件路徑和groundTruth
data = load('./data/vehicleDatasetGroundTruth.mat');
vehicleDataset = data.vehicleDataset; % table型,包含文件路徑和groundTruth
% 添加絕對(duì)路徑至vehicleDataset中
vehicleDataset.imageFilename = fullfile([pwd, '/data/'],vehicleDataset.imageFilename);
% 顯示數(shù)據(jù)集中的一個(gè)圖像,以了解它包含的圖像的類型。
vehicleDataset(1:4,:) % 顯示部分?jǐn)?shù)據(jù)情況
% 將數(shù)據(jù)集分成兩部分:一個(gè)是用于訓(xùn)練檢測(cè)器的訓(xùn)練集,一個(gè)是用于評(píng)估檢測(cè)器的測(cè)試集。
% 選擇 70% 的數(shù)據(jù)進(jìn)行訓(xùn)練,其余數(shù)據(jù)用于評(píng)估。
rng(0); % 控制隨機(jī)數(shù)生成
shuffledIndices = randperm(height(vehicleDataset));
idx = floor(0.7 * length(shuffledIndices) );
trainingDataTbl = vehicleDataset(shuffledIndices(1:idx),:);
testDataTbl = vehicleDataset(shuffledIndices(idx+1:end),:);
% 保存數(shù)據(jù)和標(biāo)簽
imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); % 路徑
bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle')); % 真實(shí)框和類別
imdsTest = imageDatastore(testDataTbl{:,'imageFilename'});
bldsTest = boxLabelDatastore(testDataTbl(:,'vehicle'));
% 整理訓(xùn)練測(cè)試集
trainingData = combine(imdsTrain,bldsTrain); % 聯(lián)合文件路徑和真實(shí)框
testData = combine(imdsTest,bldsTest);
% 顯示數(shù)據(jù)
data = read(trainingData); % data包括圖片數(shù)據(jù)、真實(shí)框坐標(biāo)、類別
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox); % 在數(shù)據(jù)矩陣中標(biāo)出真實(shí)框
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage) % 顯示圖像
% 創(chuàng)建yolo網(wǎng)絡(luò)
inputSize = [224 224 3];
numClasses = width(vehicleDataset)-1; % 通過table的列數(shù)計(jì)算類別數(shù)
% 用于評(píng)估錨框個(gè)數(shù)
trainingDataForEstimation = transform(trainingData,@(data)preprocessData(data,inputSize));
numAnchors = 7;
[anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingDataForEstimation, numAnchors)
% 特征提取層采用resnet50
featureExtractionNetwork = resnet50;
featureLayer = 'activation_40_relu';
% 設(shè)置yolo網(wǎng)絡(luò)
lgraph = yolov2Layers(inputSize,numClasses,anchorBoxes,featureExtractionNetwork,featureLayer);
% 進(jìn)行數(shù)據(jù)增強(qiáng)
augmentedTrainingData = transform(trainingData,@augmentData);
% 可視化增強(qiáng)后的圖片
augmentedData = cell(4,1);
for k = 1:4
? ?data = read(augmentedTrainingData);
? ?augmentedData{k} = insertShape(data{1},'Rectangle',data{2});
? ?reset(augmentedTrainingData);
end
figure
montage(augmentedData,'BorderSize',10)
% 對(duì)增強(qiáng)數(shù)據(jù)進(jìn)行預(yù)處理
preprocessedTrainingData = transform(augmentedTrainingData,@(data)preprocessData(data,inputSize));
data = read(preprocessedTrainingData);
% 顯示一下
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox);
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage)
% 訓(xùn)練參數(shù)
options = trainingOptions('sgdm', ...
? ? ? ?'MiniBatchSize', 16, ....
? ? ? ?'InitialLearnRate',1e-3, ...
? ? ? ?'MaxEpochs',20,...
? ? ? ?'CheckpointPath', tempdir, ...
? ? ? ?'Shuffle','never');
? ?
if doTraining ? ? ?
? ?% 訓(xùn)練YOLOv2檢測(cè)器
? ?[detector,info] = trainYOLOv2ObjectDetector(preprocessedTrainingData,lgraph,options);
else
? ?% 載入預(yù)訓(xùn)練模型
? ?pretrained = load('yolov2_mytrain.mat');
? ?detector = pretrained.detector;
end
% 測(cè)試訓(xùn)練好的模型并顯示
I = imread(testDataTbl.imageFilename{4});
I = imresize(I,inputSize(1:2));
[bboxes,scores] = detect(detector,I);
I = insertObjectAnnotation(I,'rectangle',bboxes,scores);
figure
imshow(I)
% 預(yù)處理測(cè)試集
preprocessedTestData = transform(testData,@(data)preprocessData(data,inputSize));
% 對(duì)測(cè)試集數(shù)據(jù)進(jìn)行測(cè)試
detectionResults = detect(detector, preprocessedTestData);
% 評(píng)估準(zhǔn)確率
[ap,recall,precision] = evaluateDetectionPrecision(detectionResults, preprocessedTestData);
figure
plot(recall,precision)
xlabel('Recall')
ylabel('Precision')
grid on
title(sprintf('Average Precision = %.2f',ap))



?