使用py-faster-rcnn訓(xùn)練自己的數(shù)據(jù)集

本文記錄了在ubuntu16.04下使用py-faster-rcnn來訓(xùn)練自己的數(shù)據(jù)集的大致過程。
在此之前,已經(jīng)成功配置過了caffe-gpu,使用的顯卡是GTX1080ti,安裝的cuda8.0.61+cudnn v5.1,caffe-gpu的配置過程可以參考:Ubuntu16.04配置caffe-GPU環(huán)境。

第一步:制作自己的數(shù)據(jù)集

首先,為了方便,可以將自己的訓(xùn)練圖像名稱改成PASCAL VOC格式,比如我自己的數(shù)據(jù)集共有1150張訓(xùn)練圖像,寫一個簡單的python腳本將其重命名為00001.jpg~001150.jpg。
數(shù)據(jù)集的制作工具:labelImg。安裝和使用方法都很簡單,這里不再贅述。

第二步:clone py-faster-rcnn源代碼

在bash中執(zhí)行

git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git

將得到一個py-faster-rcnn文件夾。
下載后按照py-faster-rcnn中README.md中的指導(dǎo),依次編譯/py-faster-rcnn/lib/文件夾和/py-faster-rcnn/caffe-fast-rcnn/文件夾。
在編譯/py-faster-rcnn/caffe-fast-rcnn/文件夾時出現(xiàn)了以下錯誤:

ys@ysubuntu:~/pycaffe/py-faster-rcnn/caffe-fast-rcnn$ make -j8 && make pycaffe
PROTOC src/caffe/proto/caffe.proto
CXX src/caffe/parallel.cpp
CXX src/caffe/internal_thread.cpp
...
In file included from ./include/caffe/util/device_alternate.hpp:40:0,
                 from ./include/caffe/common.hpp:19,
                 from ./include/caffe/blob.hpp:8,
                 from ./include/caffe/net.hpp:10,
                 from ./include/caffe/solver.hpp:7,
                 from ./include/caffe/sgd_solvers.hpp:7,
                 from src/caffe/solvers/nesterov_solver.cpp:3:
./include/caffe/util/cudnn.hpp: In function ‘void caffe::cudnn::createPoolingDesc(cudnnPoolingStruct**, caffe::PoolingParameter_PoolMethod, cudnnPoolingMode_t*, int, int, int, int, int, int)’:
./include/caffe/util/cudnn.hpp:127:41: error: too few arguments to function ‘cudnnStatus_t cudnnSetPooling2dDescriptor(cudnnPoolingDescriptor_t, cudnnPoolingMode_t, cudnnNanPropagation_t, int, int, int, int, int, int)’
         pad_h, pad_w, stride_h, stride_w));
                                         ^
./include/caffe/util/cudnn.hpp:15:28: note: in definition of macro ‘CUDNN_CHECK’
     cudnnStatus_t status = condition; \
                            ^
In file included from ./include/caffe/util/cudnn.hpp:5:0,
                 from ./include/caffe/util/device_alternate.hpp:40,
                 from ./include/caffe/common.hpp:19,
                 from ./include/caffe/blob.hpp:8,
                 from ./include/caffe/net.hpp:10,
                 from ./include/caffe/solver.hpp:7,
                 from ./include/caffe/sgd_solvers.hpp:7,
                 from src/caffe/solvers/nesterov_solver.cpp:3:
