学习笔记14:L2正则化和丢弃(dropout)

训练模型的过拟合会降低模型的泛化能力,采用正则化的方法解决过拟合的问题。

正则化的原理是在损失函数中增加一个惩罚项来限制过大的权重。

L0正则化的值是模型参数中非零参数的个数。

L1正则化表示各个参数绝对值之和。

L2正则化标识各个参数的平方的和的开方值。

3、L0正则化

根据上面的讨论,稀疏的参数可以防止过拟合,因此用L0范数(非零参数的个数)来做正则化项是可以防止过拟合的。

从直观上看,利用非零参数的个数,可以很好的来选择特征,实现特征稀疏的效果,具体操作时选择参数非零的特征即可。但因为L0正则化很难求解,是个NP难问题,因此一般采用L1正则化。L1正则化是L0正则化的最优凸近似,比L0容易求解,并且也可以实现稀疏的效果。

4、L1正则化

L1正则化在实际中往往替代L0正则化,来防止过拟合。在江湖中也人称Lasso。

L1正则化之所以可以防止过拟合,是因为L1范数就是各个参数的绝对值相加得到的,我们前面讨论了,参数值大小和模型复杂度是成正比的。因此复杂的模型,其L1范数就大,最终导致损失函数就大,说明这个模型就不够好。

5、L2正则化

L2正则化可以防止过拟合的原因和L1正则化一样,只是形式不太一样。


L2范数是各参数的平方和再求平方根,我们让L2范数的正则项最小,可以使W的每个元素都很小,都接近于0。但与L1范数不一样的是,它不会是每个元素为0,而只是接近于0。越小的参数说明模型越简单,越简单的模型越不容易产生过拟合现象。

L2正则化江湖人称Ridge,也称“岭回归”


Dropout

Dropout的思想其实非常简单粗暴:对于网络的每一层,随机的丢弃一些单元。如下图所示:


关于为什么dropout能够减轻过拟合,ng给出了两个比较直观的解释:

  • 正是因为在每一层随机的丢弃了一些单元,所以相当于训练出来的网络要比正常的网络小的多,在一定程度上解释了避免过拟合的问题。
  • 如下图所示的一个简单单层网络,因为每一个特征都有可能被丢弃,所以整个网络不会偏向于某一个特征(把某特征的权重的值赋的很大),会把每一个特征的权重都赋的很小,这就有点类似于L2正则化了,能够起到减轻过拟合的作用。 
    单层网络
这个方法看起来有点疯狂,但是他确实是有效的。下面开始从技术实现方面来看下dropout正则项,这里最重要的一个参数就是  keep_prob ,称作 保留概率 (同样,1-keep_prob 则为丢弃概率),比如某一层的  keep_prob=0.8

,则意味着某一层随机的保留80%的神经单元(也即有20%的单元被丢弃)

TensorFlow 提供了一个 tf.nn.dropout() 函数,你可以用来实现 dropout。

让我们来看一个如何使用 tf.nn.dropout()的例子。

keep_prob = tf.placeholder(tf.float32) # probability to keep units

hidden_layer = tf.add(tf.matmul(features, weights[0]), biases[0])
hidden_layer = tf.nn.relu(hidden_layer)
hidden_layer = tf.nn.dropout(hidden_layer, keep_prob)

logits = tf.add(tf.matmul(hidden_layer, weights[1]), biases[1])

上面的代码展示了如何在神经网络中应用dropout

tf.nn.dropout()函数有两个参数:

  1. hidden_layer:你要应用 dropout 的 tensor
  2. keep_prob:任何一个给定单位的留存率(没有丢弃的)

keep_prob 可以让你调整 drop 单位的数量。为了补偿被丢弃的单位,tf.nn.dropout() 把所有保留下来的单位(没有丢弃的)乘 1/keep_prob

在训练时,一个好的keep_prob初始值是0.5

在测试时,把 keep_prob 值设为1.0 ,这样保留所有的单位,最大化模型的能力。

tensorflow示例

# Solution is available in the other "solution.py" tab
import tensorflow as tf

hidden_layer_weights = [
    [0.1, 0.2, 0.4],
    [0.4, 0.6, 0.6],
    [0.5, 0.9, 0.1],
    [0.8, 0.2, 0.8]]
out_weights = [
    [0.1, 0.6],
    [0.2, 0.1],
    [0.7, 0.9]]

# Weights and biases
weights = [
    tf.Variable(hidden_layer_weights),
    tf.Variable(out_weights)]
biases = [
    tf.Variable(tf.zeros(3)),
    tf.Variable(tf.zeros(2))]

# Input
features = tf.Variable([[0.0, 2.0, 3.0, 4.0], [0.1, 0.2, 0.3, 0.4], [11.0, 12.0, 13.0, 14.0]])

keep_prob = tf.placeholder(tf.float32)
hidden_layer = tf.add(tf.matmul(features, weights[0]), biases[0])
hidden_layer = tf.nn.relu(hidden_layer)
hidden_layer = tf.nn.dropout(hidden_layer, keep_prob)

logits = tf.add(tf.matmul(hidden_layer, weights[1]), biases[1])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(logits, feed_dict={keep_prob:0.5}))

[[  9.55999947  16.        ]
 [  0.82600003   1.59000015]
 [ 33.74000168  43.38000107]]

猜你喜欢

转载自blog.csdn.net/Softdiamonds/article/details/80365116