web-dev-qa-db-ja.com

さまざまな時間ステップを持つRNNのKerasマスキング

時間の長さが変化するシーケンスを使用して、KNNをRNNに適合させようとしています。私のデータは、フォーマット(sample, time, feature) = (20631, max_time, 24)のNumpy配列にあります。ここで、max_timeは、実行時に、タイムスタンプが最も多いサンプルで使用可能なタイムステップの数として決定されます。明らかに、最長のものを除いて、各時系列の最初に0を埋め込みました。

最初は次のようにモデルを定義しました...

model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(100, input_dim=24))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_Epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y))

完全を期すために、損失関数のコードを次に示します。

def weibull_loglik_discrete(y_true, ab_pred, name=None):
    y_ = y_true[:, 0]
    u_ = y_true[:, 1]
    a_ = ab_pred[:, 0]
    b_ = ab_pred[:, 1]

    hazard0 = k.pow((y_ + 1e-35) / a_, b_)
    hazard1 = k.pow((y_ + 1) / a_, b_)

    return -1 * k.mean(u_ * k.log(k.exp(hazard1 - hazard0) - 1.0) - hazard1)

そして、これがカスタムアクティベーション関数のコードです:

def activate(ab):
    a = k.exp(ab[:, 0])
    b = k.softplus(ab[:, 1])

    a = k.reshape(a, (k.shape(a)[0], 1))
    b = k.reshape(b, (k.shape(b)[0], 1))

    return k.concatenate((a, b), axis=1)

モデルを適合させ、いくつかのテスト予測を行うと、テストセット内のすべてのサンプルはまったく同じ予測を取得しますで、これは怪しげなようです。

マスキングレイヤーを削除すると状況は良くなります。そのため、マスキングレイヤーに何か問題があると思いますが、私が知る限りでは、ドキュメントに正確に従いました。

マスキングレイヤーで誤って指定されているものはありますか?他に何か不足していますか?

21
John Chrysostom

実際のデータなしでは検証できませんでしたが、RNNで同様の経験をしました。私の場合、正規化は問題を解決しました。モデルに正規化レイヤーを追加します。

4
vagoston

マスキングの実装方法は正しいはずです。 (samples、timesteps、features)の形状のデータがあり、データのないタイムステップを同じサイズのゼロマスクでマスクしたい場合features引数、次にMasking(mask_value=0., input_shape=(timesteps, features))を追加します。ここを参照してください: keras.io/layers/core/#masking

モデルが単純すぎる可能性がある、またはエポック数がモデルですべてのクラスを区別するには不十分である可能性があります。このモデルを試してください:

model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(256, input_dim=24))
model.add(Dense(1024))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_Epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y)) 

それがうまくいかない場合は、エポックを数倍にしてみて(例:200、400)、結果が改善されるかどうかを確認します。

5
Robert Valencia