概要
前回の続きで、白黒画像からの物体検出精度を上げる研究を行っていきます。 今回は前回提案した解決案のうち、"グレースケール画像で学習を行ったモデルを用いる"ということについて取り組んでみます。
前回との変更点
前回まで、物体検出モデルはYOLOv3を使っていましたが、YOLOv3で学習を行うには非常に時間がかかり、マシンのスペックによってはメモリ不足で学習途中でエラーが出力されてしまうこともあります。 今回は、学習に使う画像を白黒に変えることで精度に変化はあるのかという研究を目的としていますので、YOLOv3に対して精度は若干劣りますが、比較的短い時間で学習を行うことが出来るFaster R-CNNというものを使いたいと思います。
FasterR-CNNの導入から学習まで
- こちらのgitよりkeras版のソースコードをダウンロード
- keras-frcnnディレクトリ下にinput_weightディレクトリを作成
- input_weightに学習済みモデルをResNet50またはVGG16よりダウンロード
- keras-frcnnディレクトリ下にTrain_dataディレクトリとTest_dataディレクトリを作成
- 訓練データをPASCAL VOC2007からダウンロード(カラー画像)
- Train_dataディレクトリ下に訓練データをダウンロードして解凍
- ソースコードを一部変更
l.45
python:train_frcnn.py if options.parser == 'pascal_voc': from keras_frcnn.pascal_voc_parser import get_data
↓
python:train_frcnn.py if options.parser == 'pascal_voc': from keras_frcnn.parser import get_data
に変更
pascal_voc_parser.pyをparser.pyという名前でファイルコピー
l.14とl.19
python:parser.py data_paths = [os.path.join(input_path,s) for s in ['VOC2007', 'VOC2012']] ### 中略 ### for data_path in data_paths:
l.15
python:parser.py data_path = input_path
を追加 parser.pyのl.21からl.101のコードのインデントを一つさげる
l.150
python:train_frcnn.py epoch_length = 300 #1000から変更
最後にTrain_data/ImageSets/Main の下のval.txtの名前をtest.txtに変更、train.txtの名前をtrainval.txtに変更(val.txtとtrain.txtをまとめたテキストtrain.txtは消すか他の名前に変える)。
- 学習実行
YOLOv3とアルゴリズム単位で精度比較もしてみたかったため、ある程度のエポックで回してみます。
今回はエポックを200としました。
python train_frcnn.py -p Train_data --num_epochs 200 --input_weight_path ./input_weights/resnet50_weights_tf_dim_ordering_tf_kernels.h5
config.pickleが生成されればokです。 大体学習を終えるまで30時間かかりました。
※注意点
上記のソースコードはkerasバージョン2.2.2でしか動作が確認できませんでした(2.2.4と2.2.3で試したがダメだった)。
そのためkerasのバージョンは2.2.2を推奨します。
kerasのバージョン変更はpip install keras==2.2.2
で行うことが出来ます。
テスト実行
テストはpython test_frcnn.py -p ./テストデータのディレクトリ
で実行できます。
無事学習が出来ているか確認してみます。
良い感じに検出が出来ており、導入が完了しました。 では、本題の学習データを白黒に変えた時、精度の変化はあるのかということについて検証していきます。
学習データを白黒に変更して実行
学習データとしてダウンロードしたPASCAL VOC2007の画像を白黒化して学習を実行します。 カラー画像を白黒画像化するプログラム以下のものを作成しました。
python:cvt_clr2gray.py import cv2 import numpy as np for i in range(10000): img = cv2.imread("./JPEGImages/00"+str(i).zfill(4)+".jpg") if img is None: continue gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) clr_img = np.zeros((img.shape[0],img.shape[1],3)) for j in range(gray_img.shape[0]): for k in range(gray_img.shape[1]): for l in range(3): clr_img[j][k][l] = gray_img[j][k] cv2.imwrite("./JPEGImages_gray/00"+str(i)+".jpg", clr_img)
200エポックだと時間がかかり過ぎたのでエポックを10にして、比較のため白黒画像とカラー画像でそれぞれ学習を実行しました。
カラー画像で学習したモデルのテスト結果
白黒画像で学習したモデルのテスト結果
カラーで学習したモデルでは一人も検出できていませんが、白黒画像で学習したモデルでは人を検出できていることから、学習データを白黒画像にすることで、白黒画像からの検出精度を高められることが分かりました。
次回
入力画像の前処理を行います。