SSD-tensorflow 單類目標的檢測
阿新 • • 發佈:2018-12-29
最近一段時間主要是做目標檢測的任務,在沒接觸DL之前,受到目標影象尺度、特徵不明顯等影響傳統方法效果並不是很好。
一、跑通SSD-tensorflow Demo
二、實現單類目標的檢測
跑通了上一步 該怎麼做呢,Demo中實現了20類 的目標檢測,但因需要,我只訓練檢測行人。
1、準備資料
(1)、提取原voc資料集裡含有人的 xml 和 imge
參考網友的根據自己的目錄修改(我的目錄有點長,認真看)
bash xxx.sh
#!bin/sh
year="VOC2007"
# mkdir ...where to store
#mkdir .././datasets/test2/test1/
mkdir .././datasets/VOCperson/${year}_Anno/
mkdir .././datasets/VOCperson/${year}_Image/
cd .././datasets/VOCtrainval_06-Nov-2007/VOCdevkit/VOC2007/Annotations/
grep -H -R "<name>person</name>" > /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/temp.txt #找到有關鍵字的行,並把這些行存到臨時文件
#grep -H -R "<name>person</name>" > temp.txt #找到有關鍵字的行,並把這些行存到臨時文件
cd /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson
cat temp.txt | sort | uniq > $year.txt #根據名字排序,並把相鄰的內容完全一樣的多餘行刪除。
find -name $year.txt | xargs perl -pi -e 's|.xml:\t\t<name>person</name>||g' #把文件中字尾名和其他無用資訊刪掉,只保留沒後綴名的檔名
cat $year.txt | xargs -i cp /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCtrainval_06-Nov-2007/VOCdevkit/VOC2007/Annotations/{}.xml /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/${year}_Anno/
cat $year.txt | xargs -i cp /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCtrainval_06-Nov-2007/VOCdevkit/VOC2007/JPEGImages/{}.jpg /media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/${year}_Image/
rm temp.txt
這樣就得到了含有人的 imge和相應的xml檔案,如下
(2)、修改xml 檔案
由於提取的xml檔案中可能還有其他物體的 object 資訊,需要進一步去除
bash xxx.sh
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 31 10:03:03 2017
@author: hans
"""
import os
import xml.etree.ElementTree as ET
origin_ann_dir = 'Annotations_old/'
new_ann_dir = 'Annotations/'
for dirpaths, dirnames, filenames in os.walk(origin_ann_dir):
for filename in filenames:
if os.path.isfile(r'%s%s' %(origin_ann_dir, filename)):
origin_ann_path = os.path.join(r'%s%s' %(origin_ann_dir, filename))
new_ann_path = os.path.join(r'%s%s' %(new_ann_dir, filename))
tree = ET.parse(origin_ann_path)
root = tree.getroot()
for object in root.findall('object'):
name = str(object.find('name').text)
if not (name == "person"): #去除 不是 person的 object
root.remove(object)
tree.write(new_ann_path)
(3)、訓練集、測試集 劃分
通過修改自己的相關目錄,注意這裡是 執行 .py 檔案 ,
import os
import random
xmlfilepath=r'/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/VOC2007_Anno'
saveBasePath=r"/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson"
trainval_percent=0.8
train_percent=0.7
total_xml = os.listdir(xmlfilepath)
num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
print("train and val size",tv)
print("traub size",tr)
ftrainval = open(os.path.join(saveBasePath,'/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/ImageSets/Main/trainval.txt'), 'w')
ftest = open(os.path.join(saveBasePath,'/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/ImageSets/Main/test.txt'), 'w')
ftrain = open(os.path.join(saveBasePath,'/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/ImageSets/Main/train.txt'), 'w')
fval = open(os.path.join(saveBasePath,'/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/ImageSets/Main/val.txt'), 'w')
for i in list:
name=total_xml[i][:-4]+'\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
(4)、轉 tfrecord
這一步沒有太多修改,沒多大問題
三、訓練網路(fine-tune)
(1)修改 pascalvoc_common.py檔案
(2)注意這裡是微調的,才開始搞的時候我把 CHECKPOINT_PATH 註釋了,直接導致 loss 30~50 ,訓練出來的模型也識別不出任何結果。(困了 好幾天,呵呵)。用VGG-16 模型進行訓練效果也同樣(引數有問題?)
set files are stored.
DATASET_DIR=/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/datasets/VOCperson/tfrecord/
#../../../../common/dataset/VOC2007/VOCtrainval_06-Nov-2007/VOCdevkit/VOC2007_tfrecord/
#Directory where checkpoints and event logs are written to.
TRAIN_DIR=.././log_files/log_person/
#The path to a checkpoint from which to fine-tune
CHECKPOINT_PATH=/media/xd/000398040009E3B2/txh_ubuntu/hands_on_ml/SSD-Tensorflow-master/checkpoints/VGG_VOC0712_SSD_300x300_iter_120000/VGG_VOC0712_SSD_300x300_iter_120000.ckpt
python3 ../train_ssd_network.py \
--train_dir=${TRAIN_DIR} \
--dataset_dir=${DATASET_DIR} \
--dataset_name=pascalvoc_2007 \
--dataset_split_name=train \
--model_name=ssd_300_vgg \
--checkpoint_path=${CHECKPOINT_PATH} \
--save_summaries_secs=60 \
--save_interval_secs=600 \
--weight_decay=0.0005 \
--optimizer=adam \
--learning_rate=0.001 \
--batch_size=32 \
最後,上張效果圖(有點不理想),調參、調參
四、遙感影象檢測
見下一篇中 要 解決高解析度遙感影象檢測中影象太大檢測不出來的問題
,也就是把影象放大後再擷取影象又可以重新檢測出來了。