我在一个项目中使用了densenet模型,并在使用正则化时遇到了一些困难。
在没有使用任何正则化的情况下,验证损失和训练损失(均方误差,MSE)都在降低。不过,训练损失下降得更快,导致最终模型出现了一些过拟合现象。
因此,我决定使用dropout来避免过拟合。在使用Dropout时,验证损失和训练损失在第一个epoch时都下降到了大约0.13,并且在接下来的大约10个epoch中保持不变。
在那之后,这两个损失函数的下降方式与没有使用dropout时相同,再次导致了过拟合。最终的损失值与没有使用dropout时大致相同。
因此,对我来说,dropout似乎并没有真正起作用。
然而,如果我切换到L2正则化,我能够避免过拟合,但我更希望使用Dropout作为正则化方法。
现在我想知道是否有人也遇到过这种情况?
我在密集块(瓶颈层)和过渡块中都使用了dropout(dropout率=0.5):
def bottleneck_layer(self, x, scope): with tf.name_scope(scope): x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1') x = Relu(x) x = conv_layer(x, filter=4 * self.filters, kernel=[1,1], layer_name=scope+'_conv1') x = Drop_out(x, rate=dropout_rate, training=self.training) x = Batch_Normalization(x, training=self.training, scope=scope+'_batch2') x = Relu(x) x = conv_layer(x, filter=self.filters, kernel=[3,3], layer_name=scope+'_conv2') x = Drop_out(x, rate=dropout_rate, training=self.training) return xdef transition_layer(self, x, scope): with tf.name_scope(scope): x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1') x = Relu(x) x = conv_layer(x, filter=self.filters, kernel=[1,1], layer_name=scope+'_conv1') x = Drop_out(x, rate=dropout_rate, training=self.training) x = Average_pooling(x, pool_size=[2,2], stride=2) return x
回答:
在没有使用任何正则化的情况下,验证损失和训练损失(均方误差,MSE)都在降低。不过,训练损失下降得更快,导致最终模型出现了一些过拟合现象。
这不是过拟合。
当你的验证损失开始增加,而你的训练损失继续下降时,过拟合就开始了;这是它的典型特征:
该图像改编自维基百科关于过拟合的条目 – 水平轴上可能有不同的内容,例如深度或提升树的数量,神经网络拟合迭代的次数等。
训练损失和验证损失之间的(通常预期的)差异是完全不同的东西,称为泛化差距:
理解泛化的一个重要概念是泛化差距,即模型在训练数据上的表现与其在来自相同分布的未见数据上的表现之间的差异。
实际上,验证数据确实是未见数据。
因此,对我来说,dropout似乎并没有真正起作用。
情况很可能是这样的 – dropout并不期望总是对每个问题都有效。