最適な学習実行環境の選び方
Neural Network Consoleでは、ニューラルネットワークの学習のためにCPU、もしくはより高速な学習を実現するGPUを用いることができます。また、Cloud版では複数のGPU(マルチGPU)を用いて、さらに学習を高速化することもできます。
本チュートリアルでは、学習するネットワークに応じた最適な学習実行環境を選択する方法について解説します。
1 必要なメモリ量を推定する
学習時に必要なメモリ量は、大まかに言ってニューラルネットワークに含まれるニューロンの数と、CONFIGタブのGlobal Configで設定するBatch Size、およびニューラルネットワークのパラメータの数で決まります。
画面右に表示されるStatisticsのOutputは、編集中のネットワーク全体のニューロンの数を示します。また、画面右に表示されるStatisticsのCostParameterは、編集中のネットワーク全体に含まれるパラメータのサイズを示します。学習中に必要なメモリ量は、これらを元に以下の式で求めることができます。
必要メモリ量(byte) =
ニューロンの数×Batch Size×2(data & grad)×4(byte)+
パラメータ数×2(data & grad)×4(byte)
学習を行う際は、上記で求められる必要メモリ量に対し余裕を持ったメモリを搭載した学習実行環境を選択するようにします。
入力データサイズが非常に大きい、レイヤー数が非常に多い、Affineなど大量のパラメータを必要とするレイヤーを多用している、などのケースでは、上記必要メモリ量が簡単に学習実行環境の搭載メモリ量をオーバーしてしまうことがあります。このような場合は、学習の設定を変更する必要があります。詳しくは「メモリ不足問題とその対策」をご参照ください。
2 学習に要するおおよその時間を推定する
1GPUでの学習に要する時間は、最適化の最小単位である1 Iterationの演算に要する時間に、1 epochに含まれるIteration数(学習データ数に比例)、およびEpoch数(CONFIGタブ、Global ConfigのMax Epochで指定)を掛けることで推定することができます。
1GPUでの学習に要する時間 =
× 1 Iterationの演算に要する時間
× 1 epochに含まれるIteration数
× Epoch数
評価を実行するepochにおいては、さらに評価のための演算時間が必要になるため、実際の学習完了までの時間はこれよりやや長くなります。
マルチGPUを用いた場合、ここから学習に要する時間を最大でGPU数分の1にまで短縮することができます。
学習実行環境や学習の設定と、学習に要する時間には以下の関係があります。
- 学習に要する時間は最適化の最小単位である1 Iterationの演算に要する時間に比例して長くなる
- 学習に要する時間はデータの数に比例して長くなる
- 学習に要する時間はMax Epochに比例して長くなる
- 学習に要する時間はGPU数に反比例する
1 Iterationの演算に要する時間は、Profile機能を用いることで実際の値を測定することができます。Profile機能による測定結果のうち、let_data + forward_all + backward_all + update + monitor_lossの数値の合計が、おおよそ1 Iterationの演算に要する時間(ms)となります。
1 epochに含まれる実際のIteration数は、学習に用いるデータセットに含まれるデータ数をBatch Size(CONFIGタブ、Global Configで指定)で割ることで求めることができます。
3 GPU、マルチGPUでの学習に適さないケース
Neural Network Consoleでは、GPUを用いることで、ほとんどのケースでCPUを用いた場合の10倍~数百倍高速に学習を完了することができます。また、マルチGPUを用いることで、最大で学習に要する時間をGPU数分の1にまで短縮することができます。しかしながら、学習するネットワークによってはGPUやマルチGPUを用いてもそれほど速度が向上しないこともあります。
GPUやマルチGPUでの性能向上効果が得られにくいケースは以下の通りです。
学習に要する時間が極めて短いニューラルネットワーク
1 Iterationの演算に要する時間が極端に短い場合(10ms以下など)、あるいは学習全体に要する時間が極端に短い場合(10分未満など)では、学習開始までの準備に要する時間や、マルチGPUの場合GPU間の通信に要する時間等、その他のオーバーヘッドが支配的になり、GPUやマルチGPUを用いても、学習速度がそれほど向上しないことがあります。
1つのデータのサイズが小さい、もしくは1つのレイヤーの処理にかかる時間が短いニューラルネットワーク
Profile機能による測定の結果、1 Iterationの演算に要する時間がそれなりであっても、各レイヤーのForward、Backward演算に要する時間が極めて短く(0.1ms以下など)、代わりにレイヤーの数や繰り返し演算回数が膨大であるようなネットワークではGPUによる高速化効果が得られづらいことがあります。
演算量に対してパラメータサイズが大きいニューラルネットワーク
画面右に表示されるStatisticsのCostMultiplyAddは、編集中のネットワーク全体に含まれる乗加算回数を示します。CostMultiplyAddは演算量の1つの目安として参照することができます。また、CostParameterは、編集中のネットワーク全体に含まれるパラメータ数を示します。
ConvolutionではなくAffineレイヤーを多用するなど、演算量に対するパラメータ数の割合が大きいケース(CostMultiplyAddがCostParameterの10倍以下など)では、演算時間に対するGPU間のパラメータ交換に要する時間が支配的になるため、マルチGPUによる高速化効果が得られづらくなります。
4 メモリ不足問題とその対策
通常Neural Networkの学習には多くのメモリを必要とします。メモリ量を気にせずサイズの大きいデータや複雑なネットワーク構造を指定すると、実際は思った以上に多くのメモリが消費されていることがあります。
正しいネットワーク構造を設計しているにもかかわらず学習などが正しく実行できない時は、学習実行環境の搭載メモリ量が十分ではない可能性があります。
学習実行環境のメモリが必要メモリ量に対して不足していることが疑われる場合は、以下のいずれかの方法で使用メモリ量を削減します。
Batch Sizeを小さくする
CONFIGタブ、Global ConfigでBatch Sizeを小さくすることで、使用メモリ量を削減することができます。
メモリ不足が疑われる場合は、ひとまずBatch Sizeを1に設定して学習処理が実行されるかどうかを確認することで、素早く原因を特定することができます。
Batch Sizeを小さくすると、これに伴い学習結果として得られる精度も変わってきます。
得られる精度を変えずにBatch Sizeを変更するには、Batch Sizeの変更に合わせて、OptimizerのLearning Rateを変更します。より具体的には、Batch Sizeを半分にするたびに、Learning Rateも半分に設定します。
この時、Batch Sizeを半分にするたびにOptimizerのUpdate Intervalを倍にすることで、学習結果を元のBatch Sizeで学習した結果にさらに近づけることができます。
ネットワーク構造を見直す
レイヤー右下に表示されるニューロン数のバーの長さを参考に、ネットワークのどの箇所で多くのメモリを消費しているのかを特定し、全体の使用メモリ量を小さくするようにネットワーク構造を編集します。