Ubuntu 16.04下利用tf-faster-rcnn在VOC或其他資料集上訓練自己的模型
暑期的時候有朋友問我如何配置tf-faster-rcnn,那會簡單寫了個steps.pdf。正好最近閒了下來,就把它彙總一下。
Introduction
這是一篇介紹如何使用tf-faster-rcnn在VOC和其他資料集訓練自己模型的筆記. 筆記中所有檔案的地址: 地址 我的機器和庫版本: GTX 1060, miniconda 4.5.4, CUDA 9.0, CUDNN 7.1.4, tensorflow-gpu 1.8.0.
1 配置tf-faster-rcnn
1.1 Intall opencv, cython, easydict
我使用的是opencv 3.4.1, cython 0.28.4 and easydict 1.7.
1.2 Clone the repository
git clone https://github.com/endernewton/tf-faster-rcnn.git
1.3 Build the Cython modules
cd tf-faster-rcnn/lib
make clean
make
cd ..
1.4 Install the Python COCO API
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
cd ../..
1.5 Setup data
cd data wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar tar xvf VOCtrainval_06-Nov-2007.tar tar xvf VOCtest_06-Nov-2007.tar tar xvf VOCdevkit_08-Jun-2007.tar ln -s VOCdevkit VOCdevkit2007 cd ..
1.6 Download pre-trained model
Google Driver: link
Baidu Cloud: link
下載模型並放入目錄tf-faster-rcnn/
, 在當前目錄執行命令
tar xvf voc_0712_80k-110k.tgz
1.7 Create a folder and a soft link to use the pre-trained model
NET=res101 TRAIN_IMDB=voc_2007_trainval+voc_2012_trainval mkdir -p output/$NET/$TRAIN_IMDB cd output/$NET/$TRAIN_IMDB ln -s ../../../voc_2007_trainval+voc_2012_trainval ./default cd ../../..
1.8 Modify python file
修改tf-faster-rcnn/lib/datasets/voc_eval.py
, 121 line.
# save
print('Saving cached annotations to {:s}'.format(cachefile))
with open(cachefile, 'w') as f: ---> with open(cachefile, 'wb') as f:
pickle.dump(recs, f)
1.9 Demo for testing on custom images
修改python檔案之後, 執行以下命令.
GPU_ID=0
CUDA_VISIBLE_DEVICES=$GPU_ID ./tools/demo.py
1.10 End
至此為止, 只需要對./tools/demo.py
進行輕微修改, 你就可以使用這個模型來預測自己的資料集(資料集中的category必須在VOC資料集裡面). 當然mean iou肯定不會很高的, 大約會在0.20~0.60這個區間.
2 Train your own model on the VOC dataset
2.1 Download CNN pre-trained model
mkdir -p data/imagenet_weights
cd data/imagenet_weights
wget -v http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz
tar -xzvf resnet_v1_101_2016_08_28.tar.gz
mv resnet_v1_101.ckpt res101.ckpt
cd ../..
2.2 Modify shell file
為了節約時間, 這裡將shell檔案中的ITES修改為300.
2.2.1 tf-faster-rcnn/experiments/scripts/train_faster_rcnn.sh
pascal_voc)
TRAIN_IMDB="voc_2007_trainval"
TEST_IMDB="voc_2007_test"
STEPSIZE="[50000]"
ITERS=70000 ---> 300
ANCHORS="[8,16,32]"
RATIOS="[0.5,1,2]"
;;
2.2.2 tf-faster-rcnn/experiments/scripts/test_faster_rcnn.sh
pascal_voc)
TRAIN_IMDB="voc_2007_trainval"
TEST_IMDB="voc_2007_test"
ITERS=70000 ---> 300
ANCHORS="[8,16,32]"
RATIOS="[0.5,1,2]"
;;
2.3 Train your model on pascal_voc
因為train腳本里自動執行test指令碼, 而VOC2007的測試集有4952張圖片, 所以test過程會花些時間. 為了節約時間, 我們只保留data/VOCdevkit2007/VOC2007/ImageSets/Main/test.txt
裡前200行. 最後執行下面命令進行模型的訓練
./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc res101
2.4 End
到此為止, 你可以在VOC資料集上訓練自己的模型.
3 Train your own model on other dataset
這裡給大家拿一個車輛檢測比賽的資料集舉例子, 這個資料集有兩類檔案(詳情見資料集說明). 首先我們把下載的資料集解壓後放入一個新目錄tf-faster-rcnn/dataset
.
3.1 Data Preprocess
3.1.1 首先清空目錄data/VOCdevkit2007/VOC2007/
在目錄tf-faster-rcnn/
執行命令
rm -rf data/VOCdevkit2007/VOC2007/*
3.1.2 data/VOCdevkit2007/VOC2007/Annotations
這個目錄儲存訓練集所有影象的Annotations檔案(image_name.xml) 這裡給出一個notebook 來演示如何獲取.xml檔案
3.1.3 data/VOCdevkit2007/VOC2007/ImageSets/Main
- train.txt: 訓練集中所有影象名(不帶字尾).
- trainval.txt: 訓練集和驗證集中所有影象名.
- val.txt: 驗證集中所有影象名.
- test.txt: 測試集中所有影象名 (test指令碼以它為基準來評估mean iou的, 所以如果你的測試集沒有xml檔案, 那你不可以將測試集放入. 相反的, 你應該在此寫入驗證集中所有影象名).
注意: test.txt和val.txt是一樣的, 簡單copy一下val.txt重新命名即可.
3.1.4 獲取data/VOCdevkit2007/VOC2007/JPEGImages
所有影象檔案(同理如果你的測試集沒有xml檔案, 你不可以將其放入該目錄). 這裡給出一個notebook演示如何獲取.txt和.jpg檔案
3.1.5 End
接下來只需要把dataset/
下的Annotations
, ImageSets/Main
, JPEGImages
移動到目錄data/VOCdevkit2007/VOC2007/
. 至此, 資料集已準備完畢.
3.2 Modify the program
3.2.1 lib/datasets/pascal_voc.py
- 修改classes, 36 line.
self._classes = ('__background__', # always index 0 'car')
- 如果你的資料集是以0為基準的, 需要移除-1運算, 169 line.
x1 = float(bbox.find('xmin').text) y1 = float(bbox.find('ymin').text) x2 = float(bbox.find('xmax').text) y2 = float(bbox.find('ymax').text)
3.2.2 lib/datasets/imdb.py
修改程式, 105 - 124 line.
def _get_widths(self):
return [PIL.Image.open(self.image_path_at(i)).size[0]
for i in range(self.num_images)]
def _get_heights(self):
return [PIL.Image.open(self.image_path_at(i)).size[1]
for i in range(self.num_images)]
def append_flipped_images(self):
num_images = self.num_images
widths = self._get_widths()
heights = self._get_heights()
for i in range(num_images):
boxes = self.roidb[i]['boxes'].copy()
oldx1 = boxes[:, 0].copy()
oldx2 = boxes[:, 2].copy()
boxes[:, 0] = widths[i] - oldx2 - 1
boxes[:, 2] = widths[i] - oldx1 - 1
for ids in range(len(boxes)):
if boxes[ids][2] < boxes[ids][0]:
boxes[ids][0] = 0
assert (boxes[:, 2] >= boxes[:, 0]).all()
entry = {'boxes': boxes,
'gt_overlaps': self.roidb[i]['gt_overlaps'],
'gt_classes': self.roidb[i]['gt_classes'],
'flipped': True}
self.roidb.append(entry)
self._image_index = self._image_index * 2
3.2.3 lib/datasets/voc_eval.py
27 - 30 line, int() -> float().
obj_struct['bbox'] = [float(bbox.find('xmin').text),
float(bbox.find('ymin').text),
float(bbox.find('xmax').text),
float(bbox.find('ymax').text)]
3.3 Train your model
3.3.1 Training
- Remove old model
rm -rf output
- Clear cache
rm data/cache/voc_2007_test_gt_roidb.pkl rm data/cache/voc_2007_trainval_gt_roidb.pkl rm data/VOCdevkit2007/VOC2007/ImageSets/Main/test.txt_annots.pkl
- Update parameters
3.1. 在
experiments/scripts/train_faster_rcnn.sh
中修改 stepsize 和 iteations. 3.2. 在experiments/cfgs
中修改模型的引數. 3.3. 在lib/model/config.py
中修改訓練引數和測試引數. 注意: 必須保證train_faster_rcnn.sh
和test_faster_rcnn.sh
中的ITERS相同. - Train model
./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc res101
3.3.2 Predict
通過./tools/demo.py
可以獲取引數影象的邊界框. 這裡我給出一個例子demo example , 下面是對輸入的簡單解釋:
- demo_net: 分類網路架構
- demo_ite: 網路的ITERS, 可以選擇不同ITERS時期的網路來做測試
- demo_dir: 測試集目錄
- demo_vis: 是否視覺化測試的影象
- write_and: 是否將預測的boxes寫入csv檔案
- dataset: 選擇資料集格式
Note: 為了更好的觀察預測效果, 可以先在data/demo
裡面放幾張預測圖片, 執行時將demo_vis設定為True. 如果視覺化的檢測結果沒有很大偏差, 這時只需修改demo_dir
同時將demo_vis
設定為False,即可對全部的資料進行預測,(如果同時視覺化很多圖片是很可怕的, 切記!!!).
3.4 How to improve the performance of your model
你需要理解透徹這個專案裡的所有程式, 只有這樣你才可以通過修改引數, 加入資料增強, 選擇不同的度量等方法來訓練自己的網路.