LSTMがバニラリカレントニューロンネットワークよりも情報ラッチングのパフォーマンスが悪い理由


8

ベンジオらによる「勾配降下法による長期依存性の学習は難しい」という論文から実験をやり直すことで、LSTMがバニラ/単純リカレントニューラルネットワーク(SRNN)よりも長い期間情報を記憶できる理由をよく理解したいと思います1994

その論文の図1と2を参照してください。シーケンスが指定されている場合、タスクは単純です。高い値(1など)で始まる場合、出力ラベルは1です。低い値(たとえば-1)で始まる場合、出力ラベルは0です。中央はノイズです。このタスクは、モデルが正しいラベルを出力するためにミドルノイズを通過するときに開始値を覚えておく必要があるため、情報ラッチと呼ばれます。単一ニューロンRNNを使用して、このような動作を示すモデルを作成しました。図2(b)は結果を示しています。このようなモデルのトレーニングの成功頻度は、シーケンスの長さが増加するにつれて劇的に減少します。LSTMは、1994年にまだ発明されていないため、結果はありませんでした。

それで、私は好奇心が強くなり、LSTMが実際にそのようなタスクに対してより良いパフォーマンスを発揮するかどうかを見たいと思います。同様に、バニラセルとLSTMセルの両方に単一のニューロンRNNを構築して、情報ラッチをモデル化しました。驚いたことに、LSTMのパフォーマンスが低下していることがわかりました。理由はわかりません。誰かが私を説明するのを手伝ってもらえますか、または私のコードに何か問題がある場合はどうですか?

これが私の結果です:

ここに画像の説明を入力してください

これが私のコードです:

import matplotlib.pyplot as plt
import numpy as np    
from keras.models import Model
from keras.layers import Input, LSTM, Dense, SimpleRNN


N = 10000
num_repeats = 30
num_epochs = 5
# sequence length options
lens = [2, 5, 8, 10, 15, 20, 25, 30] + np.arange(30, 210, 10).tolist()

