Deep learning Keras中的CNN-LSTM:尺寸误差

Deep learning Keras中的CNN-LSTM:尺寸误差,deep-learning,theano,keras,conv-neural-network,lstm,Deep Learning,Theano,Keras,Conv Neural Network,Lstm,在keras 1.2.2中,我制作了一个具有以下维度的数据集: X_列车:(2000、100、32、32、3) y_列车:(2000,1) 这里,2000是实例数(数据批次),100是每个批次中的样本数,32是图像行和列,3是通道数(RGB) 我写了这段代码,它在CNN之后应用LSTM。我使用TimeDistributed layers并取LSTM输出的平均值,得到如下结果: 我希望LSTM在每个批次上工作,然后取该批次上LSTM输出的平均值。所以,我的总输出(我的标签)是一个(2000,

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

  • X_列车:(2000、100、32、32、3)
  • y_列车:(2000,1)
这里,2000是实例数(数据批次),100是每个批次中的样本数,32是图像行和列,3是通道数(RGB)

我写了这段代码,它在CNN之后应用LSTM。我使用TimeDistributed layers并取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))

如果我们跟踪模型中形状的轨迹,我们将在
Dense()之后到达
shape=(None,100,35)
。然后将其馈送到
LSTM()
,该函数将返回长度为20的整个隐藏向量序列,因此得到
shape=(None,100,20)
。然后取轴1上的平均值,得到
shape=(无,100,1)
。 该网络的架构有问题,因为您的目标具有
shape=(无,1)
。所以要么改变

LSTM(output_dim=20, return_sequences=False) 
并在合并后添加一个
flatte()
层。或者在合并后使用
densed(1,activation='sigmoid')
获取预测


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

非常感谢:)LSTM的输出形状是shape=(无,100,20)。我的批次中的样本数量是100个,我想对这100个输出(LSTM)取平均值,以获得20维输出。我们在这里怎么做?在自定义合并层中将平均值的轴更改为0。取100个数值的平均值。然后展平得到一个(无,20)形状的张量。但这与您的输出不匹配,因为您构建的标签的形状为(None,100,1)。我不知道你到底想在这里实现什么。非常感谢。我更改了我的代码并更新了它(在问题中)。你认为现在是正确的吗?我已经在代码的注释中写下了张量的维数。我想做的是首先对100(这是我的批处理)取平均值,得到一个20维的向量,然后对它们应用稠密运算得到一个标量输出。你确定维数是正确的吗?您没有更改平均值的轴参数。但是,将标签数组更改为(2500,1)并对其进行四舍五入(以获得二进制值,而不是0到1之间的实际值),你是对的。如果我这样写:time\u distributed\u merge\u layer=Lambda(function=Lambda x:K.mean(x,axis=0,keepdims=False),output\u shape=(None,20)),多亏了Nassim Ben,我更新了代码。