ChainerCVのデモンストレーションプログラムを読んでみた
ChainerCVの物体認識(SSD)のデモンストレーションのファイルを読んでみました。
目次
本編
ChainerCVのSSDのデモンストレーションの、 学習についてのデモのコード train.py を読んでみます。
まず全体を見渡してみます。
最初に大量のimportがあります。次にクラスや関数の定義があって、最後に実行します。
クラスと関数は3つ定義されていて、それぞれこのような役割のようです。
class MultiboxTrainChain(chainer.Chain):
# モデル(ネットワーク)の定義
class Transform(object):
# データの拡張方法の定義
def main():
# 実行部分をまとめたもの
main部分を読んでみて、このプログラムが何をしているのか見てみます。
引数の解釈
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--model', choices=('ssd300', 'ssd512'), default='ssd300')
parser.add_argument('--batchsize', type=int, default=32)
parser.add_argument('--iteration', type=int, default=120000)
parser.add_argument('--step', type=int, nargs='*', default=[80000, 100000])
parser.add_argument('--gpu', type=int, default=-1)
parser.add_argument('--out', default='result')
parser.add_argument('--resume')
args = parser.parse_args()
argparseモジュールを使って、引数をパースします。パースした結果はargsというオブジェクトに入れています。
モデルのインスタンスを作る
if args.model == 'ssd300':
model = SSD300(n_fg_class=len(voc_bbox_label_names), pretrained_model='imagenet')
elif args.model == 'ssd512':
model = SSD512(n_fg_class=len(voc_bbox_label_names), pretrained_model='imagenet')
model.use_preset('evaluate')
train_chain = MultiboxTrainChain(model)
if args.gpu >= 0:
chainer.cuda.get_device_from_id(args.gpu).use()
model.to_gpu()
コマンドライン引数で指定されたモデルがssd300だったらSSD300の、ssd512だったらSSD512のモデルを選択して、modelという名前でインスタンスを作ります。
そのモデルのuse_presetというメソッドを実行します。引数がevaluateなので評価用のプリセットにするのでしょうか。
train_chainという名前で、MultiboxTrainChainクラスのインスタンスを作ります。前述のクラスですね。
コマンドライン引数のGPUの項目が0以上の場合は、指定されたIDのGPUを選択して、モデルをGPUへ転送します。
学習用のデータセットを作る
train = TransformDataset(ConcatenatedDataset(VOCBboxDataset(year='2007', split='trainval'), VOCBboxDataset(year='2012', split='trainval')), Transform(model.coder, model.insize, model.mean))
train_iter = chainer.iterators.MultiprocessIterator(train, args.batchsize)
trainという名前で、学習用のデータセットを作ります。
Pascal VOC 2007と2012のデータセットをダウンロードして、結合して、Transformクラスで定義したデータ拡張をしたデータセットを作っているようですね。
作ったデータセットからコマンドライン引数のバッチサイズの大きさでイテレーターを作ります。
評価用のデータセットを作る
test = VOCBboxDataset(year='2007', split='test', use_difficult=True, return_difficult=True)
test_iter = chainer.iterators.SerialIterator(test, args.batchsize, repeat=False, shuffle=False)
Pascal VOC 2007データセットから評価用のデータセットを作ります。
シリアルイテレーターを使って、バッチサイズに合わせたイテレーターを作ります。
オプティマイザーを作る
# initial lr is set to 1e-3 by ExponentialShift
optimizer = chainer.optimizers.MomentumSGD()
optimizer.setup(train_chain)
for param in train_chain.params():
if param.name == 'b':
param.update_rule.add_hook(GradientScaling(2))
else:
param.update_rule.add_hook(WeightDecay(0.0005))
オプティマイザーオブジェクトを作ります。最適化手法として、ここではモーメンタムSGDを選択しています。
アップデーターを作る
updater = training.updaters.StandardUpdater(train_iter, optimizer, device=args.gpu)
モデルのパラメータ更新用のアップデーターを作ります。
トレーナーを作る
trainer = training.Trainer(updater, (args.iteration, 'iteration'), args.out)
trainer.extend(extensions.ExponentialShift('lr', 0.1, init=1e-3), trigger=triggers.ManualScheduleTrigger(args.step, 'iteration'))
trainer.extend(DetectionVOCEvaluator(test_iter, model, use_07_metric=True, label_names=voc_bbox_label_names), trigger=triggers.ManualScheduleTrigger(args.step + [args.iteration], 'iteration'))
log_interval = 10, 'iteration'
trainer.extend(extensions.LogReport(trigger=log_interval))
trainer.extend(extensions.observe_lr(), trigger=log_interval)
trainer.extend(extensions.PrintReport(['epoch', 'iteration', 'lr', 'main/loss', 'main/loss/loc', 'main/loss/conf', 'validation/main/map']), trigger=log_interval)
trainer.extend(extensions.ProgressBar(update_interval=10))
trainer.extend(extensions.snapshot(), trigger=triggers.ManualScheduleTrigger(args.step + [args.iteration], 'iteration'))
trainer.extend(extensions.snapshot_object(model, 'model_iter_{.updater.iteration}'), trigger=(args.iteration, 'iteration'))
アップデーターと実行回数の情報を渡して、Trainerクラスのインスタンスを作ります。
そして、そのトレーナーのオプションをいろいろ設定します。
学習の実行
if args.resume:
serializers.load_npz(args.resume, trainer)
trainer.run()
コマンドライン引数でresumeが設定されている場合は、そのファイルを読み込んでネットワークにパラメータをセットします。つまり、以前の学習結果を読み込んで、続きの学習をするわけですね。
そしてトレーナーのrunメソッドを呼んで学習を実行します。
まとめ
つまりこのプログラムは、Pascal VOC 2007と2012のデータセットを読み込んで、データ拡張した上で、既存のモデルに対して学習を行うわけです。
流れはChainerの画像認識のチュートリアルとすごく似てますが、下記を調べないといけないですかね。
データセットの様式
学習用のモデルのクラスの書き方
ChainerCVのリンク(SSD300/SSD512)の使い方
公開日
広告
Chainerカテゴリの投稿
- ChainerCVで使える画像のデータ拡張
- ChainerCVで画像を出力する方法
- ChainerCVのResNetを使う
- ChainerCVのSSDに学習させてみた
- ChainerCVのデモンストレーションプログラムを読んでみた
- ChainerCVのデモンストレーションプログラムを読んでみた(推論編)
- Chainerが出力するネットワーク構造図をGraphvizで見る
- Chainerで数字を分類してみた
- ChainerのSSDのデモで物体検出をしてみる
- Chainerのチュートリアルを試してみた
- Chainerのチュートリアルを試してみた(ChainerCVでデータ拡張編)
- Chainerのチュートリアルを試してみた(データ拡張編)
- Chainerのチュートリアルを試してみた(トレーナー編)
- Chainerのチュートリアルを試してみた(畳み込みを深くする編)
- Chainerのチュートリアルを試してみた(畳み込み編)
- Chainerのデータセットの作り方(ラベル付き画像編)
- VoTTのPascal VOC出力をChainerCVのデータセットとして読み込んでみた