SSD目標檢測框架教程–2017.3
參考文獻:
- 官網: https://github.com/weiliu89/caffe/tree/ssd
- 博客: http://blog.csdn.net/wizardna521/article/details/53463348
SSD簡介
SSD是weiliu博士基於caffe,用於實時目標檢測的深度學習框架。相比於Faster rcnn, 其在目標檢測速度有了顯著提高,精度也有一定提升;相比YOLO,速度差不多,但檢測精度更高。在精度和速度的tradeoff方面,SSD可以說是YOLO和Faster rcnn兩者的優勢結合。
傳統的目標檢測(Faster rcnn 系列),需要region proposal 過程,也就是說需要預先提取候選區域,然後將此區域分類。SSD不需要region proposal, 而是採取在最後使用default mask的方法來檢測目標。SSD產生幾千個default box用於預測。每個feature map產生6個長寬比不同的default box,每一層輸出包含k個feature map, 每個feature map 有m x n個像素,則每一層可以產生6kmn個default box;不同層的輸出可以產生不同scale的feature map, 淺層的輸出產生小的scale(小目標)default box,深層的輸出產生大的scale(大目標)default box。VOC2007實驗中,他使用了conv4_3,conv7,conv8_2, conv9_2, conv10_2, conv11_2的feature map。
製作數據
將自己需要訓練的數據製作成PASCAL格式,matlab代碼如下:
% create skeleton detection label like PASCAL
% Huahui Chen, 2017.3.24
source_data_dir = '/home/chh/icme/data/detection/PKU_Skeleton_Renew';
source_label_dir = '/home/chh/icme/data/detection/Train_Label_PKU_final';
dest_label_dir = '/home/chh/icme/data/detection/detection_label';
source_label_total_filename = dir([source_label_dir '/*.txt']);
pic_height = 512;
pic_width = 512;
pic_channel = 3;
parfor i = 1 : length(source_label_total_filename)
i
filename = source_label_total_filename(i).name;
[a, filename_nopost, post] = fileparts(filename);
fid_dest = fopen([dest_label_dir '/' filename_nopost '.xml'], 'w');
fid_source = fopen([source_data_dir '/' filename_nopost '.txt']);
frame_num = 0;
while(fgetl(fid_source) ~= -1)
frame_num = frame_num + 1;
end
fprintf(fid_dest, '\n');
fprintf(fid_dest, '\t%s.png\n', filename_nopost);
fprintf(fid_dest, '\tskeleton\n');
objects = csvread([source_label_dir '/' filename_nopost '.txt']);
for j = 1 : length(objects)
fprintf(fid_dest, '\t\n');
fprintf(fid_dest, '\t\t%d\n', objects(j, 1));
fprintf(fid_dest, '\t\t\n');
fprintf(fid_dest, '\t\t\t%d\n', uint16(objects(j, 3) / frame_num * pic_width));
fprintf(fid_dest, '\t\t\t%d\n', uint16(objects(j, 2) / frame_num * pic_width));
fprintf(fid_dest, '\t\t\t%d\n', pic_height);
fprintf(fid_dest, '\t\t\t%d\n', 1);
fprintf(fid_dest, '\t\t\n');
fprintf(fid_dest, '\t\n');
end
fprintf(fid_dest, '\t\n');
fprintf(fid_dest, '\t\t%d\n', pic_channel);
fprintf(fid_dest, '\t\t%d\n', pic_height);
fprintf(fid_dest, '\t\t%d\n', pic_width);
fprintf(fid_dest, '\t\n');
fprintf(fid_dest, '');
fclose(fid_dest);
end
創建LMDB數據
將產生的數據複製到以下目錄:
*.xml —-> $(SSD)/data/VOCdevkit/VOC2007/Annotations
*.jpg —–> $(SSD)/data/VOCdevkit/VOC2007/JPEGImages
在$(SSD)/data/VOCdevkit/VOC2007/ImageSets/Main/ 放置trainval.txt 和 test.txt. 注意內容是無後綴的文件名。如0002-L
修改labelmap_**.prototxt內容
cd $(SSD)
修改create_list.sh路徑等
./data/VOC0712/create_list.sh
生成trainval.txt test.txt test_name_size.txt 在 data/VOC0712
修改create_data.sh路徑等
./data/VOC0712/create_data.sh
在data/VOCdevkit/VOC0712/lmdb/VOC0712_test_lmdb trainval_lmdb
訓練
修改ssd_pascal.py路徑等python examples/ssd/ssd_pascal.py
$(SSD)/models/VGGNet/VOC0712/SSD_300x300/下產生網絡和model weights
$(SSD)/jobs/VGGNet/VOC0712/SSD_300x300/下 產生job file, log file, python script
測試
官網上給的 python examples/ssd/score_ssd_pascal.py 將產生score和bndbox,對應的label 是文件名,不是很適用
ssd_detect.bin 可以產生lable,源文件是ssd_detection.cpp
結果保存在test_detect.txt
./build/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_1000x300/deploy.prototxt models/VGGNet/VOC0712/SSD_1000x300/VGG_VOC0712_SSD_1000x300_iter_40000.caffemodel data/VOC0712/test_detect.txt --out_file jobs/VGGNet/VOC0712/SSD_1000x300/test_detect.txt
圖形顯示:
python examples/ssd/plot_detections.py jobs/VGGNet/VOC0712/SSD_1000x300/test_detect.txt / --labelmap-file data/VOC0712/labelmap_voc.prototxt --save-dir jobs/VGGNet/VOC0712/SSD_1000x300/ --visualize-threshold 0.1
job相當於一個工程,其中存有訓練、測試的腳本和日誌,其中的腳本或程序是上述步驟生成的可以獨立運行的腳本或程序。