听它爹说他孩儿:Keras 学习笔记 5.2

过度拟合与欠缺拟合

克服过度拟合的过程叫做正则化。让我们仔细看看最普通的正则化技术,以及它们的实际应用:本笔记 4.3 电影评论分类的改进。

减小网络尺寸

防止过度拟合最简单的办法是减小网络尺寸,即减少模型可学习参数的数目。决定模型参数多少的,是层的数目和每层单元的数目。模型的参数越多,存储容量越大,表示训练样本及其目标影射关系的词典性能越好。例如,具有 500,000 二值参数的模型,可以轻松学会 MNIST 训练集全部数字的分类。要永远记住:深度学习模型可以很好地拟合训练数据,但真正的挑战是泛化,不是拟合。

同时也要记住,你的模型应当有足够的存储资源,以使用足够的参数,防止欠缺拟合。网络的大小应该适中,不宜过大或过小、

不幸的是,无法简单确定正确的网络层数和每层单元数。你必须评估不同架构的数组,以找到适合你的数据的模型大小。评估要用你的验证数据,不能用测试数据。通常的流程是这样:起初用相对很少的网络层和参数,然后逐渐增大层的容量,或者增加新层,直到你看见验证损失的逐渐降低。

用电影评论分类的问题做下实验:

 原始模型 

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

 减少容量后的模型 

model = models.Sequential()
model.add(layers.Dense(4, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(4, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

 增加容量后的模型 

model = models.Sequential()
model.add(layers.Dense(512, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
使用权重正则化技术
你可能熟悉奥卡姆剃刀定律(Occam's Razor):对某一问题有两种解释,用的假设最少、最简单的往往是正确的解释。相同的理念也可用于神经网络的学习模型:给出网络架构和一些训练数据、多组权重值(多个模型),可以解释这些数据。简单的模型比复杂的模型更少出现过度拟合。

这里所说的简单模型是这样的:它的各参数值的分布熵较小,或者,如你前面见到的,它的参数较少。“熵”的物理意义是体系混乱程度的度量。减缓过度拟合的通常做法,是限制网络的复杂程度,强制它的权重取值范围很小,权重分布更为规范。这就是权重正则化,在网络的损失函数中,对较大权重增加成本。这种成本出自两种计算:

  • L1 范式 —— 增加的成本是权重系数有比例的绝对值。
  • L2 范式 —— 增加的成本是权重系数有比例的平方值。

Keras 权重正则化的实现,是把正则生成器的实例作为关键字参数,传递给各层。让我们给影评分类网络增加 L2 范式正则化。

  给模型增加 L2 范式正则化  

from keras import regularizers
model = models.Sequential()
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                       activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                       activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

l2(0.001) 的含意是:网络层权重矩阵的每一系数增加 0.001与权重系数值的乘积,从而加大网络的总损失。注意,因为这一惩罚只在训练时采用,网络训练时的损失远大于测试时的损失。

你还可以这样使用 Keras 的正则化生成器。

from keras import regularizers
regularizers.l1(0.001) # L1 正则生成器
regularizers.l1_l2(l1=0.001, l2=0.001) # L1 和 L2 同步的正则生成器
使用舍弃技术

舍弃,是神经网络正则化技术最有效、最常用的之一。舍弃技术用于网络层,把训练过程中层输出特征的数字,随机舍弃(设置为零)。假如训练过程中,对于某个输入,一个层返回向量 [0.2, 0.5, 1.3, 0.8, 1.1] 。在应用舍弃技术后,向量中的几个值随机地变为零,例如 [0, 0.5, 1.3, 0, 1.1]。舍弃率是归零的个数在全部特征中的占比,通常 0.2 至 0.5。在测试阶段,并不舍弃特征值,相反地,层的输出值按舍弃率同等缩小,因此,测试时得到的特征值比训练时多。

设想有个 Numpy 矩阵包含某层的输出 layer_output,形状是(批量大小,特征值)。训练时,我们把矩阵的一些值随机归零:

layer_output *= np.random.randint(0, high=2, size=layer_output.shape)# 训练时,舍弃过 50% 的输出

测试时,我们按舍弃率缩小输出值。在此,缩小0.5(因为此前舍弃过这些输出):

layer_output *= 0.5 # 测试时

注意,这种处理的实现,可在训练时采取两种操作,测试时保留输出不变。这是实践中经常用到的:

layer_output *= np.random.randint(0, high=2, size=layer_output.shape) # 训练时
layer_output /= 0.5 # 注意,这里是放大不是缩小

在 Keras 中,你可以用 Dropout 层把舍弃技术引入神经网络。 Dropout 层用于舍弃前面层的输出:

model.add(layers.Dropout(0.5))

我们在 IMDB 网络中增加两个 Dropout 层,看看它们降低过度拟合的效果。

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

概括起来,防止神经网络过度拟合的常用方法有:

  • 使用更多的训练数据
  • 减小网络容量
  • 使用权重正则化技术
  • 使用舍弃技术





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值