이 질문은 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는 크기가 풀링 변경하고 너무 회선 (패딩 부족)된다는 것을 잊어. kgrm은 model.summary()
을 사용하여 치수를 확인하라고 안내합니다.
변경 대상 레이어 앞의 레이어 출력은 (None, 32, 26, 5)
, 입니다. 변경된 모양은 model.add(Reshape((32*26*5,)))
입니다.
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