You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CNN-LSTM回归模型的TFRecord数据输入方法求助

问题描述

我拥有2000年、2010年、2020年三个年份的图像数据集,分别存储为combined_2000.tfrecord、combined_2010.tfrecord和combined_2020.tfrecord文件,图像尺寸为40×40×7,每个文件包含图像与标签。计划采用CNN-LSTM架构构建回归模型,已完成数据集拆分,但不清楚如何将三年的图像输入到定义好的模型中。

已完成的数据集拆分代码:

train_size = int(0.7 * 2000)
val_size = int(0.15 * 2000)
test_size = 2000 - train_size - val_size

train_tf_2000 = combined_dataset_2000.take(train_size)
remaining_tf_2000 = combined_dataset_2000.skip(train_size)
val_tf_2000 = remaining_tf_2000.take(val_size)
test_tf_2000 = remaining_tf_2000.skip(val_size)

train_tf_2010 = combined_dataset_2010.take(train_size)
remaining_tf_2010 = combined_dataset_2010.skip(train_size)
val_tf_2010 = remaining_tf_2010.take(val_size)
test_tf_2010 = remaining_tf_2010.skip(val_size)

train_tf_2020 = combined_dataset_2020.take(train_size)
remaining_tf_2020 = combined_dataset_2020.skip(train_size)
val_tf_2020 = remaining_tf_2020.take(val_size)
test_tf_2020 = remaining_tf_2020.skip(val_size)

已定义的CNN-LSTM模型:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, TimeDistributed, LSTM, Dense, Dropout

# Assuming your image dimensions are (image_height, image_width, num_channels)
input_shape = (40, 40, 7)  # Adjust num_channels if needed
num_years = 3


# Define CNN model
cnn = Sequential()
cnn.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
cnn.add(MaxPooling2D((2, 2)))
cnn.add(Flatten())

# Define LSTM model
model = Sequential()
model.add(TimeDistributed(cnn, input_shape=(num_years, *input_shape)))
model.add(LSTM(64, return_sequences=True))
model.add(LSTM(64))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1))  # Single output unit for regression

model.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae'])
解决方案

你的模型输入要求是形状为(num_years, 40, 40, 7)的时间序列样本,即每个输入样本由同组的2000、2010、2020三年的图像按时间顺序组成。需要通过以下步骤将拆分后的数据集适配模型输入:

1. 确保样本顺序对齐

首先要保证combined_dataset_2000、combined_dataset_2010、combined_dataset_2020中的样本是一一对应的(第i个样本属于同一组,对应三年的观测数据),这是合并的前提。

2. 合并同组三年样本

使用tf.data.Dataset.zip将三年的数据集按样本索引配对,再通过map操作把三年的图像拼接成时间序列,同时提取对应标签(这里以2020年的标签作为回归目标为例,可根据需求调整):

import tensorflow as tf

# 合并三年样本为模型输入格式
def combine_year_samples(img_2000, label_2000, img_2010, label_2010, img_2020, label_2020):
    # 将三年图像拼接成(3, 40, 40, 7)的时间序列
    sequence_imgs = tf.stack([img_2000, img_2010, img_2020], axis=0)
    # 自定义回归目标,这里取2020年标签,可替换为三年标签的均值等逻辑
    target_label = label_2020
    return sequence_imgs, target_label

# 合并训练集
train_dataset = tf.data.Dataset.zip((train_tf_2000, train_tf_2010, train_tf_2020))
train_dataset = train_dataset.map(lambda x, y, z: combine_year_samples(x[0], x[1], y[0], y[1], z[0], z[1]))

# 合并验证集
val_dataset = tf.data.Dataset.zip((val_tf_2000, val_tf_2010, val_tf_2020))
val_dataset = val_dataset.map(lambda x, y, z: combine_year_samples(x[0], x[1], y[0], y[1], z[0], z[1]))

# 合并测试集
test_dataset = tf.data.Dataset.zip((test_tf_2000, test_tf_2010, test_tf_2020))
test_dataset = test_dataset.map(lambda x, y, z: combine_year_samples(x[0], x[1], y[0], y[1], z[0], z[1]))

3. 数据集优化(可选但推荐)

添加批处理、预取操作提升训练效率:

batch_size = 32

train_dataset = train_dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)
val_dataset = val_dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)
test_dataset = test_dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)

4. 模型训练

直接使用合并后的数据集训练模型:

history = model.fit(
    train_dataset,
    validation_data=val_dataset,
    epochs=20,
    verbose=1
)

# 测试模型
test_loss, test_mae = model.evaluate(test_dataset, verbose=1)
print(f"Test Loss: {test_loss}, Test MAE: {test_mae}")

关键说明

  • 如果回归目标是三年序列对应的综合值,只需修改combine_year_samples函数中的target_label计算逻辑(比如取三年标签的平均值)。
  • 确保读取TFRecord的函数输出为(image, label)格式的元组,否则需要调整combine_year_samples的参数解析逻辑。

内容的提问来源于stack exchange,提问作者riskiem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:44:49