1. 程式人生 > >Ubuntu 16.04下利用tf-faster-rcnn在VOC或其他資料集上訓練自己的模型

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

  1. train.txt: 訓練集中所有影象名(不帶字尾).
  2. trainval.txt: 訓練集和驗證集中所有影象名.
  3. val.txt: 驗證集中所有影象名.
  4. 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

  1. 修改classes, 36 line.
    self._classes = ('__background__', # always index 0
    				 'car')
    
  2. 如果你的資料集是以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

  1. Remove old model
    rm -rf output
    
  2. 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
    
  3. 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.shtest_faster_rcnn.sh中的ITERS相同.
  4. Train model
    ./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc res101
    

3.3.2 Predict

通過./tools/demo.py 可以獲取引數影象的邊界框. 這裡我給出一個例子demo example , 下面是對輸入的簡單解釋:

  1. demo_net: 分類網路架構
  2. demo_ite: 網路的ITERS, 可以選擇不同ITERS時期的網路來做測試
  3. demo_dir: 測試集目錄
  4. demo_vis: 是否視覺化測試的影象
  5. write_and: 是否將預測的boxes寫入csv檔案
  6. dataset: 選擇資料集格式

Note: 為了更好的觀察預測效果, 可以先在data/demo裡面放幾張預測圖片, 執行時將demo_vis設定為True. 如果視覺化的檢測結果沒有很大偏差, 這時只需修改demo_dir同時將demo_vis設定為False,即可對全部的資料進行預測,(如果同時視覺化很多圖片是很可怕的, 切記!!!).

3.4 How to improve the performance of your model

你需要理解透徹這個專案裡的所有程式, 只有這樣你才可以通過修改引數, 加入資料增強, 選擇不同的度量等方法來訓練自己的網路.