※現在、ブログ記事を移行中のため一部表示が崩れる場合がございます。
順次修正対応にあたっておりますので何卒ご了承いただけますよう、お願い致します。

ChainerでGPUを使ってみよう


2017年 04月 01日

GPU(GEFORCE)がやってきて、CUDAが動くことが確認できた。
次にやることは、当然、ChainerからGPUを呼び出して高速に処理できるかどうか確認だ。

でも、どうすれば良いだろうか。
ネットをググるといろいろ見つかる。

Chainer, Cupy入門
Using GPU(s) in Chainer

でも、ちゃんと理解して読むのは面倒だ。
もっと横着して、とりあえず高速化できたことを実感したいだけなのだ。

と、思いながら眺めていると、sampleプログラムが用意されているらしい。
ということで、Example: Multi-layer Perceptron on MNIST にたどり着いた。
プログラムの説明がされているが、ここは無視して先へ行こう。

プログラムは,https://github.com/pfnet/chainer/tree/master/examples/mnist
にあり、その中の train_mnist.py を使おう。

落としてきたのを早速使おうと思ったが、引数などがわからない。
ということで、こうしてみた。

Chainer$ python train_mnist.py -h
usage: train_mnist.py [-h] [--batchsize BATCHSIZE] [--epoch EPOCH]
[--frequency FREQUENCY] [--gpu GPU] [--out OUT]
[--resume RESUME] [--unit UNIT]

Chainer example: MNIST

optional arguments:
-h, --help            show this help message and exit
--batchsize BATCHSIZE, -b BATCHSIZE
Number of images in each mini-batch
--epoch EPOCH, -e EPOCH
Number of sweeps over the dataset to train
--frequency FREQUENCY, -f FREQUENCY
Frequency of taking a snapshot
--gpu GPU, -g GPU     GPU ID (negative value indicates CPU)
--out OUT, -o OUT     Directory to output the result
--resume RESUME, -r RESUME
Resume the training from snapshot
--unit UNIT, -u UNIT  Number of units
Chainer$
このhelpから、GPUを使ったり、使わなかったりできるようである。
また、MNISTのデータセットによる学習の方法を色々変更できるようである。

ということで、とりあえず GPUを使ってみる。

Chainer$ time python train_mnist.py --gpu 0
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 20

epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.190744    0.100864              0.942366       0.9688                    2.51869
2           0.0727718   0.0912103             0.977082       0.9729                    4.94768
3           0.0478274   0.0774016             0.984665       0.9782                    7.38254
4           0.0347961   0.0868006             0.988882       0.9776                    9.83191
5           0.0270504   0.0715661             0.991232       0.9802                    12.2751
6           0.0239067   0.0839594             0.991648       0.9788                    14.727
7           0.019942    0.108413              0.993249       0.9735                    17.1812
8           0.0196713   0.123052              0.993531       0.9752                    19.6178
9           0.0170191   0.114625              0.994732       0.9745                    22.0544
10          0.0180467   0.0911058             0.994248       0.9784                    24.5015
11          0.00817388  0.085924              0.997332       0.983                     26.9448
12          0.0148509   0.0858529             0.995549       0.9829                    29.4061
13          0.0136102   0.0828243             0.995665       0.9823                    31.8695
14          0.00764308  0.087563              0.997666       0.9823                    34.3035
15          0.00990256  0.0917816             0.997049       0.9821                    36.7519
16          0.00949388  0.0919063             0.996916       0.9832                    39.2067
17          0.0117759   0.107311              0.996182       0.9788                    41.6581
18          0.00881249  0.114125              0.997466       0.9802                    44.1091
19          0.00849844  0.126373              0.997432       0.9804                    46.5538
20          0.0113175   0.127489              0.996916       0.982                     49.0085

real	0m51.140s
user	0m54.076s
sys	0m1.516s
Chainer$

そして、GPUのパラメータを省略して走らせてみた。
Chainer$ time python train_mnist.py
GPU: -1
# unit: 1000
# Minibatch-size: 100
# epoch: 20

epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.191744    0.0953521             0.9416         0.9681                    12.4707
2           0.0746516   0.0803793             0.97685        0.9751                    26.2723
3           0.0480194   0.0769992             0.98415        0.9777                    40.4596
4           0.0356241   0.0734232             0.98815        0.9809                    55.1215
5           0.0288026   0.0780974             0.991033       0.9798                    70.0129
6           0.0256375   0.0692356             0.991767       0.9816                    85.1152
7           0.019081    0.0735485             0.993517       0.9807                    100.445
8           0.0180646   0.0919526             0.994033       0.9795                    116.013
9           0.0150982   0.119397              0.995          0.9729                    132.205
10          0.0154503   0.0797152             0.995017       0.9827                    148.153
11          0.0165233   0.0966392             0.994867       0.9802                    164.572
12          0.0133162   0.0922653             0.995967       0.9796                    181.214
13          0.0105952   0.0962888             0.996283       0.9824                    198.541
14          0.00972216  0.119107              0.997          0.9777                    216.178
15          0.0147316   0.0933644             0.995667       0.9829                    233.837
16          0.00804468  0.103328              0.997283       0.9814                    252.124
17          0.00883891  0.103616              0.997533       0.9803                    270.925
18          0.0117491   0.0804654             0.9968         0.9834                    289.642
19          0.0106261   0.0900959             0.996967       0.9816                    308.791
20          0.0083072   0.106447              0.997983       0.9796                    328.388

real	5m30.403s
user	21m17.916s
sys	0m5.044s
Chainer$
ということで、0m51.140s 対 5m30.403s の時間差が出て、約6.5倍速くなったことがわかる。
詳しい調査は、次回から行うつもり。