res = {}
for (RNN_CELL, key) in zip([SimpleRNN, LSTM], ['srnn', 'lstm']):
    res[key] = {}
    print(key, end=': ')
    for seq_len in lens:
        print(seq_len, end=',')
        xs = np.zeros((N, seq_len))
        ys = np.zeros(N)

        # construct input data
        positive_indexes = np.arange(N // 2)
        negative_indexes = np.arange(N // 2, N)

        xs[positive_indexes, 0] = 1
        ys[positive_indexes] = 1

        xs[negative_indexes, 0] = -1
        ys[negative_indexes] = 0

        noise = np.random.normal(loc=0, scale=0.1, size=(N, seq_len))

        train_xs = (xs + noise).reshape(N, seq_len, 1)
        train_ys = ys

        # repeat each experiments multiple times
        hists = []
        for i in range(num_repeats):
            inputs = Input(shape=(None, 1), name='input')

            rnn = RNN_CELL(1, input_shape=(None, 1), name='rnn')(inputs)
            out = Dense(2, activation='softmax', name='output')(rnn)
            model = Model(inputs, out)
            model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
            hist = model.fit(train_xs, train_ys, epochs=num_epochs, shuffle=True, validation_split=0.2, batch_size=16, verbose=0)
            hists.append(hist.history['val_acc'][-1])
        res[key][seq_len] = hists
    print()


fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(pd.DataFrame.from_dict(res['lstm']).mean(), label='lstm')
ax.plot(pd.DataFrame.from_dict(res['srnn']).mean(), label='srnn')
ax.legend()

結果はノートブックにも表示されます。これは、結果を複製したい場合に便利です。CPUのみを使用して私のマシンで実験を実行するのに1日以上かかりました。GPU対応のマシンではより高速になる可能性があります。

2018-04-18の更新

リカレントニューラルネットワークのトレーニングの難しさ」の図6に触発されたRNNの風景の図を再現してみました。ここで観察された長いシーケンスのトレーニングの難しさを説明することに関連している可能性がある、反復/タイムステップ/シーケンスの長さが増加するにつれて、損失の風景に崖が形成されるのを見るのは興味深いです。詳細については、こちらをご覧ください

ここに画像の説明を入力してください

2018-04-19の更新

@shimaoの実験を拡張します。LSTMとGRUは情報のラッチがあまり得意ではないようです。しかし、ビットリレーと呼ばれる別のタスク(@shimaoのタスク2)に切り替えると、SRNNとLSTMが同じように悪いのに、GRUのパフォーマンスが向上します。

今、私はセルタイプのパフォーマンスがタスク固有であると思う傾向があります。

タスク1:情報のラッチ(1ユニット、10回の繰り返し、10エポック)

ここに画像の説明を入力してください

タスク2:ビットリレー(8ユニット、10回の繰り返し、10エポック)

ここに画像の説明を入力してください

エラーバーは標準偏差です。

次に、興味深い質問は、なぜLSTMが情報ラッチに機能しないのかということです。タスクの単純さを考えると、それは機能するはずですよね。グラデーションに関して、景観(崖など)に関連している可能性があります。


どちらの場合も、単一ユニットのRNNを使用しているようです。あなたはそれをもっと大きくしようとしましたか、例えば10か100ですか?
Alex R.

1
いいえ、元の論文のアイデアは、最も簡単なシステムを設計して、効果的に推論できるようにすることです。複数のセルを使用する動機は何ですか?タスクはとても簡単で、シーケンスが短い場合、LSTMとSRNNの両方がうまく機能することがわかります。
zyxue

私はこの論文をよく読んでいませんが(または最近)、実験条件を正確に再現していることを確信していますか?エラーの原因となる可能性のある設定と用紙の間に、小さいが重要な違いがいくつもあると考えられます。または、別の言い方をすると、これは基本的にデバッグ情報の問題であり、比較的情報のないユニットテストが1つしかない。
Sycoraxは、モニカを復活させる'16

@ Sycorax、1994年にLSTMがまだ発明されていないため、この論文はバニラRNNについてのみです。バニラRNNに関する私の結果は彼らの結果と一致しています。LSTMのパフォーマンスが悪いのは私を困惑させる理由です。
zyxue

この論文papers.nips.cc/paper/…は興味深いかもしれません-引用した論文でBengioが提起した長期的な依存関係の問題に対処しているため、Schmidhuberが使用した実験を複製する方がより生産的なパスになる可能性があります
Sycorax氏モニカを復活させる

回答:


3

作成された例の前半は正で残りは負なので、コードにバグがありますが、データをtrainとval 分割する前にケラはシャッフルしません。つまり、すべてのvalセットが負であり、トレインセットは正の方向に偏っています。そのため、精度が0(偶然より悪い)などの奇妙な結果が得られました。

さらに、トレーニングが常に収束するように、いくつかのパラメーター(学習率、エポック数、バッチサイズなど)を調整しました。

最後に、計算を節約するために5および100タイムステップだけ実行しました。

ここに画像の説明を入力してください

奇妙なことに、GSTMはRNNとほぼ同じように動作しますが、LSTMは適切にトレーニングしません。

私は少し難しいタスクを試してみました。正のシーケンスでは、最初の要素とシーケンスの途中の要素の符号は同じです(+1または両方-1)。負のシーケンスでは、符号が異なります。LSTMのメモリセルを追加すると、ここでメリットが得られることを期待していました

ここに画像の説明を入力してください

それはRNNよりもうまく機能するようになりましたが、ごくわずかであり、GRUが何らかの理由で勝っています。

単純なタスクでRNNがLSTMよりも優れている理由に対する完全な答えはありません。単純なRNNでは問題が簡単であるという事実に加えて、LSTMを適切にトレーニングするための適切なハイパーパラメーターが見つからなかったのではないかと思います。おそらく、パラメータが非常に少ないモデルは、ローカルミニマムでスタックする傾向があります。

変更されたコード


私はあなたの実験を拡張し、一貫した結果を得ました。パフォーマンスはタスク固有である可能性が高いと思います。
zyxue

0

それが違いになるかどうかはわかりませんが、次のように使用します。

out = Dense (1, activation='sigmoid', ...

そして

model.compile(loss='binary_crossentropy', ...

バイナリ分類問題の場合。


1
数学的には2つは同じだと思います。特に、シグモイドはクラスが2つしかないsoftmaxと同等です。binary_crossentropyは、結局のところ、2つのクラスの相互エントロピーです。この問題は私を本当に困惑させています、そして誰かが良い説明を提供することができるなら私は報奨金を増やすことにオープンです。
zyxue

バージョンごとに同じパラメーターを使用していますか?LSTMはより複雑で、より多くのデータ、より多くのエポック、異なる学習率などを必要とする可能性があります。@ zyxue
Wayne
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.