나는 LSTM에 대한 나의 이해를 조정하려고 노력하고 있으며 Keras에서 구현 한 Christopher Olah 의이 게시물 에서 지적했습니다 . Keras 튜토리얼을 위해 Jason Brownlee이 작성한 블로그를 따르고 있습니다. 내가 주로 혼동하는 것은
- 데이터 계열을
[samples, time steps, features]
및 - 스테이트 풀 LSTM
아래에 붙여 넣은 코드를 참조하여 위의 두 가지 질문에 집중하십시오.
# reshape into X=t and Y=t+1
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 1))
testX = numpy.reshape(testX, (testX.shape[0], look_back, 1))
########################
# The IMPORTANT BIT
##########################
# create and fit the LSTM network
batch_size = 1
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
for i in range(100):
model.fit(trainX, trainY, nb_epoch=1, batch_size=batch_size, verbose=2, shuffle=False)
model.reset_states()
참고 : create_dataset은 길이 N의 시퀀스를 취하고 N-look_back
각 요소가 look_back
길이 시퀀스 인 배열을 반환합니다 .
시간 단계 및 기능이란 무엇입니까?
알 수 있듯이 TrainX는 Time_steps 및 Feature가 각각 마지막 2 차원 (이 특정 코드에서 3 및 1) 인 3 차원 배열입니다. 아래 이미지와 관련하여 many to one
분홍색 상자의 수가 3 인 경우를 고려하고 있습니까? 또는 문자 그대로 체인 길이가 3 (즉, 3 개의 녹색 상자 만 고려 됨)을 의미합니까?
다변량 계열을 고려할 때 기능 인수가 관련성이 있습니까? 예를 들어 두 개의 금융 주식을 동시에 모델링 하는가?
상태 저장 LSTM
상태 저장 LSTM은 배치 실행간에 셀 메모리 값을 저장한다는 의미입니까? 이 경우, batch_size
하나이고, 훈련 실행 사이에 메모리가 재설정되므로 상태가 좋았다는 것이 중요합니다. 나는 이것이 훈련 데이터가 섞여 있지 않다는 사실과 관련이 있다고 생각하지만 어떻게 해야할지 모르겠습니다.
이견있는 사람? 이미지 참조 : http://karpathy.github.io/2015/05/21/rnn-effectiveness/
편집 1 :
빨간색과 초록색 상자가 동일하다는 @van의 의견에 대해 약간 혼란 스럽습니다. 확인하기 위해 다음 API 호출이 롤링되지 않은 다이어그램에 해당합니까? 특히 두 번째 다이어그램에 주목하십시오 ( batch_size
임의로 선택되었습니다).
편집 2 :
Udacity의 딥 러닝 과정을 수행했지만 time_step 인수에 대해 여전히 혼란스러워하는 사람들은 다음 토론을 참조하십시오 . https://discussions.udacity.com/t/rnn-lstm-use-implementation/163169
최신 정보:
그것은 밝혀 model.add(TimeDistributed(Dense(vocab_len)))
내가 무엇을 찾고 있었다되었다. 예를 들면 다음과 같습니다. https://github.com/sachinruk/ShakespeareBot
업데이트 2 :
https://www.youtube.com/watch?v=ywinX5wgdEU 에서 LSTM에 대한 나의 이해를 요약했습니다.
답변
우선, 시작하기 위해 훌륭한 자습서 ( 1 , 2 )를 선택하십시오 .
시간 단계의 의미 : Time-steps==3
X.shape (데이터 모양 설명)에서 세 개의 분홍색 상자가 있음을 의미합니다. Keras에서 각 단계에는 입력이 필요하므로 녹색 상자 수는 일반적으로 빨간색 상자 수와 같아야합니다. 구조를 해킹하지 않는 한
하나에 많은 많은 대 많은 : keras에서는이 return_sequences
당신의 초기화 매개 변수 LSTM
나 GRU
또는 SimpleRNN
. 때 return_sequences
입니다 False
(기본적으로), 다음은 한 많은 그림과 같이. 반환 모양은 (batch_size, hidden_unit_length)
마지막 상태를 나타내는입니다. 때 return_sequences
입니다 True
, 다음은 많은 많은 . 반환 형태는(batch_size, time_step, hidden_unit_length)
기능 인수가 관련이 있습니까? 기능 인수는 “빨간색 상자의 크기” 또는 각 단계의 입력 차원을 의미합니다. 예를 들어 8 가지 종류의 시장 정보를 예측하려면을 사용하여 데이터를 생성 할 수 있습니다 feature==8
.
Stateful : 소스 코드를 찾을 수 있습니다 . 상태를 초기화 할 때이면 stateful==True
마지막 훈련의 상태가 초기 상태로 사용되며, 그렇지 않으면 새 상태가 생성됩니다. stateful
아직 켜지지 않았습니다. 그러나 batch_size
1 만 할 수 있다는 데 동의하지 않습니다 stateful==True
.
현재 수집 된 데이터로 데이터를 생성합니다. 모든 순차적 정보를 수집하기 위해 하루를 기다리지 않고 재고 정보가 스트림으로 제공되는 이미지를 작성하십시오 . 네트워크를 통한 교육 / 예측 동안 온라인으로 입력 데이터를 생성하려고 합니다. 동일한 네트워크를 공유하는 400 개의 주식이있는 경우을 설정할 수 있습니다 batch_size==400
.
답변
허용 된 답변을 보완하는이 답변은 각성 행동과 각 그림을 달성하는 방법을 보여줍니다.
일반적인 케 라스 행동
표준 케 라스 내부 처리는 다음 그림과 같이 항상 많거나 많습니다 ( features=2
예 : 압력 및 온도를 사용한 경우).
이 이미지에서는 다른 차원과의 혼동을 피하기 위해 단계 수를 5로 늘 렸습니다.
이 예의 경우 :
- 우리는 N 오일 탱크가 있습니다
- 우리는 5 시간 동안 시간 단위로 조치를 취했습니다 (시간 단계).
- 우리는 두 가지 특징을 측정했습니다 :
- 압력 P
- 온도 T
입력 배열은 다음과 같은 모양이어야합니다 (N,5,2)
.
[ Step1 Step2 Step3 Step4 Step5
Tank A: [[Pa1,Ta1], [Pa2,Ta2], [Pa3,Ta3], [Pa4,Ta4], [Pa5,Ta5]],
Tank B: [[Pb1,Tb1], [Pb2,Tb2], [Pb3,Tb3], [Pb4,Tb4], [Pb5,Tb5]],
....
Tank N: [[Pn1,Tn1], [Pn2,Tn2], [Pn3,Tn3], [Pn4,Tn4], [Pn5,Tn5]],
]
슬라이딩 윈도우 용 입력
LSTM 레이어는 종종 전체 시퀀스를 처리해야합니다. 창문을 나누는 것이 가장 좋은 아이디어는 아닙니다. 레이어는 시퀀스가 진행되면서 어떻게 진화하고 있는지에 대한 내부 상태를 가지고 있습니다. Windows는 긴 시퀀스를 학습 할 가능성을 없애 모든 시퀀스를 윈도우 크기로 제한합니다.
창에서 각 창은 긴 원본 시퀀스의 일부이지만 Keras에서는 각각 독립적 인 시퀀스로 표시됩니다.
[ Step1 Step2 Step3 Step4 Step5
Window A: [[P1,T1], [P2,T2], [P3,T3], [P4,T4], [P5,T5]],
Window B: [[P2,T2], [P3,T3], [P4,T4], [P5,T5], [P6,T6]],
Window C: [[P3,T3], [P4,T4], [P5,T5], [P6,T6], [P7,T7]],
....
]
이 경우 처음에는 하나의 시퀀스 만 있지만 창을 만들기 위해 여러 시퀀스로 나눕니다.
“시퀀스 란 무엇인가”라는 개념은 추상적입니다. 중요한 부분은 다음과 같습니다.
- 많은 개별 시퀀스로 일괄 처리 할 수 있습니다
- 시퀀스를 시퀀스로 만드는 것은 단계 (일반적으로 시간 단계)로 진화한다는 것입니다.
“단일 레이어”로 각 경우 달성
다 대다 표준 달성 :
다음을 사용하여 간단한 LSTM 계층으로 다대 다를 달성 할 수 있습니다 return_sequences=True
.
outputs = LSTM(units, return_sequences=True)(inputs)
#output_shape -> (batch_size, steps, units)
다 대일 달성 :
똑같은 레이어를 사용하면 keras는 똑같은 내부 전처리를 수행하지만, return_sequences=False
이 인수 를 사용 하거나 무시하면 keras는 자동으로 이전 단계를 무시합니다.
outputs = LSTM(units)(inputs)
#output_shape -> (batch_size, units) --> steps were discarded, only the last was returned
일대 다 달성
이제는 keras LSTM 레이어만으로는 지원되지 않습니다. 단계를 곱하려면 자신 만의 전략을 만들어야합니다. 두 가지 좋은 접근 방식이 있습니다.
- 텐서를 반복하여 일정한 다단계 입력 생성
- a
stateful=True
를 사용하여 한 단계의 출력을 반복적으로 가져 와서 다음 단계의 입력으로 사용합니다 (필요output_features == input_features
)
반복 벡터가있는 일대 다
keras 표준 동작에 맞추려면 단계적으로 입력이 필요하므로 원하는 길이만큼 입력을 반복하면됩니다.
outputs = RepeatVector(steps)(inputs) #where inputs is (batch,features)
outputs = LSTM(units,return_sequences=True)(outputs)
#output_shape -> (batch_size, steps, units)
상태 저장 이해 = True
stateful=True
한 번에 컴퓨터의 메모리에 맞지 않는 데이터를로드하지 않는 것 외에도 사용 가능한 방법 중 하나가 제공됩니다.
상태 저장을 통해 시퀀스의 “부분”을 단계적으로 입력 할 수 있습니다. 차이점은 다음과 같습니다.
- 이어
stateful=False
, 두 번째 배치의 첫 번째 배치로부터 독립적 새로운 시퀀스를 포함 - 이어
stateful=True
, 두 번째 배치를 동일한 서열을 연장 제 배치를 계속한다.
창에서 시퀀스를 나누는 것과 마찬가지로 두 가지 주요 차이점이 있습니다.
- 이 창문은 중첩되지 않습니다 !!
stateful=True
이 창들은 하나의 긴 시퀀스로 연결되어 있습니다.
에서은 stateful=True
, 모든 새로운 배치는 이전 배치 (당신이 호출 할 때까지 계속하는 것으로 해석됩니다 model.reset_states()
).
- 배치 2의 순서 1은 배치 1의 순서 1을 계속합니다.
- 배치 2의 시퀀스 2는 배치 1의 시퀀스 2를 계속합니다.
- 배치 2의 시퀀스 n은 배치 1의 시퀀스 n을 계속합니다.
입력 예, 배치 1에는 1 단계와 2 단계가 있고 배치 2에는 3 ~ 5 단계가 있습니다.
BATCH 1 BATCH 2
[ Step1 Step2 | [ Step3 Step4 Step5
Tank A: [[Pa1,Ta1], [Pa2,Ta2], | [Pa3,Ta3], [Pa4,Ta4], [Pa5,Ta5]],
Tank B: [[Pb1,Tb1], [Pb2,Tb2], | [Pb3,Tb3], [Pb4,Tb4], [Pb5,Tb5]],
.... |
Tank N: [[Pn1,Tn1], [Pn2,Tn2], | [Pn3,Tn3], [Pn4,Tn4], [Pn5,Tn5]],
] ]
배치 1과 배치 2에서 탱크 정렬을 확인하십시오! 그것이 우리가 필요한 이유 shuffle=False
입니다 (물론 하나의 시퀀스 만 사용하지 않는 한).
당신은 배치를 무제한으로 가질 수 있습니다. (일괄 처리마다 가변 길이를 사용하려면을 사용하십시오 input_shape=(None,features)
.
stateful = True 인 일대 다
여기서는 하나의 출력 단계를 가져 와서 입력하기 때문에 배치 당 1 단계 만 사용하려고합니다.
그림의 동작이 “원인”이 아님을 유의하십시오 stateful=True
. 아래의 수동 루프에서 해당 동작을 강제합니다. 이 예에서는 stateful=True
시퀀스를 중지하고 원하는 것을 조작하며 중지 한 부분부터 계속할 수 있습니다.
솔직히 말해서,이 경우에는 반복 접근법이 더 나은 선택 일 것입니다. 그러나 우리가 조사하고 있기 때문에 stateful=True
이것은 좋은 예입니다. 이것을 사용하는 가장 좋은 방법은 다음 “다 대다”사례입니다.
층:
outputs = LSTM(units=features,
stateful=True,
return_sequences=True, #just to keep a nice output shape even with length 1
input_shape=(None,features))(inputs)
#units = features because we want to use the outputs as inputs
#None because we want variable length
#output_shape -> (batch_size, steps, units)
이제 예측을위한 수동 루프가 필요합니다.
input_data = someDataWithShape((batch, 1, features))
#important, we're starting new sequences, not continuing old ones:
model.reset_states()
output_sequence = []
last_step = input_data
for i in steps_to_predict:
new_step = model.predict(last_step)
output_sequence.append(new_step)
last_step = new_step
#end of the sequences
model.reset_states()
stateful = True 인 다 대다
이제 우리는 매우 멋진 응용 프로그램을 얻습니다. 입력 시퀀스가 주어지면 미래의 알려지지 않은 단계를 예측하십시오.
위의 “일대 다”와 동일한 방법을 사용하고 있지만 다음과 같은 차이점이 있습니다.
- 한 단계 앞선 시퀀스 자체를 대상 데이터로 사용합니다.
- 시퀀스의 일부를 알고 있으므로 결과의이 부분을 버립니다.
레이어 (위와 동일) :
outputs = LSTM(units=features,
stateful=True,
return_sequences=True,
input_shape=(None,features))(inputs)
#units = features because we want to use the outputs as inputs
#None because we want variable length
#output_shape -> (batch_size, steps, units)
훈련:
시퀀스의 다음 단계를 예측하기 위해 모델을 훈련시킬 것입니다.
totalSequences = someSequencesShaped((batch, steps, features))
#batch size is usually 1 in these cases (often you have only one Tank in the example)
X = totalSequences[:,:-1] #the entire known sequence, except the last step
Y = totalSequences[:,1:] #one step ahead of X
#loop for resetting states at the start/end of the sequences:
for epoch in range(epochs):
model.reset_states()
model.train_on_batch(X,Y)
예측 :
예측의 첫 단계는 “상태 조정”과 관련이 있습니다. 이것이 우리가 이미이 부분을 알고 있더라도 전체 시퀀스를 다시 예측하는 이유입니다.
model.reset_states() #starting a new sequence
predicted = model.predict(totalSequences)
firstNewStep = predicted[:,-1:] #the last step of the predictions is the first future step
이제 우리는 일대 다 사례 에서처럼 루프로갑니다. 그러나 여기서 상태를 재설정하지 마십시오! . 우리는 모델이 시퀀스의 어느 단계에 있는지 알기를 원합니다 (그리고 우리가 위에서 만든 예측 때문에 첫 번째 새로운 단계에 있음을 알고 있습니다)
output_sequence = [firstNewStep]
last_step = firstNewStep
for i in steps_to_predict:
new_step = model.predict(last_step)
output_sequence.append(new_step)
last_step = new_step
#end of the sequences
model.reset_states()
이 접근법은 다음 답변과 파일에서 사용되었습니다.
- LSTM을 사용하여 시계열의 다중 순방향 시간 단계 예측
- Keras 모델을 사용하여 미래 날짜 또는 이벤트를 예측하는 방법은 무엇입니까?
- https://github.com/danmoller/TestRepo/blob/master/TestBookLSTM.ipynb
복잡한 구성 달성
위의 모든 예제에서 “하나의 레이어”의 동작을 보여주었습니다.
물론, 반드시 동일한 패턴을 따르지 않고 여러 레이어를 서로 겹쳐 쌓고 자신 만의 모델을 만들 수 있습니다.
흥미로운 하나의 예는 “다 대일 인코더”와 “일대 다”디코더가있는 “자동 인코더”입니다.
인코더 :
inputs = Input((steps,features))
#a few many to many layers:
outputs = LSTM(hidden1,return_sequences=True)(inputs)
outputs = LSTM(hidden2,return_sequences=True)(outputs)
#many to one layer:
outputs = LSTM(hidden3)(outputs)
encoder = Model(inputs,outputs)
디코더 :
“반복”방법 사용
inputs = Input((hidden3,))
#repeat to make one to many:
outputs = RepeatVector(steps)(inputs)
#a few many to many layers:
outputs = LSTM(hidden4,return_sequences=True)(outputs)
#last layer
outputs = LSTM(features,return_sequences=True)(outputs)
decoder = Model(inputs,outputs)
오토 인코더 :
inputs = Input((steps,features))
outputs = encoder(inputs)
outputs = decoder(outputs)
autoencoder = Model(inputs,outputs)
와 훈련 fit(X,X)
추가 설명
LSTM에서 단계가 계산되는 방법 또는 stateful=True
위 의 경우 에 대한 세부 사항을 원하는 경우이 답변에서 자세한 내용을 읽을 수 있습니다 .`Keras LSTM 이해 ‘
답변
RNN의 마지막 계층에 return_sequences가 있으면 간단한 Dense 계층을 사용할 수 없으며 대신 TimeDistributed를 사용하십시오.
다음은 다른 사람들을 도울 수있는 예제 코드입니다.
단어 = keras.layers.Input (batch_shape = (없음, self.maxSequenceLength), 이름 = “입력”)
# Build a matrix of size vocabularySize x EmbeddingDimension
# where each row corresponds to a "word embedding" vector.
# This layer will convert replace each word-id with a word-vector of size Embedding Dimension.
embeddings = keras.layers.embeddings.Embedding(self.vocabularySize, self.EmbeddingDimension,
name = "embeddings")(words)
# Pass the word-vectors to the LSTM layer.
# We are setting the hidden-state size to 512.
# The output will be batchSize x maxSequenceLength x hiddenStateSize
hiddenStates = keras.layers.GRU(512, return_sequences = True,
input_shape=(self.maxSequenceLength,
self.EmbeddingDimension),
name = "rnn")(embeddings)
hiddenStates2 = keras.layers.GRU(128, return_sequences = True,
input_shape=(self.maxSequenceLength, self.EmbeddingDimension),
name = "rnn2")(hiddenStates)
denseOutput = TimeDistributed(keras.layers.Dense(self.vocabularySize),
name = "linear")(hiddenStates2)
predictions = TimeDistributed(keras.layers.Activation("softmax"),
name = "softmax")(denseOutput)
# Build the computational graph by specifying the input, and output of the network.
model = keras.models.Model(input = words, output = predictions)
# model.compile(loss='kullback_leibler_divergence', \
model.compile(loss='sparse_categorical_crossentropy', \
optimizer = keras.optimizers.Adam(lr=0.009, \
beta_1=0.9,\
beta_2=0.999, \
epsilon=None, \
decay=0.01, \
amsgrad=False))