web-dev-qa-db-ja.com

ステートフルLSTMについて

私はRNN/LSTMでこの チュートリアル を実行しており、ステートフルLSTMを理解するのに非常に苦労しています。私の質問は次のとおりです。

1.バッチサイズのトレーニング

RNNs に関するKerasのドキュメントで、バッチ内のi- th位置のサンプルの非表示状態が、次のi- th位置のサンプルの入力非表示状態としてフィードされることがわかりましたバッチ。これは、サンプル間で非表示の状態を渡したい場合、サイズ1のバッチを使用する必要があるため、オンライン勾配降下を実行することを意味しますか?サイズ> 1のバッチ内で非表示状態を渡し、そのバッチで勾配降下を実行する方法はありますか?

2. 1文字マッピングの問題

チュートリアルの段落「1文字から1文字へのマッピングのためのステートフルLSTM」には、batch_size = 1およびstateful = Trueを使用して、アルファベットの次の文字を予測することを学習するコードが与えられましたアルファベット。コードの最後の部分(53行目から完全なコードの最後まで)では、ランダムな文字(「K」)でモデルをテストし、「B」を予測してから「B」を指定すると、「C」を予測します。 。 'K'以外は問題なく動作するようです。ただし、次のTweakをコードに適用しました(最後の部分も52行目以上に維持しました)。

    # demonstrate a random starting point
    letter1 = "M"
    seed1 = [char_to_int[letter1]]
    x = numpy.reshape(seed, (1, len(seed), 1))
    x = x / float(len(alphabet))
    prediction = model.predict(x, verbose=0)
    index = numpy.argmax(prediction)
    print(int_to_char[seed1[0]], "->", int_to_char[index])
    letter2 = "E"
    seed2 = [char_to_int[letter2]]
    seed = seed2
    print("New start: ", letter1, letter2)
    for i in range(0, 5):
        x = numpy.reshape(seed, (1, len(seed), 1))
        x = x / float(len(alphabet))
        prediction = model.predict(x, verbose=0)
        index = numpy.argmax(prediction)
        print(int_to_char[seed[0]], "->", int_to_char[index])
        seed = [index]
    model.reset_states()

and these outputs:

    M -> B
    New start: M E
    E -> C
    C -> D
    D -> E
    E -> F

It looks like the LSTM did not learn the alphabet but just the positions of the letters, and that regardless of the first letter we feed in, the LSTM will always predict B since it's the second letter, then C and so on.

したがって、以前の隠し状態を現在の隠し状態の初期の隠し状態として維持することは、テスト中にたとえば文字「K」で開始した場合、文字AからJが以前に供給されなかったことを考えると、学習にどのように役立ちますか?そして、初期の隠し状態はトレーニング中と同じではありませんか?

3.文生成のための本でのLSTMのトレーニング

文章を生成する方法を学び、おそらく著者のスタイルも学ぶために、本全体でLSTMをトレーニングしたいのですが、そのテキストでLSTMを自然にトレーニングするにはどうすればよいですか(テキスト全体を入力して、LSTMに単語間の依存関係を把握させます) )LSTMをトレーニングするために、その本から「人工的に」一連の文を自分で作成する代わりに、ステートフルLSTMを使用する必要があると思いますが、どのようにしたらよいかわかりません。

17
H.M.
  1. KerasにステートフルLSTMがあることは、Keras変数を使用して状態を格納および更新することを意味し、実際には、いつでも(つまり、reset_states())。一方、非ステートフルモデルは、バッチを処理するたびに初期のゼロ状態を使用するため、_train_on_batch_、_test_on_batch_の後に常にreset_states()を呼び出したかのようになります。および_predict_on_batch_。ステートフルモデルの次のバッチで再利用される状態に関する説明は、ステートフルでないモデルとの違いについてです。もちろん、状態は常にバッチ内で流れます。そうするためには、サイズが1のバッチがない必要があります。ステートフルモデルが役立つシナリオが2つあります。

    • 分割されたデータシーケンスは非常に長いため、それら全体をトレーニングすることは現実的ではないため、トレーニングする必要があります。
    • 予測時間では、最後だけでなく、シーケンスの各時点の出力を取得する必要があります(ネットワークにフィードバックするため、またはアプリケーションで必要なため)。後で統合するためにエクスポートするモデル(バッチサイズが1のトレーニングモデルの「コピー」)で、個人的にそれを行います。
  2. アルファベットのRNNの例は、実際にはあまり役に立たないようです。文字Aで始まる場合にのみ機能します。任意の文字で始まるアルファベットを再現する方法を学びたい場合は、そのような例(アルファベットのサブシーケンスまたはローテーション)でネットワークをトレーニングする必要があります。しかし、通常のフィードフォワードネットワークは、(A、B)、(B、C)などのペアのアルファベットトレーニングの次の文字を予測することを学ぶことができると思います。この例は、何よりも実証目的であると考えています。

  3. あなたはおそらくそれをすでに読んだかもしれませんが、人気のある投稿 リカレントニューラルネットワークの不合理な有効性 は、実行したいことに沿って興味深い結果を示しています(ただし、実装の詳細にはあまり触れていません) 。テキストデータを使用してRNNをトレーニングする個人的な経験はありませんが、調査できるアプローチは多数あります。文字ベースのモデル(投稿のモデルなど)を構築して、一度に1つの文字を入力して受け取ることができます。より高度なアプローチは、テキストに対していくつかの前処理を行い、それらを一連の数値に変換することです。 Kerasには テキスト前処理関数 が含まれています。特徴空間として単一の数字を使用しても、おそらく十分に機能しないため、各Wordをワンホットエンコーディングのベクトルに変換するか、さらに興味深いことに、それぞれに最適なベクトル表現をネットワークに学習させることができます。彼らはen embedding と呼んでいます。特に前処理をさらに進めて [〜#〜] nltk [〜#〜] のようなものを調べることができます。ストップワード、句読点などを削除する場合は特にそうです。最後に、異なるサイズのシーケンスがある場合(たとえば、固定サイズの抜粋ではなく全文を使用している場合、これは重要かどうかにかかわらず)、もう少し注意して maskingを使用する必要があります。 および/または サンプルの重み付け 。正確な問題に応じて、それに応じてトレーニングを設定できます。同様のテキストを生成することを学びたい場合、「Y」は「X」(ワンホットエンコード)に類似し、1つ(またはそれ以上)の位置だけシフトされます(この場合、_return_sequences=True_および TimeDistributedレイヤー )。オーターを決定する場合、出力は softmax Dense layer になります。

お役に立てば幸いです。

24
jdehesa