/usr/local/cuda/include/cudnn.h:803:27: note: declared here
 cudnnStatus_t CUDNNWINAPI cudnnSetPooling2dDescriptor(
                           ^
Makefile:563: recipe for target '.build_release/src/caffe/solvers/nesterov_solver.o' failed
make: *** [.build_release/src/caffe/solvers/nesterov_solver.o] Error 1
make: *** Waiting for unfinished jobs....
...
make: *** [.build_release/src/caffe/parallel.o] Error 1
ys@ysubuntu:~/pycaffe/py-faster-rcnn/caffe-fast-rcnn$ make clean
ys@ysubuntu:~/pycaffe/py-faster-rcnn/caffe-fast-rcnn$ 

錯誤的原因應(yīng)該是py-faster-rcnn中自帶的cudnn相關(guān)文件版本太老。
解決辦法參考:py-faster-rcnn安裝問題總結(jié)。也就是用最新下載的caffe源代碼中/caffe/include/和/caffe/src/下面所有和cudnn相關(guān)的.hpp文件和.cpp文件復(fù)制到/py-faster-rcnn/caffe-fast-rcnn/文件夾下,替換掉老版本的cudnn文件。
這樣就能順利編譯/py-faster-rcnn/caffe-fast-rcnn/文件夾了。

自己的數(shù)據(jù)集放在哪兒

為了盡量少改動代碼,最方便的方式是按照源代碼中的PASCAL VOC數(shù)據(jù)集的放置格式,即在.../py-faster-rcnn/data/文件夾下,新建一個名為VOCdevkit2007,然后,其子文件夾的目錄樹如下圖:


Screenshot from 2018-03-26 09-47-26.png

也就是在VOCdevkit2007下再建一個名為VOC2007的文件夾;然后在VOC2007下面分別建立3個文件夾:Annotations、ImageSets和JPEGImages。其中JPEGImages下面放的是訓(xùn)練集圖片:


Screenshot from 2018-03-26 09-56-31.png

Annotations下面放的是自己制作的訓(xùn)練集圖片對應(yīng)的.xml標簽文件:
Screenshot from 2018-03-26 09-55-50.png

ImageSets下面的目錄如下:


Screenshot from 2018-03-26 09-56-20.png

其下再建一個Main文件夾,在Main文件夾下面放trainval.txt文件,trainval.txt文件內(nèi)容是每張訓(xùn)練圖片名:
Screenshot from 2018-03-26 10-00-26.png

下載訓(xùn)練好的VGG16模型

參照py-faster-rcnn的使用說明,要訓(xùn)練模型需要下載一個訓(xùn)練好的VGG16模型用于遷移學(xué)習(xí)。在py-faster-rcnn/目錄下打開bash,執(zhí)行:

./data/scripts/fetch_imagenet_models.sh

或者直接在進入網(wǎng)址:https://dl.dropbox.com/s/gstw7122padlf0l/imagenet_models.tgz?dl=0下載預(yù)訓(xùn)練好的VGG16模型。
下載下來后,在/py-faster-rcnn/data/文件夾下新建一個imagenet_models文件夾,將VGG16模型放進去:

Screenshot from 2018-03-26 10-08-15.png

修改幾個地方來訓(xùn)練自己的數(shù)據(jù)集

修改train.prototxt和solver.prototxt

打開/py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_end2end/train.prototxt,使用編輯器的查找替換功能,將其中的數(shù)字21替換成你自己的數(shù)據(jù)集類別數(shù)+1,將數(shù)字84替換成你自己的(數(shù)據(jù)集類別數(shù)+1)*4,這個文件中共有3處21,一處84需要替換;

在/py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_end2end/solver.prototxt中,根據(jù)自己的實際情況修改,比如我只是的總訓(xùn)練迭代次數(shù)只設(shè)置了10000次,所以solver文件中,stepsize值我改成了6000。

修改pascal_voc.py

將/py-faster-rcnn/lib/datasets/pascal_voc.py中的約33行處的:

self._classes = ('__background__', # always index 0
                         'aeroplane', 'bicycle', 'bird', 'boat',
                         'bottle', 'bus', 'car', 'cat', 'chair',
                         'cow', 'diningtable', 'dog', 'horse',
                         'motorbike', 'person', 'pottedplant',
                         'sheep', 'sofa', 'train', 'tvmonitor')

改成自己的類別名稱。

修改train_net.py

在/py-faster-rcnn/tools/train_net.py中,可以為其中的命令行參數(shù)設(shè)置默認值,這樣就不用每次訓(xùn)練時都在命令行設(shè)置多個參數(shù)了,下面是我設(shè)置的默認值:

def parse_args():
    """
    Parse input arguments
    """
    parser = argparse.ArgumentParser(description='Train a Fast R-CNN network')
    parser.add_argument('--gpu', dest='gpu_id',
                        help='GPU device id to use [0]',
                        default=0, type=int)
    parser.add_argument('--solver', dest='solver',
                        help='solver prototxt',
                        default='models/pascal_voc/VGG16/faster_rcnn_end2end/solver.prototxt', type=str)
    parser.add_argument('--iters', dest='max_iters',
                        help='number of iterations to train',
                        default=10000, type=int)
    parser.add_argument('--weights', dest='pretrained_model',
                        help='initialize with pretrained model weights',
                        default='data/imagenet_models/VGG16.v2.caffemodel', type=str)
    parser.add_argument('--cfg', dest='cfg_file',
                        help='optional config file',
                        default='experiments/cfgs/faster_rcnn_end2end.yml', type=str)
    parser.add_argument('--imdb', dest='imdb_name',
                        help='dataset to train on',
                        default='voc_2007_trainval', type=str)
    parser.add_argument('--rand', dest='randomize',
                        help='randomize (do not use a fixed seed)',
                        action='store_true')
    parser.add_argument('--set', dest='set_cfgs',
                        help='set config keys', default=None,
                        nargs=argparse.REMAINDER)

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    args = parser.parse_args()
    return args

另外可能需要修改的是/py-faster-rcnn/lib/fast_rcnn/config.py中的__C.TRAIN.SNAPSHOT_ITERS參數(shù),它確定了你的模型每訓(xùn)練多少次保存一次快照,源碼設(shè)置的是10000,根據(jù)自己設(shè)置的最大迭代次數(shù)來合理修改(它的值當(dāng)然不能大于最大迭代次數(shù),不然訓(xùn)練了半天一個模型都沒保存)。

訓(xùn)練模型

以上準備工作完成后,在/py-faster-rcnn/目錄下打開bash,執(zhí)行:

python ./tools/train_net.py --gpu 0

開始模型訓(xùn)練。
可能會遇到這個問題:

Traceback (most recent call last):
  File "./tools/train_net.py", line 112, in <module>
    max_iters=args.max_iters)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/fast_rcnn/train.py", line 157, in train_net
    pretrained_model=pretrained_model)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/fast_rcnn/train.py", line 51, in __init__
    pb2.text_format.Merge(f.read(), self.solver_param)
