请帮助我了解如果将我的输入数据标准化为[-0.5。 0.5],否则不会过拟合。

我正在解决一个回归ML问题,试图检测图像上4个关键点的位置。为此,我导入预训练的ResNet 50并将其顶层替换为以下体系结构:


ResNet之后的展平层
具有256个节点的完全连接(密集)层,然后激活LeakyRelu和批处理规范化
另一个具有128个节点的完全连接层,之后还有LeakyRelu和批处理规范化
最后一个全连接层(具有8个节点),该层为我提供4个关键点的8个坐标(4 Xs和4 Ys)。


由于我坚持使用Keras框架,因此我使用ImageDataGenerator生成数据流(图像)。由于模型的输出(8个数字:4个关键点中的每个坐标为2个坐标)被归一化为[-0.5,0.5]范围,因此我决定模型(图像)的输入也应处于此范围内,因此将其归一化为在Keras的preprocessing_function中使用ImageDataGenerator具有相同的范围。

我开始进行模型训练后,问题就出现了。我已经冻结了整个ResNet(训练= False),目的是首先将顶层的渐变移动到适当的程度,然后才解冻一半ResNet并微调模型。在冻结ResNet的情况下进行训练时,我注意到我的模型在几个时期之后就过度拟合。出乎意料的是,即使我的数据集大小相当不错(25k图像)并且采用了批量标准化,它也会发生。

更令人惊讶的是,如果我从输入归一化转向[-0.5,0.5]并使用tf.keras.applications.resnet50.preprocess_input进行图像预处理,问题将完全消失。这种预处理方法无法规范化图像数据,而且令我惊讶的是,可以进行适当的模型训练而不会过度拟合。

我尝试使用具有不同概率的Dropout,即L2正则化。还尝试通过减少顶层的数量和每个顶层中的节点数量来降低模型的复杂性。我确实在学习速度和批量大小。如果我的输入数据被归一化,没有任何帮助,而且我也不知道为什么会发生这种情况。

重要提示:当使用VGG代替ResNet时,一切似乎都正常工作!

我真的很想弄清楚为什么会这样。



UPD:该问题是由两个原因引起的:
-ResNet中的批处理规范化层在冻结时无法正常工作
-ResNet的图像预处理应使用Z分数完成

经过上述两个修复后,一切似乎都正常运行!

最佳答案

在下面提及解决方案以使社区受益。

通过进行以下更改可以解决问题:


冻结时,Batch Normalization layers中的ResNet无法正常工作。因此,在训练模型之前,Batch Normalization Layers中的ResNet应该为unfreezed
ResNet的图像预处理(规范化)应使用Z-score而不是Keras的preprocessing_function中的ImageDataGenerator

08-16 05:35