CNN+LSTM序列X光图像分类实现报错:输入形状不兼容
问题:CNN+LSTM网络输入形状不匹配报错
尝试用CNN+LSTM网络处理预处理为150×150×3的X光图像序列,完成4分类任务。X_train形状为(4067, 150, 150, 3),执行model.fit()时触发输入形状不兼容的错误。
代码实现:
# x_train = np.reshape(x_train, (4067, 150, 150, 3)) # y_train = np.reshape(y_train, (4067, 4)) model = Sequential() model.add(TimeDistributed(Conv2D(filters = 32, kernel_size=(3,3), padding='same', activation = 'relu'), input_shape=(None, 150, 150, 3))) model.add(TimeDistributed(AveragePooling2D())) model.add(TimeDistributed(Flatten())) model.add(LSTM(100)) model.add(Dense(24, activation='relu',name='output')) model.add(Dense(4, activation = 'softmax')) from tensorflow.keras.optimizers import Adam optimizer = Adam(lr=0.001) model.compile(optimizer = optimizer, loss = 'categorical_crossentropy', metrics=['accuracy']) from tensorflow.keras.callbacks import ReduceLROnPlateau reduce_lr = ReduceLROnPlateau(monitor = 'val_accuracy', factor = 0.3, patience = 2, min_delta = 0.001, mode = 'auto', verbose = 1) hist_cnn_lstm = model.fit(x_train, y_train, batch_size=64, epochs=15, validation_data = (x_valid, y_valid), callbacks=reduce_lr )
错误信息:
Epoch 1/15 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-24-3ec61fbabcf1> in <module>() 1 hist_cnn_lstm = model.fit(x_train, y_train, batch_size=64, epochs=15, 2 validation_data = (x_valid, y_valid), ----> 3 callbacks=reduce_lr 4 ) 1 frames /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs) 1145 except Exception as e: # pylint:disable=broad-except 1146 if hasattr(e, "ag_error_metadata"): -> 1147 raise e.ag_error_metadata.to_exception(e) 1148 else: 1149 raise ValueError: in user code: File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1021, in train_function * return step_function(self, iterator) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1010, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1000, in run_step ** outputs = model.train_step(data) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 859, in train_step y_pred = self(x, training=True) File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler raise e.with_traceback(filtered_tb) from None File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 264, in assert_input_compatibility raise ValueError(f'Input {input_index} of layer "{layer_name}" is ValueError: Input 0 of layer "sequential_1" is incompatible with the layer: expected shape=(None, None, 150, 150, 3), found shape=(None, 150, 150, 3)
解决方法
问题根源
TimeDistributed层用于处理序列数据,要求输入必须包含时间步维度。你的X_train形状是(样本数, 150, 150, 3),缺少时间步维度;而模型输入定义的input_shape=(None, 150, 150, 3)对应完整输入形状是(样本数, 时间步数, 150, 150, 3),两者不匹配导致报错。
具体修改步骤
调整输入数据形状:给X_train和X_valid增加时间步维度。如果每个样本是单张图像(时间步数为1),用
np.expand_dims扩展维度:x_train = np.expand_dims(x_train, axis=1) # 形状变为(4067, 1, 150, 150, 3) x_valid = np.expand_dims(x_valid, axis=1)如果每个样本是包含N张图像的序列,需确保原始数据时间步维度正确,调整为
(样本数, N, 150, 150, 3)。(可选)明确输入形状的时间步:如果序列长度固定(比如每个样本都是1张图像),可把
input_shape中的None改成固定值,让模型定义更清晰:model.add(TimeDistributed(Conv2D(filters=32, kernel_size=(3,3), padding='same', activation='relu'), input_shape=(1, 150, 150, 3)))
修改后的完整代码示例
import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import TimeDistributed, Conv2D, AveragePooling2D, Flatten, LSTM, Dense from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import ReduceLROnPlateau # 调整输入数据形状 x_train = np.expand_dims(x_train, axis=1) x_valid = np.expand_dims(x_valid, axis=1) model = Sequential() # 这里可以用固定时间步1,或者保留None支持可变长度序列 model.add(TimeDistributed(Conv2D(filters = 32, kernel_size=(3,3), padding='same', activation = 'relu'), input_shape=(1, 150, 150, 3))) model.add(TimeDistributed(AveragePooling2D())) model.add(TimeDistributed(Flatten())) model.add(LSTM(100)) model.add(Dense(24, activation='relu',name='output')) model.add(Dense(4, activation = 'softmax')) optimizer = Adam(lr=0.001) model.compile(optimizer = optimizer, loss = 'categorical_crossentropy', metrics=['accuracy']) reduce_lr = ReduceLROnPlateau(monitor = 'val_accuracy', factor = 0.3, patience = 2, min_delta = 0.001, mode = 'auto', verbose = 1) hist_cnn_lstm = model.fit(x_train, y_train, batch_size=64, epochs=15, validation_data = (x_valid, y_valid), callbacks=reduce_lr)
内容的提问来源于stack exchange,提问作者Blackcat
相关产品推荐
相关产品推荐

