2016-10-24 6 views
6

이 질문은 github issue으로도 존재합니다. 2 차원 컨볼 루션과 LSTM 레이어가 모두 포함 된 Keras 신경 네트워크를 구축하고 싶습니다.Keras : lstm과 conv에 연결하기위한 모양 변경

네트워크는 MNIST를 분류해야합니다. MNIST의 학습 데이터는 0에서 9까지의 자필 자릿수 60000 회색 이미지입니다. 각 이미지는 28x28 픽셀입니다.

이미지를 4 개 부분 (왼쪽/오른쪽, 위/아래)으로 분할하고 4 개 순서로 정렬하여 LSTM의 시퀀스를 얻습니다.

|  |  |1 | 2| 
|image| -> ------- -> 4 sequences: |1|2|3|4|, |4|3|2|1|, |1|3|2|4|, |4|2|3|1| 
|  |  |3 | 4| 

작은 하위 이미지 중 하나는 14 x 14 크기입니다. 4 개의 시퀀스는 너비 (높이 또는 너비와 상관 없음)를 따라 함께 쌓입니다. 이 형상에 벡터를 생성

[60000, 4, 1, 56, 14]

  • 60000 샘플
  • (4)의 개수는 시퀀스의 요소의 개수가된다 (# 시간 단계)의
  • 1 색의 깊이가 Keras 모델에 부여한다 (그레이 스케일)
  • 56 및도 14은 너비 및 높이 이제이
이다

. 문제는 CNN과 LSTM 사이의 입력 차원을 변경하는 것입니다. 나는 온라인으로 검색하고이 질문에 발견 Python keras how to change the size of input after convolution layer into lstm layer

이 솔루션은 이미지를 평평하게 만합니다 (BATCH_SIZE하지만 모든 것을 붕괴 것 펼치기 층에 반대) 시간 단계를 유지하는 모양 변경 층 것으로 보인다합니다.

여기 내 코드는 지금까지의 :

nb_filters=32 
kernel_size=(3,3) 
pool_size=(2,2) 
nb_classes=10 
batch_size=64 

model=Sequential() 

model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], 
    border_mode="valid", input_shape=[1,56,14])) 
model.add(Activation("relu")) 
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1])) 
model.add(Activation("relu")) 
model.add(MaxPooling2D(pool_size=pool_size)) 


model.add(Reshape((56*14,))) 
model.add(Dropout(0.25)) 
model.add(LSTM(5)) 
model.add(Dense(50)) 
model.add(Dense(nb_classes)) 
model.add(Activation("softmax")) 

이 코드는 오류 메시지를 생성합니다

ValueError: total size of new array must be unchanged

가 분명히 모양 변경 층에 입력이 잘못되었습니다.

model.add(Reshape((4,56*14))) 

이 잘 생각하지 않으며, 어떠한 경우에도 오류가 동일하게 유지 : 다른 방법으로, 나는 역시 모양 변경 층에 시간 단계를 통과했습니다.

나는 이것을 올바르게하고 있습니까? Reshape 레이어가 CNN과 LSTM을 연결하는 데 적합한 도구입니까?

이 문제에 대한 다소 복잡한 접근법이 있습니다. 다음과 같이합니다. https://github.com/fchollet/keras/pull/1456 다음 계층에서 시간 단계 차원을 숨기는 것으로 보이는 TimeDistributed 계층입니다.

또는 https://github.com/anayebi/keras-extra CNN과 LSTM을 결합하기위한 특수 레이어 집합입니다.

간단한 변형이 트릭을 수행하는 이유는 무엇입니까? (적어도 나에게는 복잡해 보입니다) 왜 그렇게 복잡합니까?

UPDATE :

는 황당, I는 크기가 풀링 변경하고 너무 회선 (패딩 부족)된다는 것을 잊어. kgrmmodel.summary()을 사용하여 치수를 확인하라고 안내합니다.

변경 대상 레이어 앞의 레이어 출력은 (None, 32, 26, 5), 입니다. 변경된 모양은 model.add(Reshape((32*26*5,)))입니다.

이제 ValueError를 대신 LSTM는 불평 사라 : 나는 전체 네트워크를 통해 시간 단계의 차원을 통과해야처럼

Exception: Input 0 is incompatible with layer lstm_5: expected ndim=3, found ndim=2

보인다. 어떻게해야합니까? 나는 회선의 input_shape에 추가하면,도, 불평 : 귀하의 의견은 크기 (samples, channels, rows, cols) 4 차원해야 Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode="valid", input_shape=[4, 1, 56,14])

Exception: Input 0 is incompatible with layer convolution2d_44: expected ndim=4, found ndim=5

답변

5

따르면 정의 Convolution2D에. 이것이 왜 오류가 발생하는지 직접적인 이유입니다.

해결하려면 TimeDistributed 래퍼를 사용해야합니다. 이를 통해 시간에 걸쳐 정적 인 (재발하지 않는) 레이어를 사용할 수 있습니다.