Keras 中的 CNN-LSTM:维度错误

Mah*_* K 3 theano deep-learning conv-neural-network lstm keras

在 keras 1.2.2 中,我制作了一个具有以下维度的数据集:

  • X_train: (2000, 100, 32, 32, 3)
  • y_train: (2000,1)

这里,2000 是实例数(数据的批次),100 是每批中的样本数,32 是图像行和列数,3 是通道数(RGB)。

我写了这段代码,它在 CNN 之后应用了 LSTM。我使用了 TimeDistributed 层,并取了 LSTM 输出的平均值,如下所示: 在此处输入图片说明

我希望 LSTM 处理每个批次,然后取该批次的 LSTM 输出的平均值。所以,我的总输出(我的标签)是一个 (2000,1) 向量。

我收到此错误:

  • 检查模型目标时出错:预期 lambda_14 有 2 个维度,但得到形状为 (2000L, 100L, 1L) 的数组

这是我的代码:

# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import keras
from keras.layers import Input ,Dense, Dropout, Activation, LSTM
from keras.layers import Lambda, Convolution2D, MaxPooling2D, Flatten, Reshape
from keras.models import Sequential
from keras.layers.wrappers import TimeDistributed
from keras.layers.pooling import GlobalAveragePooling1D
from keras.optimizers import SGD
from keras.utils import np_utils
from keras.models import Model
import keras.backend as K


import numpy as np

timesteps=100;
number_of_samples=2500;
nb_samples=number_of_samples;
frame_row=32;
frame_col=32;
channels=3;

nb_epoch=1;
batch_size=timesteps;

data= np.random.random((2500,timesteps,frame_row,frame_col,channels))
label=np.random.random((2500,timesteps,1))

X_train=data[0:2000,:]
y_train=label[0:2000]

X_test=data[2000:,:]
y_test=label[2000:,:]

#%%

model=Sequential();                          

model.add(TimeDistributed(Convolution2D(32, 3, 3, border_mode='same'), input_shape=X_train.shape[1:]))
model.add(TimeDistributed(Activation('relu')))
model.add(TimeDistributed(Convolution2D(32, 3, 3)))
model.add(TimeDistributed(Activation('relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Dropout(0.25)))

model.add(TimeDistributed(Flatten()))
model.add(TimeDistributed(Dense(512)))
#output dimension here is (None, 100, 512)                

model.add(TimeDistributed(Dense(35, name="first_dense" )))
#output dimension here is (None, 100, 35)                


model.add(LSTM(output_dim=20, return_sequences=True))
#output dimension here is (None, 100, 20)

time_distributed_merge_layer = Lambda(function=lambda x: K.mean(x, axis=1, keepdims=False))

model.add(time_distributed_merge_layer)
#output dimension here is (None, 1, 20)


#model.add(Flatten())
model.add(Dense(1, activation='sigmoid', input_shape=(None,20)))


model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

model.fit(X_train, y_train,
          batch_size=batch_size,
          nb_epoch=nb_epoch,
          validation_data=(X_test, y_test))
Run Code Online (Sandbox Code Playgroud)

Nas*_*Ben 5

如果我们跟踪模型中的形状,我们会shape = (None, 100, 35)Dense(). 然后你把它提供给 an LSTM(),它将返回长度为 20 的整个隐藏向量序列,所以你得到一个shape = (None, 100, 20). 然后你在轴 1 上取平均值,所以你得到shape = (None, 100, 1). 该网络的架构存在问题,因为您的目标具有shape = (None, 1). 所以要么改变

LSTM(output_dim=20, return_sequences=False) 
Run Code Online (Sandbox Code Playgroud)

Flatten()在合并后添加一个图层。或者Flatten()在合并后使用 aDense(1, activation='sigmoid')来获得您的预测?

这取决于你,但现在它无法工作。