私の元の設定では、
X1 = (1200,40,1)
y1 = (1200,10)
その後、私は自分のコードで完璧に動作します:
model = Sequential()
model.add(LSTM(12, input_shape=(40, 1), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense(10)))
さらに、X1
およびy1
と同じサイズの時系列データをさらに取得しました。つまり、
X2 = (1200,40,1)
y2 = (1200,10)
次に、X1
、X2
およびy1
、y2
を3D配列としてスタックします。
X_stack = (1200,40,2)
y_stack = (1200,10,2)
次に、keras
コードを次のように変更してみます。
model = Sequential()
model.add(LSTM(12, input_shape=(40, 2), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense((10,2))))
私のコードは、3D配列X_stack
およびy_stack
を2D配列として再形成せずに直接操作する必要があります。設定の変更方法を教えていただけませんか?ありがとうございました。
私はこの質問に簡単な答えを出すことはできませんが、LSTMのいくつかの基本的な概念について説明が必要だと思います(1対1、1対多、...)
上部構造のRNN(LSTMを含む)はsequentialなので、CNNはspatialのように、時間のような相関を見つけるように構築されます空間のような相関関係を見つけるために構築されています
次に、1対1、1対多、多対1および多対多でLSTMのさらなる差別化があります。 Kerasでの多対1および多対多のLSTMの例に示すように
ここで必要なネットワークタイプは、ポイント5の Kerasでの多対1の多対多のLSTMの例 であり、次のように述べています。
ステップ数が入力/出力長と異なる場合の多対多:これはKerasでは非常に困難です。それをコーディングする簡単なコードスニペットはありません。
入力形状はX_stack = (1200,40,2)
で、出力形状はy_stack = (1200,10,2)
であるためタイムタイプの数が異なるため、タイプ5です(40
入力と10
出力)
等しい数の入力タイムステップと出力タイムステップを持つことができれば、入力データと出力データ(numpy.reshape
)keras LSTM Feeding input with a right shapeのように([and]in the array)。これは、2Dへの再形成(つまり、平坦化)を意味するものではありません。 https://machinelearningmastery.com/timedistributed-layer-for-long-short-term-memory-networks-in-python/ は、多対多のLSTMを構築するための完全な例ですequalTimeDistributed
レイヤーを使用した入力および出力タイムステップ
完全性のためだけに、spatio-temporalデータについてもCNN-LSTMsがありますが、2つの積み重ねた時系列には明示的な空間相関はありません:
3D数量、つまり時間とともに変化するボリューム内の分布があり、これを学習したい場合は、CNN-LSTMネットワークを使用する必要があります。このアプローチでは、3D情報と時間情報の両方が保持されます。 3D情報が保持されるとは、空間情報が破棄されないことを意味します。通常、LSTMのような時間のような学習者では、この空間情報は多くの場合、画像をLSTMで処理する前にフラット化することによって破棄されます。 (時空間)CNN-LSTMをケラスで構築する方法の完全なチュートリアルは次のとおりです https://machinelearningmastery.com/cnn-long-short-term-memory-networks/
配列について報告した形状のどこかにエラーがあると想定しています。私はy_stack.shape == (1200, 10, 2)
を推測しています、それは正しいですか?
ただし、ここにあなたが説明することを実行する1つの可能性があります。
model = Sequential()
model.add(LSTM(12, input_shape=(40, 2), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add(Dense(10 * 2))
model.add(Reshape((10, 2)))
ネットワークの出力は、Dense
レイヤーによって2Dテンソルとして作成され、Reshape
によって3Dテンソルに再形成されます。入出力の観点からは、これは指定したとおりに動作するはずです。
X_stack.shape()
の出力タプルを使用できます。
model = Sequential()
model.add(LSTM(12, input_shape=(X_stack.shape[1], X_stack.shape[2]),return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense((10,2))))
スタックする各アレイのパラメーターを共有する必要があると想定しています。
まったく新しい機能を積み重ねている場合、それぞれに関連付けられたターゲットはありません。
完全に異なる例を積み重ねている場合は、3D配列を使用せず、通常のように最後に追加するだけです。
ソリューション
この問題を解決するには、 KerasのTimeDistributedラッパー を利用します。
LSTMレイヤーは、形状(j, k)
を期待します。ここで、j
はタイムステップの数、k
はフィーチャの数です。配列を入力と出力の3Dとして保持する必要があるため、フィーチャの次元とは異なる次元にスタックする必要があります。
簡単な補足:
アプローチの違いに注意することが重要だと思います。フィーチャディメンションを積み重ねると、同じタイムステップで複数のフィーチャを使用できます。その場合は、同じLSTMレイヤーを使用し、このルートを使用しないことをお勧めします。 3D入力と3D出力が必要なため、同じLSTMレイヤーを個別に適用できるスタックする新しいディメンションを作成することを提案します。
TimeDistributed:
このラッパーは、1
インデックスの各配列にレイヤーを適用します。 X1
配列にX2
配列と1
配列をスタックし、TimeDistributedラッパーを使用することで、スタックする各配列に個別にLSTMレイヤーを適用します。元のモデルの要約と更新されたモデルの要約のパラメーター数がまったく同じであることに注意してください。
実装手順:
最初のステップは、(40, 2)
の入力を(2, 40, 1)
に再形成することです。これにより、2 x(40, 1)
配列入力と同等になります。これは、私が行ったようにモデルで行うか、データセットを構築して入力形状を更新するときに行うことができます。
(..., 1)
を追加することで、一度に積み重ねた配列の1つだけを見ている場合に、LSTMが理解できる形式でデータを保持しています。たとえば、元のinput_shapeが(40, 1)
であることに注目してください。次に、各レイヤーをTimeDistributedラッパーでラップします。
最後に、(2, 10)
を(10, 2)
にスワップして、データに一致するようにy出力を再形成します。
コード
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import LSTM, Dense, TimeDistributed, InputLayer, Reshape
from tensorflow.python.keras import backend
import numpy as np
# Original Model
model = Sequential()
model.add(LSTM(12, input_shape=(40, 1), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense(10)))
model.summary()
元のモデルの概要
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm (LSTM) (None, 40, 12) 672
_________________________________________________________________
lstm_1 (LSTM) (None, 40, 12) 1200
_________________________________________________________________
lstm_2 (LSTM) (None, 6) 456
_________________________________________________________________
dense (Dense) (None, 10) 70
=================================================================
Total params: 2,398
Trainable params: 2,398
Non-trainable params: 0
_________________________________________________________________
Apply TimeDistributed Wrapper
model = Sequential()
model.add(InputLayer(input_shape=(40, 2)))
model.add(Reshape(target_shape=(2, 40, 1)))
model.add(TimeDistributed(LSTM(12, return_sequences=True)))
model.add(TimeDistributed(LSTM(12, return_sequences=True)))
model.add(TimeDistributed(LSTM(6, return_sequences=False)))
model.add(TimeDistributed(Dense(10)))
model.add(Reshape(target_shape=(10, 2)))
model.summary()
更新されたモデルの概要
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
reshape (Reshape) (None, 2, 40, 1) 0
_________________________________________________________________
time_distributed (TimeDistri (None, 2, 40, 12) 672
_________________________________________________________________
time_distributed_1 (TimeDist (None, 2, 40, 12) 1200
_________________________________________________________________
time_distributed_2 (TimeDist (None, 2, 6) 456
_________________________________________________________________
time_distributed_3 (TimeDist (None, 2, 10) 70
_________________________________________________________________
reshape_1 (Reshape) (None, 10, 2) 0
=================================================================
Total params: 2,398
Trainable params: 2,398
Non-trainable params: 0
_________________________________________________________________