FXのデータで研究を始めてみたものの、全く収束する気配がありません。
もしかしたらLSTMの使い方を間違っているのかも?
確認のため簡単なシミュレーションデータで実装してみました。
データはよく使われるsin波(に少し手を加えたもの)です。

簡単なLSTMモデルの定義
loss = gloss.L2Loss() # 損失関数
### sequentilalモデルを作ってもよいけれど、これでいく!
class RNNModel(nn.Block):
def __init__(self, rnn_layer, **kwargs):
super(RNNModel, self).__init__(**kwargs)
self.rnn = rnn_layer
self.dense = nn.Dense(1)
def forward(self, inputs, state):
X=inputs
Y, state = self.rnn(X, state)
output = self.dense(Y)
return output, state
def begin_state(self, *args, **kwargs):
return self.rnn.begin_state(*args, **kwargs)
100エポックでの結果

200エポックでの結果

結果を見ると、エポックを進めるたびに
- 損失関数の結果が、いい感じに収束している(#1の図)
- 予測結果が実測値に近づいている(#2の図)
- 予測値と実測値の差の分布が小さくなっている(#3の図)
ので、大きく間違ってはいないのではないか?と考えています。
実装時に特に悩んだのは次の2点
- LSTMの入力データってどんな形状とすべきなのか?
特徴量、タイムステップ、バッチサイズの3次元データになるのですが、以前cntkを使っているときには軸をどうすればよいのかわからず、サンプル、英語ブログを調べまくって「多分こうだろう・・・」でやっていました。
ところがmxnetではドキュメントにしっかりと明記してありました!
data: input tensor with shape (sequence_length, batch_size, input_size) when layout is “TNC”. For other layouts, dimensions are permuted accordingly using transpose() operator which adds performance overhead. Consider creating batches in TNC layout during data batching step.
http://mxnet.incubator.apache.org/api/python/gluon/rnn.html#mxnet.gluon.rnn.RNN
以前は普通にNTCで考えていたので、「どうやって時系列で処理しているのか?」理解できなかったのですが、正しくはTNCということでスッキリしました。
2. 隠れ層の初期化タイミングはいつか?
dive into deeplearningのサンプルを見ていてわからなくなっていたのですが、よくよく読み込むことで
・繰り返し毎に初期化(全く引き継がない)
でよいとわかりました。
色々と試行錯誤しているうちに
ラーニングレートとバッチサイズはハイパーパラメータ(人が決める)である
を痛感しました。
バッチサイズなんて処理速度に影響するだけだろう?と考えていたのが間違いでしたw
ディープラーニングはあまりに深すぎて、理解できないこと、もっと知りたいことがたくさんあります。
FXに応用できるまではまだまだ時間がかかりそうです・・・(´;ω;`)ウゥゥ