如何为LSTM-CNN模型适配卫星图像数据的输入形状?
问题分析与解决方案
原始问题信息
数据集维度输出:
print(train_x.shape,train_y.shape,test_x.shape,test_y.shape) (9219, 7, 7, 12) (9219,) (3951, 7, 7, 12) (3951,)待修改模型代码:
model = Sequential() model.add(Conv1D(32, 4, activation='relu', padding='same', input_shape= (-----))) model.add(LSTM(32, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(64, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(128)) model.add(Dense(3, activation='sigmoid'))
你的卫星图像数据集每个样本是7×7的12通道图像,而当前使用的Conv1D+LSTM混合模型仅支持1D序列输入,因此需要先调整数据维度,再设置匹配的input_shape。
核心思路
Conv1D和LSTM的输入格式为(序列长度, 特征数),需将2D空间结构(7×7)转换为1D序列,同时明确序列维度与特征维度的对应关系,以下两种方案可按需选择:
方案一:空间像素展平为序列,通道作为特征
若需关注空间像素间的序列关联,将7×7的空间像素展平为49个序列步,每个步对应12个通道特征,样本维度变为(49, 12):
- 先对数据集做维度重塑:
# 重塑训练集和测试集 train_x = train_x.reshape((train_x.shape[0], 7*7, 12)) test_x = test_x.reshape((test_x.shape[0], 7*7, 12))
- 模型的
input_shape设置为(49, 12),修改后的完整代码:
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv1D, LSTM, MaxPooling1D, Dense model = Sequential() model.add(Conv1D(32, 4, activation='relu', padding='same', input_shape=(49, 12))) model.add(LSTM(32, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(64, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(128)) model.add(Dense(3, activation='sigmoid'))
方案二:通道作为序列,空间像素展平为特征
若需关注通道(如不同光谱波段、时间序列)间的关联,将12个通道视为序列步,7×7空间像素展平为49个特征,样本维度变为(12, 49):
- 数据集重塑:
train_x = train_x.reshape((train_x.shape[0], 12, 7*7)) test_x = test_x.reshape((test_x.shape[0], 12, 7*7))
- 模型的
input_shape设置为(12, 49):
model = Sequential() model.add(Conv1D(32, 4, activation='relu', padding='same', input_shape=(12, 49))) model.add(LSTM(32, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(64, return_sequences=True)) model.add(MaxPooling1D(2)) model.add(Conv1D(16, 8, activation="relu", padding='same')) model.add(LSTM(128)) model.add(Dense(3, activation='sigmoid'))
关键注意点
- 两种方案的选择取决于你的业务需求:优先空间特征选方案一,优先通道序列特征选方案二。
- 训练集与测试集必须执行完全相同的维度转换,否则会出现输入维度不匹配的错误。
内容的提问来源于stack exchange,提问作者Hadi Emami
相关产品推荐
相关产品推荐

