web-dev-qa-db-ja.com

Tensorflow LSTM入力形状について

N = 4000個のサンプルで構成されるデータセットXがあり、各サンプルはd = 2個の特徴で構成されています(連続値)スパンバックt = 10タイムステップ。また、各サンプルの対応する「ラベル」もありますが、これも時間ステップ11で連続値です。

現在、私のデータセットはX:[4000,20]、Y:[4000]の形状です。

D個の特徴の10個の以前の入力を考慮して、TensorFlowを使用してLSTMをトレーニングしてYの値(回帰)を予測しますが、TensorFlowでこれを実装するのは大変です。

私が現在抱えている主な問題は、TensorFlowが入力がフォーマットされることをどのように期待しているかを理解することです。 this などのさまざまな例を見てきましたが、これらの例では、連続した時系列データの1つの大きな文字列を扱います。私のデータは異なるサンプルであり、それぞれ独立した時系列です。

18
Renier Botha

tf.nn.dynamic_rnnのドキュメント 状態:

inputs:RNN入力。 time_major == False(デフォルト)の場合、これは形状のテンソルである必要があります:[batch_size, max_time, ...]、またはそのような要素の入れ子になったタプル。

あなたの場合、これは、入力が[batch_size, 10, 2]の形状を持つ必要があることを意味します。 4000のシーケンスすべてを一度にトレーニングする代わりに、各トレーニングの反復でbatch_sizeだけを使用します。次のようなものが動作するはずです(わかりやすくするために形状を追加しました)。

batch_size = 32
# batch_size sequences of length 10 with 2 values for each timestep
input = get_batch(X, batch_size).reshape([batch_size, 10, 2])
# Create LSTM cell with state size 256. Could also use GRUCell, ...
# Note: state_is_Tuple=False is deprecated;
# the option might be completely removed in the future
cell = tf.nn.rnn_cell.LSTMCell(256, state_is_Tuple=True)
outputs, state = tf.nn.dynamic_rnn(cell,
                                   input,
                                   sequence_length=[10]*batch_size,
                                   dtype=tf.float32)

documentation から、outputs[batch_size, 10, 256]の形になります。つまり、各タイムステップごとに1つの256出力になります。 stateは、形状の タプル[batch_size, 256]になります。それから、各シーケンスごとに1つの最終値を予測できます。

predictions = tf.contrib.layers.fully_connected(state.h,
                                                num_outputs=1,
                                                activation_fn=None)
loss = get_loss(get_batch(Y).reshape([batch_size, 1]), predictions)

outputsstateの形の256は、cell.output_sizeによって決定されます。 cell.state_size。上記のLSTMCellを作成する場合、これらは同じです。 LSTMCellドキュメント も参照してください。

11
fwalch

(この答えは、直接np.reshape()が最終的な配列を望みどおりに編成しない場合の問題を「アドレス付け」します。入力の最終構成)。

最終的にRNNの入力形状を供給するという問題を解決し、もう混乱しないように私の個人的な試みで、これについて「個人的な」説明をします。

私の場合(そして、他の多くの人がこの組織体系を機能マトリックスに持っているかもしれないと思います)、ほとんどのブログは「助けてはいけません」。 RNN向けに2D特徴マトリックスを3D形状マトリックスに変換する方法を試してみましょう。

機能マトリックスにこの組織タイプがあるとしましょう5の観測値(つまり行-慣習的には使用する最も論理的な用語)、各行には、各タイムステップに2個の機能があります(そして2つのタイムステップがあります)、このように:

dfは私の言葉を視覚的に理解するためのものです)

In [1]: import numpy as np                                                           

In [2]: arr = np.random.randint(0,10,20).reshape((5,4))                              

In [3]: arr                                                                          
Out[3]: 
array([[3, 7, 4, 4],
       [7, 0, 6, 0],
       [2, 0, 2, 4],
       [3, 9, 3, 4],
       [1, 2, 3, 0]])

In [4]: import pandas as pd                                                          

In [5]: df = pd.DataFrame(arr, columns=['f1_t1', 'f2_t1', 'f1_t2', 'f2_t2'])         

In [6]: df                                                                           
Out[6]: 
   f1_t1  f2_t1  f1_t2  f2_t2
0      3      7      4      4
1      7      0      6      0
2      2      0      2      4
3      3      9      3      4
4      1      2      3      0

ここで、値を使用してそれらを操作します。ここで重要なのは、RNNがそのアーキテクチャに基づいているため、入力に「タイムステップ」ディメンションを組み込むことです。その次元は、2D配列をタイムステップの数だけ前後に積み重ねていると想像できます。この場合、2つのタイムステップがあります。したがって、2つの2Dアレイがスタックされます。1つはtimestep1用で、その後ろはtimestep2用です。

実際には、3D入力で行う必要があるものの、まだ5つの観測があります。問題は、それらを別の方法で配置する必要があることです。RNNは、最初の配列(つまり、timestep1)の最初の行(または指定されたバッチ-ここでは単純にします)と2番目のスタック配列の最初の行(つまり、 timestep2)。次に、2行目...最後の行(この例では5行目)まで。 S o、各タイムステップの各行で、2つの機能が必要です。もちろん、それぞれがそのタイムステップに対応する異なる配列に分離されている必要があります。これを数字で見てみましょう。

わかりやすくするために2つの配列を作成します。 dfの組織的なスキームのために、最初の2列として最初の2列(つまり、timestep1の機能1と2)を取得する必要があることに気づいたかもしれません。最後の2列、つまり、スタックの2番目の配列としての3番目と4番目

In [7]: arrStack1 = arr[:,0:2]                                                       

In [8]: arrStack1                                                                    
Out[8]: 
array([[3, 7],
       [7, 0],
       [2, 0],
       [3, 9],
       [1, 2]])

In [9]: arrStack2 = arr[:,2:4]                                                       

In [10]: arrStack2                                                                   
Out[10]: 
array([[4, 4],
       [6, 0],
       [2, 4],
       [3, 4],
       [3, 0]])

最後に、行う必要があるのは、両方が同じ最終構造の一部であるかのように両方の配列をスタックすることです(「一方が他方の後ろに」)。

In [11]: arrfinal3D = np.stack([arrStack1, arrStack2])                               

In [12]: arrfinal3D                                                                  
Out[12]: 
array([[[3, 7],
        [7, 0],
        [2, 0],
        [3, 9],
        [1, 2]],

       [[4, 4],
        [6, 0],
        [2, 4],
        [3, 4],
        [3, 0]]])

In [13]: arrfinal3D.shape                                                            
Out[13]: (2, 5, 2)

それだけです。2D機能マトリックスの構成を考慮して、RNNセルにフィードする準備ができた機能マトリックスがあります。

(このすべてに関する1つのライナーについては、次を使用できます。

In [14]: arrfinal3D_1 = np.stack([arr[:,0:2], arr[:,2:4]])                           

In [15]: arrfinal3D_1                                                                
Out[15]: 
array([[[3, 7],
        [7, 0],
        [2, 0],
        [3, 9],
        [1, 2]],

       [[4, 4],
        [6, 0],
        [2, 4],
        [3, 4],
        [3, 0]]])

お役に立てれば!

2
Ezarate11