AttributeError: 'module' object has no attribute 'text_format'

解決辦法參考:py-faster-rcnn安裝問題總結(jié)。

還可能會遇到這個問題:

Traceback (most recent call last):
  File "./tools/train_net.py", line 112, in <module>
    max_iters=args.max_iters)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/fast_rcnn/train.py", line 161, in train_net
    model_paths = sw.train_model(max_iters)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/fast_rcnn/train.py", line 102, in train_model
    self.solver.step(1)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/rpn/proposal_target_layer.py", line 66, in forward
    rois_per_image, self._num_classes)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/rpn/proposal_target_layer.py", line 191, in _sample_rois
    _get_bbox_regression_labels(bbox_target_data, num_classes)
  File "/home/ys/pycaffe/py-faster-rcnn/tools/../lib/rpn/proposal_target_layer.py", line 127, in _get_bbox_regression_labels
    bbox_targets[ind, start:end] = bbox_target_data[ind, 1:]
TypeError: slice indices must be integers or None or have an __index__ method

解決辦法參考這里
出錯原因:

Screenshot from 2018-03-26 11-02-06.png

可能是源代碼發(fā)布的時候,numpy 是支持浮點數(shù)作為索引的,但是在 numpy1.12.0 之后,numpy 只能用整數(shù)作為索引。所以,解決辦法有兩種:
第一種是卸載當(dāng)前的 numpy,安裝回以前的 1.11.2 版本,但是同時安裝的 opencv 版本也得退回老版本,因為新版本的 opencv3.1 依賴于新版本的 numpy,相同的依賴問題還有matplotlib。因此的重裝回 openCV2.4.13, matplotlib1.5.1,當(dāng)然這種辦法比較麻煩;
第二種辦法是找到使用浮點數(shù)作為 numpy 索引的相關(guān)代碼,將其強制轉(zhuǎn)換為 int 型:


Screenshot from 2018-03-26 11-03-48.png

再次運行,模型就能順利訓(xùn)練了。

測試模型

修改test.prototxt

打開/py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_end2end/test.prototxt,使用編輯器的查找替換功能,將其中的數(shù)字21替換成你自己的數(shù)據(jù)集類別數(shù)+1,將數(shù)字84替換成你自己的(數(shù)據(jù)集類別數(shù)+1)*4,這個文件中共有1處21,一處84需要替換;

修改demo.py

訓(xùn)練得到的模型在這里:


Screenshot from 2018-03-26 11-21-30.png

將其復(fù)制到/py-faster-rcnn/data/faster_rcnn_models/目錄下。
然后打開demo.py,將

CLASSES = ('__background__',
           'aeroplane', 'bicycle', 'bird', 'boat',
           'bottle', 'bus', 'car', 'cat', 'chair',
           'cow', 'diningtable', 'dog', 'horse',
           'motorbike', 'person', 'pottedplant',
           'sheep', 'sofa', 'train', 'tvmonitor')

改成自己的標簽,將

NETS = {'vgg16': ('VGG16',
                  'VGG16_faster_rcnn_final.caffemodel'),

中的模型改成自己訓(xùn)練保存的模型。比如我修改的內(nèi)容:

CLASSES = ('__background__', 'type1', 'type2', 'type3', 'type4', 'type5')

NETS = {'vgg16': ('VGG16',
                  'vgg16_faster_rcnn_iter_10000.caffemodel'),

prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
                            'faster_rcnn_alt_opt', 'faster_rcnn_test.pt')

改成

prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
                            'faster_rcnn_end2end', 'test.prototxt')

im_names = ['000456.jpg', '000542.jpg', '001150.jpg',
                '001763.jpg', '004545.jpg']

列表中的圖片名改成自己要測試的圖片名稱,當(dāng)然首先需要將相應(yīng)的圖片復(fù)制到/py-faster-rcnn/data/demo/目錄下。

修改完成,在/py-faster-rcnn/目錄下打開bash,執(zhí)行

python ./tools/demo.py

沒問題的話,就能順利看到測試結(jié)果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容