问题
我一直在研究回归 CNN 实现来预测时间序列数据,并遇到了一个问题,即我的验证损失和训练损失在训练期间立即出现分歧,如下所示:
通常,当训练期间验证损失增加时,过度拟合是罪魁祸首,但在这种情况下,验证损失最初似乎并没有减少,这很奇怪。我已经尝试用正常的过度拟合修复来处理这个问题,即增加 dropout 和增加数据量,但无济于事。
作为参考,上面的模型是用大约训练的。60,000 个样本,如混淆矩阵所示(稍后会详细介绍),但我还训练了一个包含超过 250,000 个样本的模型并得到了相同的结果:

出于这个原因,在我看来,过度拟合不太可能是唯一的问题,因为我认为将数据增加这么多会产生一些实际影响。
细节
概述
该项目试图通过从特征数据创建图像来使用 CNN 执行时间序列预测。数据有 28 个独立的特征,通过使用 28 天的窗口捕获这些特征(使每行像素为该特征时间序列的 28 天)创建 28x28 图像。这些特征本身是相关的,但不是必须的(例如,有些在 0-1 左右,有些在 100 左右,有些包括负数)
每个图像都有一个标签,它是一个介于 -1 和 1 之间的值,并且标签的符号特别重要,所以这个问题也可以通过将符号作为一个类来框定为分类问题(这就是为什么混淆矩阵是作为度量创建的)。出于这个原因,我还注意到数据集是平衡的,几乎正好有 50% 的正/负。我也使用分类测试了这个项目,但问题仍然存在。
训练图像
以下是我正在生成的图像的一些示例,以及标准化前后(不同)图像中的值示例。
预处理
每个特征时间序列在每个图像的范围内使用以下代码在 0,1 之间进行归一化。我在这里的第一个假设是,由于我的特征数据具有趋势,因此最好在图像内进行归一化,而不是在数据集的整个长度上进行归一化(使后面的图像具有更高的值)。我的第二个假设是不可能一次对整个图像阵列进行归一化(例如,对于 MNIST 数据除以 255),因为每一行像素的比例都不同。
def normalizeImages(dataset):
imageList = dataset['trainingImages'].values
for i in range(len(imageList)):
image = imageList[i]
for j in range(len(image)):
row = image[j].reshape(len(image[j]),1)
minmaxScaler = MinMaxScaler(feature_range=(0, 1)) # 0,1 seems to be standard for image data
minmaxScaler.fit(row)
row = minmaxScaler.transform(row)
image[j] = row.squeeze()
imageList[i] = image
dataset['trainingImages'] = imageList
return dataset
值得注意的是,在将所有图像拆分为验证/测试集然后打乱之前,这以完全相同的方式应用于所有图像。
除了对图像进行归一化之外,特征本身还使用聚类在图像中排列,以在 Y 轴上将相似的系列组合在一起以增加局部性。
模型
所使用的模型基于 MNIST 分类的一些示例:
model = Sequential([
Conv2D(32, (3, 3), input_shape=(inputDim, inputDim, 1), activation='relu'),
Conv2D(64, (3, 3), activation='relu'),
MaxPooling2D(pool_size=(4, 4)),
Flatten(),
Dense(128, activation='relu'),
Dropout(0.25),
Dense(64, activation='relu'),
Dropout(0.5),
Dense(1,activation='linear')
])
model.compile(loss='mse', optimizer=keras.optimizers.Adadelta(), metrics=['mse',tf.keras.metrics.RootMeanSquaredError()])
我已经用 100-3000 的时期以及 32-3500 的批量大小训练了这个模型,没有不同的结果。
我还试过什么
以下是我尝试过的其他一些事情,但还有更多,请随时询问任何其他细节。
- 在整个特征时间序列上规范化图像,而不仅仅是在图像内
- 使用时间序列上的第一个差异来消除趋势,然后对整个数据集/图像内进行归一化
- 在 MNIST 数据上进行训练,模型(针对分类进行了修改)将其学习到 98% 的准确率。
- 将优化器更改为 ADAM
- 改变 ADADELTA 的学习率:从 0.001 到 0.0001 完全阻止学习
- 按批次而不是每个时期输出损失,看看我是否只是在前几个时期过度拟合,但看起来不像。
我的理论
- 我的图像没有很好地归一化,因此即使模型能够学习具有 250,000 个样本的训练集,它们也没有传达要学习的数据?
- 测试集图像在某种程度上与训练图像不同,尽管它们以完全相同的方式进行归一化。
- 我仍然以某种方式过度拟合,需要更多数据/辍学/其他?
结论性想法
我绝不是该领域的专家,因此很可能我对标准化和图像处理做出了某种假设/错误,从而阻止了我的模型实际从我的图像中学习。
我已尝试尽可能多地包含我认为与我的问题相关的信息,但我很乐意根据要求提供任何其他信息。
提前感谢您提供的任何建议和知识,以帮助我解决此问题!
编辑
回应 etiennedm
我将密集的 64 层更改为以下内容:
Dense(64, activation='tanh'),
我之前曾尝试在没有任何 dropout 的情况下运行,但这并没有什么不同,因为模型似乎可以很好地学习训练数据,我认为删除 dropout 只会使其过拟合更快?

这是 28 个特征时间序列在其完整数据上而不是仅在 28 天图像内标准化时的结果。我使用以下代码来执行此操作:
minmaxScaler = MinMaxScaler(feature_range=(0,1))
minmaxScaler.fit(trainingSample)
featureData = minmaxScaler.transform(featureData)
可能值得注意的是,缩放器仅适用于训练数据,然后应用于整个数据集以消除训练/测试集之间的数据泄漏。结果似乎仍然大致相同:







