LoginSignup
4
8

More than 5 years have passed since last update.

chainerでoptimizerの性能を比較する

Last updated at Posted at 2017-01-02

はじめに

chainerのMnistサンプルを使って、optimizerを比較する。

環境

GPU:GTX1070
OS:Ubuntu14.04
CUDA:8.0RC
cuDNN:5.1
python:2.7.6
chainer:1.14.0
など

jsonファイルをcsvファイルに変換するコードを作成

mnistサンプルでは以下の83、84行部分

train_mnist.py
#Write a log of evaluation statistics for each epoch
trainer.extend(extensions.LogReport())

でlogにlossやaccuracyをjson形式で書き込んでいる。jsonは扱いにくいので、csvに変換するコードをまず作る。

json2csv.py
#!/usr/bin/env python
import json, csv
import argparse

parser = argparse.ArgumentParser(description='experimentation of json to csv')
parser.add_argument('--logfilename', '-l', default='log',
                    help='name of Log file')
parser.add_argument('--csvfilename', '-c', default='log_csv.csv',
                    help='name of output csv file')
args = parser.parse_args()

filename = args.logfilename

#read json file
json_data = open(filename)
data = json.load(json_data)
json_data.close()

#open csv file
f = open(args.csvfilename, 'ab')
csvWriter = csv.writer(f)


header_list = ['iteration', 'epoch', 'main/loss', 'main/accuracy',
               'validation/main/loss', 'validation/main/accuracy']
csvWriter.writerow(header_list)

print 'len(data[0])',
print len(data[0])

for i in range(len(data)):
    if len(data[i]) == 4:
        contents_list = [data[i]["iteration"], data[i]["epoch"], data[i]["main/loss"], data[i]["main/accuracy"]
                         ]
    elif len(data[i]) == 6:
        contents_list = [data[i]["iteration"], data[i]["epoch"], data[i]["main/loss"], data[i]["main/accuracy"],
                         data[i]["validation/main/loss"], data[i]["validation/main/accuracy"]]


    csvWriter.writerow(contents_list)

f.close()

これでExcelとかでグラフ化して比較できる。

比較対象

比較対象は以下
(1)通常のSGD
(2)Momentum
(3)AdaGrad
http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf
(4)Adam
https://arxiv.org/pdf/1412.6980v8.pdf
(5)RMSProp

mnist_train.pyの設定を変更する

変更点1:parserにoptimizerを追加
コマンドからoptimizerを選択できるようにするため、parser内に以下を追加。

train_mnist.py
parser.add_argument('--optimizer', '-p', type=str, default='Adam',
                    help='optimizer')

変更点2:optimizerの選択
以下の部分

train_mnist.py
optimizer = chainer.optimizers.Adam()

をargs.optimizerによって選択できるように変更する。

train_mnist.py
# Setup an optimizer
if args.optimizer == 'AdaGrad':
    optimizer = chainer.optimizers.AdaGrad()
elif args.optimizer == 'SGD':
    optimizer = chainer.optimizers.SGD()
elif args.optimizer == 'MomentumSGD':
    optimizer = chainer.optimizers.MomentumSGD()
elif args.optimizer == 'RMSprop':
    optimizer = chainer.optimizers.RMSprop()
else:
    optimizer = chainer.optimizers.Adam()

変更点3:LogReport()の変更
デフォルトでは1 epochごとにlogにlossやaccuracyが記録されるが、1 epoch時点でかなりlossが減少してるため、もっと細かく記録したい。そこで84行目の以下の部分

train_mnist.py
trainer.extend(extensions.LogReport())

を以下のようにして、100 iterationごとに記録させる。

train_mnist.py
trainer.extend(extensions.LogReport(trigger=(100, 'iteration')))

LogReport()の引数に関しては、chainer/training/extensions/log_report.pyに説明書きがある。

実験

隠れ層のユニット数はデフォルトの100、epoch数は10、batchサイズはデフォルトの100で実験した。例えば、RMSpropの場合の実行コマンドは以下。

python train_mnist_opt.py -g=0 -e=10 -p='RMSprop' -u=100

結果

結果は以下のグラフ。横軸がiteration、縦軸がtrainingのloss。
optimizer_graph.png

Adamは予想通りいいが、Momentumが意外と頑張ってる。条件を変えればまた違ってくるかも。

コードの場所

今回のコードはこちらにあげてます。
https://github.com/masataka46/compare_opt_by_chainer

4
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
8