Keras LSTM 이해
저는 LSTM에 대한 저의 이해를 조정하려고 노력하고 있으며, 여기 크리스토퍼 올라가 작성한 이 게시물에서 지적한 내용을 Keras로 구현했습니다. 저는 제이슨 브라운리가 작성한 블로그의 Keras 튜토리얼을 따르고 있습니다. 제가 주로 혼란스러워하는 것은 다음과 같습니다,
- 데이터 계열을
샘플, 시간 단계, 기능
으로 재구성하는 것과, - 상태 저장 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의 시퀀스를 받아 각 요소가 look_back
길이의 시퀀스인 N-look_back
배열을 반환합니다.
시간 단계와 특징이란 무엇인가요?
보시다시피 TrainX는 3차원 배열이며 Time_steps와 Feature는 각각 마지막 두 차원입니다(이 특정 코드에서는 3과 1). 아래 이미지와 관련하여 분홍색 상자의 수가 3인 '다대일'의 경우를 고려하고 있다는 의미일까요? 아니면 문자 그대로 체인 길이가 3이라는 의미인가요(즉, 녹색 상자 3개만 고려됨)? ![여기에 이미지 설명 입력]]3
다변량 계열을 고려할 때 특징 인수가 관련성이 있나요? 예를 들어 두 개의 금융 주식을 동시에 모델링하는 경우?
상태 저장 LSTM
상태 저장 LSTM은 배치 실행 사이에 셀 메모리 값을 저장하는 것을 의미합니까? 그렇다면 batch_size
는 하나이고 훈련 실행 사이에 메모리가 재설정되므로 상태 저장형이라는 말이 무슨 의미가 있을까요? 훈련 데이터가 셔플되지 않는다는 사실과 관련이 있다고 생각하지만 그 방법은 잘 모르겠습니다.
어떤 생각 있으신가요? 이미지 참조: http://karpathy.github.io/2015/05/21/rnn-effectiveness/
수정 1:
빨간색과 녹색 상자가 같다는 @van의 의견에 대해 약간 혼란스러웠습니다. 확인을 위해 다음 API 호출이 펼쳐진 다이어그램과 일치하나요? 특히 두 번째 다이어그램에 주목합니다(batch_size
는 임의로 선택했습니다.):
![여기에 이미지 설명 입력]][4]
수정 2:
유다시티의 딥러닝 강좌를 수강하고도 time_step 인자에 대해 혼란스러우신 분들은 다음 토론을 참고하시기 바랍니다: https://discussions.udacity.com/t/rnn-lstm-use-implementation/163169.
업데이트:
제가 찾던 것은 model.add(TimeDistributed(Dense(vocab_len)))
였습니다. 다음은 예제입니다: https://github.com/sachinruk/ShakespeareBot
업데이트2:
LSTM에 대한 이해의 대부분을 여기에 요약했습니다: https://www.youtube.com/watch?v=ywinX5wgdEU
우선, 훌륭한 튜토리얼(1,2)을 선택하여 시작합니다.
시간 단계의 의미: X.shape(데이터 모양 설명)에서 '시간 단계==3'은 분홍색 상자 3개가 있음을 의미합니다. Keras에서는 각 단계마다 입력이 필요하므로 일반적으로 녹색 상자의 수는 빨간색 상자의 수와 같아야 합니다. 구조를 해킹하지 않는 한 말입니다.
다대다 대 다대일: keras에서는
LSTM
이나GRU
,SimpleRNN
을 초기화할 때return_sequences
파라미터가 있습니다. 반환값이False
(기본값)이면 그림과 같이 다수 대 1이 됩니다. 반환 형태는 마지막 상태를 나타내는(batch_size, hidden_unit_length)
입니다. return_sequences가
True이면 **다대다**입니다. 반환 형태는
(batch_size, time_step, hidden_unit_length)`입니다.특징 인자가 관련성이 있는가: 특징 인수는 '빨간색 상자가 얼마나 큰지' 또는 각 단계의 입력 차원을 의미합니다. 예를 들어 8가지의 시장 정보로부터 예측하고 싶다면
feature==8
로 데이터를 생성할 수 있습니다.스테이트풀: 소스 코드]3를 조회할 수 있습니다. 상태를 초기화할 때
stateful==True
이면 마지막 학습의 상태를 초기 상태로 사용하고, 그렇지 않으면 새로운 상태를 생성합니다. 아직stateful
을 켜지 않았습니다. 하지만batch_size
가stateful==True
일 때만 1이 될 수 있다는 것에 동의하지 않습니다.현재 수집된 데이터로 데이터를 생성하고 있습니다. 주식 정보가 스트림으로 들어온다고 가정하고, 하루를 기다렸다가 순차적으로 모두 수집하는 것이 아니라 네트워크에서 학습/예측하는 동안 온라인으로 입력 데이터를 생성하고 싶습니다. 만약 같은 네트워크를 공유하는 주식이 400개라면
batch_size==400
을 설정하면 됩니다.정답을 보완하기 위해 이 답변은 케라스의 행동과 각 그림을 달성하는 방법을 보여줍니다.
일반 케라스 동작
표준 케라스 내부 처리는 다음 그림과 같이 항상 다대다입니다(예제로서
이 이미지에서는 다른 차원과 혼동을 피하기 위해 단계 수를 5로 늘렸습니다.
이 예제에서는
features=2
, 압력 및 온도를 사용했습니다):(N,5,2)
의 형태가 되어야 합니다:슬라이딩 창에 대한 입력
종종 LSTM 레이어는 전체 시퀀스를 처리해야 합니다. 창을 나누는 것이 최선의 아이디어가 아닐 수도 있습니다. 레이어에는 시퀀스가 앞으로 나아갈 때 어떻게 진화하고 있는지에 대한 내부 상태가 있습니다. 윈도우는 모든 시퀀스를 윈도우 크기로 제한하여 긴 시퀀스를 학습할 가능성을 제거합니다. 윈도우에서는 각 윈도우가 긴 원본 시퀀스의 일부이지만 Keras에서는 각각 독립적인 시퀀스로 간주됩니다:
이 경우 처음에는 하나의 시퀀스만 있지만 여러 시퀀스로 나누어 창을 생성한다는 점에 유의하세요. '시퀀스란 무엇인가'라는 개념은 추상적입니다. 중요한 부분은
'단일 레이어'로 각 사례 달성하기;
표준 다대다를 달성합니다:
다대다 달성하기:
정확히 동일한 레이어를 사용하면 keras는 정확히 동일한 내부 전처리를 수행하지만,
return_sequences=False
를 사용하면(또는 단순히 이 인수를 무시하면) keras는 마지막 단계 이전의 단계를 자동으로 버립니다:1 대 다수 달성하기
이제 이것은 keras LSTM 레이어만으로는 지원되지 않습니다. 단계를 곱하기 위해 자신만의 전략을 만들어야 합니다. 두 가지 좋은 접근 방식이 있습니다:
를 사용하여 한 단계의 출력을 반복적으로 가져와서 다음 단계의 입력으로 제공합니다(
output_features == input_features` 필요).반복 벡터를 사용한 일대다 변환
케라스의 표준 동작에 맞추기 위해서는 단계별 입력이 필요하므로 원하는 길이만큼 입력을 반복하기만 하면 됩니다:
스테이트풀 이해 = True
이제 컴퓨터 메모리에 맞지 않는 데이터를 한 번에 로드하는 것을 피하는 것 외에
stateful=True
의 가능한 용도 중 하나를 소개합니다. Stateful을 사용하면 시퀀스의 '부분'을 단계적으로 입력할 수 있습니다. 차이점은 다음과 같습니다:이 두 가지 주요 차이점을 제외하고는 시퀀스를 창으로 나누는 것과 같습니다:
에서는 이러한 창이 하나의 긴 시퀀스로 연결됩니다. stateful=True
에서는 모든 새 배치가 이전 배치를 계속하는 것으로 해석됩니다(model.reset_states()
를 호출할 때까지).배치 1과 배치 2에서 탱크가 정렬된 것을 확인하세요! 그렇기 때문에
shuffle=False
가 필요합니다(물론 하나의 시퀀스만 사용하는 경우가 아니라면). 배치의 개수는 무한대로 가질 수 있습니다. (각 배치에 가변 길이를 사용하려면input_shape=(None,features)
를 사용합니다.stateful=True를 사용한 일대다 배치
여기서는 하나의 출력 스텝을 가져와 입력으로 만들고자 하므로 배치당 하나의 스텝만 사용하겠습니다. 그림의 동작은 'stateful=True'에 의한 동작이 아니라는 점에 유의하세요. 아래 수동 루프에서 해당 동작을 강제할 것입니다. 이 예제에서
솔직히 이 경우에는 반복 접근 방식이 더 나은 선택일 수 있습니다. 하지만
stateful=True
는 시퀀스를 멈추고 원하는 것을 조작한 후 멈춘 지점에서 계속할 수 있도록 해줍니다.stateful=True
를 살펴보고 있기 때문에 이것은 좋은 예입니다. 이를 사용하는 가장 좋은 방법은 다음 '다대다'의 경우입니다. Layer:이제 예측을 위한 수동 루프가 필요합니다:
stateful=True를 사용한 다대다 예측
이제 입력 시퀀스가 주어졌을 때 미래의 알려지지 않은 단계를 예측하는 아주 멋진 애플리케이션이 생겼습니다. 위의 '일대다'에서와 동일한 방법을 사용하지만 한 가지 차이점이 있습니다:
훈련: 시퀀스의 다음 단계를 예측하도록 모델을 훈련하겠습니다:
예측: 예측의 첫 번째 단계는 '상태 조정'을 포함합니다. 그렇기 때문에 이미 이 부분을 알고 있더라도 전체 시퀀스를 다시 예측할 것입니다:
이제 일대다 사례에서와 같이 루프로 이동합니다. 하지만 여기서 상태를 초기화하지 마세요!**. 우리는 모델이 시퀀스의 어느 단계에 있는지 알기를 원합니다(그리고 위에서 방금 한 예측으로 인해 첫 번째 새로운 단계에 있다는 것을 알고 있습니다).
이 접근 방식은 이 답변과 파일에 사용되었습니다:
복잡한 구성 달성하기
위의 모든 예제에서 저는 '하나의 레이어'의 동작을 보여주었습니다. 물론 모든 레이어가 반드시 동일한 패턴을 따르지 않아도 여러 레이어를 겹쳐서 자신만의 모델을 만들 수 있습니다. 최근에 등장한 한 가지 흥미로운 예는 와 가 있는 입니다: 인코더:
디코더: '반복' 메서드 사용;
자동 인코더:
fit(X,X)`로 훈련하기
추가 설명
LSTM에서 스텝이 계산되는 방식에 대한 자세한 내용이나 위의 'stateful=True' 사례에 대한 자세한 내용은 이 답변에서 확인할 수 있습니다: https://stackoverflow.com/questions/53955093/doubts-regarding-understanding-keras-lstms.
RNN의 마지막 레이어에 반환 시퀀스가 있는 경우 단순한 Dense 레이어를 사용할 수 없으며 대신 TimeDistributed를 사용합니다.
다음은 다른 사람들에게 도움이 될 수 있는 코드 예제입니다.
words = keras.layers.Input(batch_shape=(None, self.maxSequenceLength), name = "input")