システムトレード構築編

【シストレ構築】DeepLearningのハイパーパラメータ

機械学習システムトレーダーの皆様、こんにちは。

DeepLearning(ディープラーニング)のライブラリを使っているときの悩みどころの一つに、ハイパーパラメータをどうやってチューニングするのかというのがありますよね。

システムトレードの構築では、バックテストの時にパラメータの組み合わせを総当たり的に試していく最適化という作業があります。これは時間のかかる作業です。

DeepLearningを利用したシストレでもこのバックテストの最適化作業はあるのですが、それとは別に、ストラテジーに採用するモデルを構築する時にも似たような作業があります。モデルのパラメータ、いわゆるハイパーパラメータも、パラメータ値の組み合わせを総当たり(グリッドサーチ)でやっていく必要があります。

しかしこの作業、バックテストの最適化とは比べにものにならないぐらい、時間のかかる作業になります。ついでに電気代もかかります(涙)。なので、ある程度、あたりをつけて効率よくやる必要があります。

このハイパーパラメータの値をどうするかですが、調べると基本的な考え方はでてきます。でも実際にどういう数値でやっているのかは意外と見つけることができません。データの特性や量に依存するので、一概に言えないからだと思います。

そこで、私が DeepLearning でシストレを構築するときのハイパーパラメータをどうしているのか、実際の値を添えてまとめてみました。

私はDeepLearningの理論はほとんど理解していません。本記事は学術的な根拠があるわけではなく、あくまで個人的な経験則になります。考え方の一つぐらいに捉えていただければと思います。

Batch size バッチサイズ

バッチサイズの特長としては下記になります。

  • 学習精度にはそれほど影響しない(?)
  • 大きいほど学習が速い
  • 大きいほどGPUメモリが必要

まず学習精度についてですが、値が小さいほどデータ1件の重みが増す、つまりデータ1件1件に特化して学習していきます。

システムトレードにおいて、それがいいことなのかそうでないのかよくわかりませんが、「バッチサイズが変わったところで精度の違いは体感できるほどではない」というのが、これまでの経験で得ています。なので私は、バッチサイズの決定において精度への関連度は無視しています。精度については、後述する学習率で調整することが多いです。

というわけで、学習速度を速めるためにできるだけ大きい値を使っています。ただし大きすぎるとGPUのメモリサイズを超えてしまい学習時にメモリエラーになります。この辺りはユニット数やニューラルネットのレイヤー数との兼ね合いもあるので、適正値はなんともいえません。

「バッチサイズ * ユニット数 * レイヤー数」がGPUメモリ内に収まるなら、バッチサイズの値は何でもいいと思います。(※ これはバッチサイズの算出式ではありません。考え方のイメージです。)

私はだいたいバッチサイズは5,000~30,000ぐらいにしています。グリッドサーチは5,000~10,000きざみにすることが多いです。

バッチサイズについて調べると100とか500とかにする事例も出てくるのですが、シストレの場合はデータ件数が多いので、これぐらい小さい値にすると学習が全然終わりません。

使用するデータが1分足で10年分とすると、データ件数は

60分 * 24時間 * 5日 * 52週 * 10年 = 3,7744,000件

にもなります。

データ300~400万件に対して、ミニバッチサイズが100とかだと小さすぎます。もっと大きい値にして、ガンガン回そうという考えで、最低5,000からにしています。

Unit ユニット数

ユニット数はストラテジーのパフォーマンスに大きく影響しますが、因果関係がよくわかりません。ユニット数が大きいほうが表現力があがると言われていますが、単純に大きければ大きいほど良いというものでもないです。少ないユニット数でパフォーマンスがいいときもあれば、大きい時にパフォーマンスがいいこともあります。

よくわかっていませんが、特徴数(入力層の素子数)の1/2~2倍ぐらいの範囲で、特徴数の1/4刻みでやっています。

たとえば特徴数が400個の場合は、ユニット数は [200,300,400,500,600,700,800] で試しています。

極端に大きい値にすると、すぐにGPUのメモリエラーになるので、特徴数が多い場合は1.5倍ぐらいまでにしておくこともあります。

中間層の数(レイヤー数)

層数も悩みどころです。基本的に大きければ大きいほど精度が上がるはずなのですが、実際はそうでもなかったりします。中間層2層のほうが中間層5層よりバックテストの結果がいいということはよくあります。(DeepLearningとは何だったのか、、、)

「層数が大きいほど表現力があるが、それゆえ過学習も起きやすい」と、いったところでしょう。

私は中間層が2~5ぐらいの範囲でやっています。DeepLearningのというからには、もっと層を増やしてやってみたいのですが、これ以上増やすとGPUのメモリーエラーが発生してしまいます。GPUは970を使っているのですが、もっといいグレードのGPUを買っておけばよかったと思っています。

Dropout ドロップアウト率

ドロップアウトなし(0%)30~40%でやることが多いです。

ドロップアウトなしだと過学習になると思うのですが、実際にバックテストするとドロップアウトなしのほうが良結果のことがあるので、毎回ドロップアウトなしも試しています。ただドロップアウトありの方が、良い結果になることが多いのは確かです。

ドロップアウト率が高すぎると、うまく学習できないことがあります。60%や70%まで上げると、学習できません。

Chainerは、ドロップアウト率のデフォルト値は50%ですが、50%だと上手く学習できなかったり、精度が良くなかったりすることがあるので、気持ち下げて30~40%でやっています。

学習率

一番、学習結果に直結するパラメータだと思います。学習率によっては、未学習だったり発散が大きすぎたりするので調整が難しいです。データ量や特徴量、バッチサイズによって適正値が違うので、これも値を少しずつ変えて試す必要があります。

Adam関数の場合で、0.001(デフォルト値)、0.0005、0.0001、0.00005、0.000001あたりでやってみたりしています。

ソフトマックス関数の結果がどのデータでも同じ確率になるという場合がよくあります。未学習というのか収束しているというのかよくわかりませんが、学習率を下げていくことで改善することがあります。


以上になります。

ハイパーパラメータの設定は、毎回手探りでいろいろ試しています。他の方が、どうやっているのか知りたいですね。

COMMENT

メールアドレスが公開されることはありません。