Keras 中的 CNN-LSTM:尺寸误差
CNN-LSTM in Keras: Dimension Error
在 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))
如果我们沿着您模型中形状的轨迹,我们会在 Dense()
之后到达 shape = (None, 100, 35)
。然后你将它提供给一个 LSTM()
,它将 return 长度为 20 的整个隐藏向量序列,所以你得到一个 shape = (None, 100, 20)
。然后取轴 1 的平均值,得到 shape = (None, 100, 1)
。
该网络的架构有问题,因为您的目标有 shape = (None, 1)
。所以要么改变
LSTM(output_dim=20, return_sequences=False)
并在合并后添加一个Flatten()
层。或者在合并后 Flatten()
并使用 Dense(1, activation='sigmoid')
来获得你的预测?
这取决于你,但现在还行不通。
在 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))
如果我们沿着您模型中形状的轨迹,我们会在 Dense()
之后到达 shape = (None, 100, 35)
。然后你将它提供给一个 LSTM()
,它将 return 长度为 20 的整个隐藏向量序列,所以你得到一个 shape = (None, 100, 20)
。然后取轴 1 的平均值,得到 shape = (None, 100, 1)
。
该网络的架构有问题,因为您的目标有 shape = (None, 1)
。所以要么改变
LSTM(output_dim=20, return_sequences=False)
并在合并后添加一个Flatten()
层。或者在合并后 Flatten()
并使用 Dense(1, activation='sigmoid')
来获得你的预测?
这取决于你,但现在还行不通。