web-dev-qa-db-ja.com

RNNのバッチサイズと時間ステップに関する疑問

TensorflowのRNNチュートリアル: https://www.tensorflow.org/tutorials/recurrent 。バッチサイズと時間ステップの2つのパラメーターについて説明しています。概念に戸惑っています。私の意見では、RNNがバッチを導入するのは、トレーニングするシーケンスが非常に長くなる可能性があるため、バックプロパゲーションがその長い(爆発/消失勾配)を計算できないためです。したがって、長いto-trainシーケンスをより短いシーケンスに分割します。各シーケンスはミニバッチであり、そのサイズは「バッチサイズ」と呼ばれます。私はここにいますか?

時間ステップに関して、RNNはセル(LSTMまたはGRUセル、またはその他のセル)のみで構成され、このセルは連続しています。展開すると、シーケンシャルコンセプトを理解できます。ただし、シーケンシャルセルの展開は概念であり、現実的ではありません。つまり、展開された方法では実装されません。 to-trainシーケンスがテキストコーパスであるとします。次に、RNNセルに毎回1ワードをフィードし、重みを更新します。では、なぜここにタイムステップがあるのでしょうか。上記の「バッチサイズ」に対する私の理解を組み合わせると、さらに混乱します。セルに1ワードまたは複数ワード(バッチサイズ)をフィードしますか?

12
derek

バッチサイズは、ネットワークの重みを更新するために一度に考慮するトレーニングサンプルの量に関係します。したがって、フィードフォワードネットワークで、一度に1つのWordからの勾配の計算に基づいてネットワークの重みを更新するとします。batch_size=1。勾配が計算されると、単一のサンプルから、これは計算上非常に安価です。一方、それも非常に不安定なトレーニングです。

このようなフィードフォワードネットワークのトレーニング中に何が起こるかを理解するために、これを参照します single_batchとmini_batchからsingle_sampleトレーニングの非常に優れた視覚的な例

ただし、num_steps変数で何が起こるかを理解する必要があります。これは、batch_sizeとは異なります。お気づきの方もいらっしゃるかと思いますが、ここまではフィードフォワードネットワークについて説明しました。フィードフォワードネットワークでは、出力はネットワーク入力から決定され、入出力関係は学習したネットワーク関係によってマッピングされます。

hidden_​​activations(t)= f(input(t))

output(t)= g(hidden_​​activations(t))= g(f(input(t)))

サイズbatch_sizeのトレーニングパスの後、各ネットワークパラメーターに関する損失関数の勾配が計算され、重みが更新されます。

ただし、リカレントニューラルネットワーク(RNN)では、ネットワークの機能が少し異なります。

hidden_​​activations(t)= f(input(t)、hidden_​​activations(t-1))

output(t)= g(hidden_​​activations(t))= g(f(input(t)、hidden_​​activations(t-1)))

= g(f(input(t)、f(input(t-1)、hidden_​​activations(t-2))))= g(f(inp(t)、f(inp (t-1)、...、f(inp(t = 0)、hidden_​​initial_state))))

名前付けの意味から推測したように、ネットワークは以前の状態のメモリを保持し、ニューロンのアクティブ化は以前のネットワークの状態にも依存します。これにより、ネットワークはすべての状態に依存していることがわかります。ほとんどのRNN最近のネットワーク状態をより重視するために、忘却係数を採用しますが、それはあなたの質問のポイントの外です。

次に、ネットワークの作成以降、すべての状態での逆伝播を考慮する必要がある場合、ネットワークパラメーターに関する損失関数の勾配を計算することは、計算上非常に高価であると推測するかもしれませんが、計算を高速化:履歴をネットワーク状態のサブセットnum_stepsで近似します。

この概念的な説明が十分に明確でなかった場合は、 上記のより多くの数学的説明 を確認することもできます。

11
Uvar

この図は、データ構造を視覚化するのに役立ちました。

Data Structure

画像の「バッチサイズ」は、そのバッチに対してRNNをトレーニングするシーケンスの例の数です。 「タイムステップあたりの値」が入力です。」 (私の場合、RNNは6つの入力を受け取ります)そして最後に、タイムステップは、トレーニングしているシーケンスの、いわば「長さ」です。

また、再帰型ニューラルネットと、プロジェクトの1つにバッチを準備する方法についても学習しています(そして、このスレッドがそれを理解しようとして偶然見つけました)。

フィードフォワードネットとリカレントネットのバッチ処理は少し異なり、異なるフォーラムを見ると、両方の用語が混乱し、混乱を招くため、視覚化すると非常に役立ちます。

お役に立てれば。

4
Nate Smith
  1. RNNの「バッチサイズ」は、計算を高速化するためのものです(並列計算ユニットには複数のレーンがあるため)。逆伝播のためのミニバッチではありません。これを証明する簡単な方法は、異なるバッチサイズの値で遊ぶことです。バッチサイズ= 4のRNNセルは、バッチサイズ= 1のセルの約4倍高速で、損失は通常非常に近いです。

  2. RNNの「タイムステップ」については、次のコードスニペット rnn.py を見てみましょう。 static_rnn()は、各input_のセルを一度に呼び出し、BasicRNNCell :: call()はそのフォワードパーツロジックを実装します。テキスト予測の場合、たとえば、バッチサイズ= 8の場合、input_は、大きなテキストコーパス内のさまざまな文からの8単語であると考えることができます。私の経験では、「時間」または「順次依存」でモデル化する深さに基づいて、タイムステップの値を決定します。繰り返しますが、BasicRNNCellを使用してテキストコーパスの次のWordを予測するには、小さな時間ステップが機能する場合があります。一方、タイムステップサイズが大きいと、勾配爆発の問題が発生する可能性があります。

    def static_rnn(cell,
           inputs,
           initial_state=None,
           dtype=None,
           sequence_length=None,
           scope=None):
    """Creates a recurrent neural network specified by RNNCell `cell`.
       The simplest form of RNN network generated is:
    
       state = cell.zero_state(...)
       outputs = []
       for input_ in inputs:
           output, state = cell(input_, state)
       outputs.append(output)
       return (outputs, state)
    """
    
    class BasicRNNCell(_LayerRNNCell):
    def call(self, inputs, state):
    """Most basic RNN: output = new_state = 
       act(W * input + U * state + B).
    """
        gate_inputs = math_ops.matmul(
            array_ops.concat([inputs, state], 1), self._kernel)
        gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
        output = self._activation(gate_inputs)
        return output, output
    
  3. これら2つのパラメーターがデータセットと重みにどのように関連付けられているかを視覚化するには、 ErikHallströmの投稿 を読む価値があります。 この図 以上のコードスニペットから、RNNの「バッチサイズ」は重み(wa、wb、b)に影響を与えないが、「タイムステップ」には影響を与えることは明らかです。したがって、問題とネットワークモデルに基づいてRNNの「タイムステップ」を決定し、計算プラットフォームとデータセットに基づいてRNNの「バッチサイズ」を決定することができます。

1
rcnjko