防止或减轻过拟合的方式(一)——正则化

在进行模型搭建时常用的解决过拟合的方法有以下几种:

  · 采用更多的数据

  · 迫使模型的复杂度降低(减少层数、正则化)

  · dropout(提高鲁棒性)

  · 提早结束训练过程

  · 数据增强

这里重点讲正则化(regularization)

假定对于一个二分类问题,它的交叉熵损失函数为

J(ω) = - 1/m Σ [ yilnyi+ (1-yi)ln(1-yi') ]

所谓正则化,即在损失函数的基础上加上一个范数,当加上L1范数时,被称为L1正则化,当加上L2范数时,被称为L2正则化

其思想就是在损失函数中加入被称为正则化项(Regularizer)的惩罚

L1(θ) = ||θ||= Σ|θi|

L2(θ) = ||θ||22= Σ|θi|2

待优化的函数就从J(ω)变为了J(ω)+λL1(θ)或J(ω)+λL2(θ)

那么如何给网络结构添加这样的结构?代码如下:

l2_model = keras.Sequential([
    keras.layers.Dense(16,kernal_regularizer=keras.regularizers.l2(0.001)),
    keras.layers.Dense(16,kernel_regularizer=keras.regularizers.l2(0.001)),
    keras.layers.Dense(1,activation=tf.nn.sigmoid)
])

更加灵活的添加方式如下:

for step,(x,y) in enumerate(db):
    with tf.GradientTape() as tape:
        # ……
        loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y_onehot,out,from_logits=True))
        loss_regularization = []
        for p in network.trainable_variables:
            loss_regularization.append(tf.nn.l2_loss(p))
        loss_regularization = tf.reduce_sum(tf.stack(loss_regularization))
        loss = loss +0.0001 * loss_regularization
        
    grad = tape.gradient(loss,network.trainable_variables)
    optimizer.apply_gradients(zip(grad,network.trainable_variables))

最小化J(ω)+λL(θ)意味着需要在偏好小范数权重和拟合训练数据之间找到一个平衡,其根本思想是通过限制权重的大小,降低模型拟合训练集中存在噪音的概率,从而减轻过拟合。需要注意的是,这两种正则化在使用时存在两个主要的区别,首先L1正则化会让参数变得更稀疏(会有更多的参数变为0),而L2正则化不会;其次,计算L1正则化的公式不可导,而计算L2正则化的公式可导,这就导致了在优化时计算L2正则化损失函数的偏导数要更加简洁,而计算L1正则化损失函数的偏导数要更加复杂。

原文地址:https://www.cnblogs.com/zdm-code/p/12248766.html