在 Keras 中使用卷积神经网络后使用 LSTM 时的尺寸误差
Dimension Error while using LSTM after Convolutional neural network in Keras
在 keras 1.2.2 中,我制作了一个具有以下维度的数据集:
X_train: (2000, 100, 32, 32, 3)
y_train: (2000,1)
这里,2000是实例数(数据批次),100是每批次的样本数,32是图像行数和列数,3是通道数(RGB)。
我编写了在 CNN 之后应用 LSTM 的代码,但是,我收到此错误:
ValueError: Input 0 is incompatible with layer lstm_layer: expected ndim=3, found ndim=2
这是我的代码:
import keras
from keras.layers import Input ,Dense, Dropout, Activation, LSTM
from keras.layers import 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 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(Convolution2D(32, 3, 3, border_mode='same',
input_shape=X_train.shape[2:]))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(35, input_shape=(timesteps,512), name="first_dense" ));
#model.add(Dense(1, name="test_dense"));
model.add(LSTM(20, return_sequences=True, name="lstm_layer"));
#%%
model.add(TimeDistributed(Dense(1), name="time_distr_dense_one"))
model.add(GlobalAveragePooling1D(name="global_avg"))
#%%
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))
您确定 fit()
是正确的使用方法吗?我会使用 train_on_batch
因为你的训练数据已经分批了。
为了更好地控制您的 input_shape,我建议您在第一层明确定义它。不要使用 X_train.shape[1:]
,而是使用 (32,32,3)
以避免任何意外。
这对你有帮助吗?
尝试将每个 Convolution2D(...)
交换为:
TimeDistributed(Convolution2D(...))
您需要让您的模型知道您的数据是连续的,并且您希望对序列中的每个元素应用一些层。这就是 TimeDistributed
包装器的用途。
LSTM 的输出维度应与您的时间步长相同。
试试这个:
model.add(LSTM(output_dim=timesteps, return_sequences=True))
对我有用。
在 keras 1.2.2 中,我制作了一个具有以下维度的数据集:
X_train: (2000, 100, 32, 32, 3)
y_train: (2000,1)
这里,2000是实例数(数据批次),100是每批次的样本数,32是图像行数和列数,3是通道数(RGB)。
我编写了在 CNN 之后应用 LSTM 的代码,但是,我收到此错误:
ValueError: Input 0 is incompatible with layer lstm_layer: expected ndim=3, found ndim=2
这是我的代码:
import keras
from keras.layers import Input ,Dense, Dropout, Activation, LSTM
from keras.layers import 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 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(Convolution2D(32, 3, 3, border_mode='same',
input_shape=X_train.shape[2:]))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(35, input_shape=(timesteps,512), name="first_dense" ));
#model.add(Dense(1, name="test_dense"));
model.add(LSTM(20, return_sequences=True, name="lstm_layer"));
#%%
model.add(TimeDistributed(Dense(1), name="time_distr_dense_one"))
model.add(GlobalAveragePooling1D(name="global_avg"))
#%%
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))
您确定 fit()
是正确的使用方法吗?我会使用 train_on_batch
因为你的训练数据已经分批了。
为了更好地控制您的 input_shape,我建议您在第一层明确定义它。不要使用 X_train.shape[1:]
,而是使用 (32,32,3)
以避免任何意外。
这对你有帮助吗?
尝试将每个 Convolution2D(...)
交换为:
TimeDistributed(Convolution2D(...))
您需要让您的模型知道您的数据是连续的,并且您希望对序列中的每个元素应用一些层。这就是 TimeDistributed
包装器的用途。
LSTM 的输出维度应与您的时间步长相同。 试试这个:
model.add(LSTM(output_dim=timesteps, return_sequences=True))
对我有用。