您的位置:首页 > 运维架构

深度学习-L1 Regularization、L2 Regularization、Dropout和人工扩大训练集减少Overfitting

2018-01-26 15:33 459 查看
学习彭亮《深度学习进阶:算法与应用》课程

背景

增加训练数据集的量是减少overfitting的途径之一:深度学习-softmax和Overfitting

减小神经网络的规模, 但是更深层更大的网络潜在有更强的学习能力

即使对于固定的神经网络和固定的训练集, 仍然可以减少overfitting:Regularization

L2 Regularization

常见的一种regularization: (weight decay)L2 regularization

Regularized cross-entropy:



即在原来的cost



上增加了一项:



权重之和 (对于神经网络里面的所有权重w相加)

其中:

λ>0: regularization 参数

n: 训练集包含实例个数

对于二次cost,

Regularized quadratic cost:



对于以上两种情况, 可以概括表示为:



Regularization的Cost偏向于让神经网络学习比较小的权重w, 当更新权重时除非第一项的Co明显减少.

λ: 调整两项的相对重要程度, 较小的λ倾向于让第一项Co最小化. 较大的λ倾向与最小化增大的项(权重之和).

对以上公式求偏导数:



以上两个偏导数可以用之前介绍的backpropagation算法求得:

添加了一个项:



即对w求偏导多了后面那一项,而对b求偏导没有变。

根据梯度下降算法, 更新法则变为:



对于随机梯度下降(stochastic gradient descent):



求和是对于一个mini-batch里面所有的x

实验

隐藏层: 30个神经元, mini-batch size: 10, 学习率: 0.5, cross-entropy

#coding=utf-8
# @Author: yangenneng
# @Time: 2018-01-26 14:10
# @Abstract:

import mnist_loader
training_data, validation_data, test_data = mnist_loader.load_data_wrapper()
import network2
net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost)
net.large_weight_initializer()
net.SGD(training_data[:1000], 400, 10, 0.5,evaluation_data=test_data, lmbda = 0.1,monitor_evaluation_cost=True, monitor_evaluation_accuracy=True,monitor_training_cost=True, monitor_training_accuracy=True)


对于训练集上的准确率表现依然很好:



但是这次accuracy在test data上面持续增加:



最高的accuracy也增加了, 说明regularization减少了overfitting

如果用50,000张训练集:

同样的参数: 30 epochs, 学习率 0.5, mini-batch size: 10

需要改变λ, 因为n从1,000变到50,000了

net.SGD(training_data, 30, 10, 0.5,
... evaluation_data=test_data, lmbda = 5.0,
... monitor_evaluation_accuracy=True, monitor_training_accuracy=True)


结果好很多, accuracy对于测试集提高了, 两条曲线之间的距离大大减小



如果用隐藏层100个神经元(之前30个)

net = network2.Network([784, 100, 10], cost=network2.CrossEntropyCost)
net.large_weight_initializer()
net.SGD(training_data, 30, 10, 0.5, lmbda=5.0,
... evaluation_data=validation_data,
... monitor_evaluation_accuracy=True)


最终结果在测试集上accuracy达到97.92, 比隐藏层30个神经元提高很多

如果调整优化一下参数 用 学习率=0.1, λ=5.0, 只需要30个epoch, 准确率就超过了98%,达到了98.04%

加入regularization不仅减小了overfitting, 还对避免陷入局部最小点 (local minimum), 更容易重现实验结果

为什么Regularization可以减少overfitting?

假设一个简单数据集



为了建立方程表示

(1)我们可以建立:



(2)我们也可以建立:y=2*x



那个模型更好?

y=2x更简单,仍然很好描述了数据, 巧合的概率很小,所以我们偏向y=2x

x^9的模型更可能是对局部带有数据噪音的扑捉

在神经网络中:

Regularized网络更鼓励小的权重, 小的权重的情况下, x一些随机的变化不会对神经网络的模型造成太大影响, 所以更小可能受到数据局部噪音的影响.

Un-regularized神经网路, 权重更大, 容易通过神经网络模型比较大的改变来适应数据,更容易学习到局部数据的噪音

Regularized更倾向于学到更简单一些的模型

简单的模型不一定总是更好,要从大量数据实验中获得,目前添加regularization可以更好的泛化更多的从实验中得来,理论的支持还在研究之中

L1 regularization:

L2求平方,L1求绝对值



跟L2 regularization 相似, 但不一样

求偏导:



sgn(w) 指的是w的符号, +1如果w是正数, -1如果w是负数

权重更新法则:



对比之前的L2更新法则:



都是减小权重, 方法不同:

L1减少一个常量, L2减少权重的一个固定比例

如果权重本身很大, L1减少的比L2更少

如果权重本身很小, L1减少的比L2更多

L1倾向于集中在少部分重要的连接上

当w=0, 偏导数∂C/∂w无意义, 因为|w|的形状在w=0时是一个V字形尖锐的拐点,不可导.

所以, 当w=0时,我们就使用un-regulazied表达式, sgn(0) = 0. 本来regularization的目的就是减小权重, 当权重=0时,无需减少

Dropout:

和L1, L2 regularization非常不同, 不是针对cost函数增加一项,而是对神经网络本身的结构做改变

假设我们有一个神经网络



通常, 我们根据输入的x,正向更新神经网络,算出输出值,然后反向根据backpropagation来更新权重和偏向

但是, dropout不同:

开始, 删除掉隐藏层随机选取的一半神经元



然后, 在这个更改过的神经网络上正向和反向更新, 利用一个mini-batch

然后, 恢复之前删除过的神经元, 重新随机选择一半神经元删除, 正向, 反向, 更新w,b

重复此过程

最后,学习出来的神经网络中的每个神经元都是在只有一半神经元的基础上学习的, 当所有神经元被恢复后, 为了补偿, 我们把隐藏层的所有权重减半

为什么dropout可以减少overfitting?

假设我们对于同一组训练数据, 利用不同的神经网络来训练, 训练完成之后, 求输出的平均值, 这样可以减少overfitting

Dropout和这个是同样的道理, 每次扔掉一半隐藏层的神经元, 相当于我们在不同的神经网络上训练了

减少了神经元的依赖性, 也就是每个神经元不能依赖于某个或者某几个其他神经元, 迫使神经网聚学习更加和其他神经元联合起来的更加健硕的特征

介绍dropout的文章, 对于以前MNIST最高的accuracy是98.4%, 利用dropout, 提高到98.7%

人工扩大训练集减少Overfitting

之前看到了只有1000张图和50,000张图片训练的区别

比较一下随着训练集的增大, accuracy的变化

参数: 隐藏层: 30个神经元, mini-batch size: 10, 学习率0.5, λ=5.0 (对于整个训练集, 对应减少当训练集减少时)

(1)当使用cross-entropy cost训练30个epochs



把图像转为转为:log scale:



accuracy一直在增加, 可以想象如果大规模增加训练集, 可以达到更高准确率

有label的训练集通常不好获得, 一种方法, 人工扭转图片产生更多训练数据:



旋转不同角度, 增加很多训练数据

比如: MNIST, 一个隐藏层有800个神经元的网络, 98.4%, 人工增加数据后, 达到98.9%, 发明了一下人工会改变图像的模拟方法进一步增大训练集, 准确率达到了 99.3%

增大时, 要模拟现实世界中这种数据可能出现的变化, 来概括更广

对比神经网络和SVM:



network在每个点的精度都高于SVM

比较两个算法的时候, 是否使用同样的训练集很重要, 因为训练集的增大可以提高accuracy

初始化权重:

之前: 随机从正态分布中产生(均值0, 方差1)

正态分布:



如果均值=0, 方差=1, 标准正太分布

均值: mean, average x_bar = sum(xi, i = 1 ….n) / n, 一组数据它的中心趋势的衡量

标准差: standard deviation, sigma = sqrt(sum((xi - x_bar)^2, (i=1, …. n)) / (n-1))

方差: 标准差^2 = 方差

eg:

X = (x1, x2, x3, x3, x5) = 1, 2, 3, 4, 5

x_bar = (1+2+3+4+5)/5= 15/5 =3

sqrt(((1-3)^2 + (2-3)^2 + (3-3)^2 + (4-3)^2 + (5-3)^2) / (5 - 1))
= sqrt( 4 + 1 + 0 + 1+ 4) / 4))
= sqrt(2.5)
= 1.58


假设如下一个神经网络:



假设输入层x: 一半是0, 一半是1, 一共1000个输入层



结果: 一半消失了, 剩下的500个1, 加上b, 分布: 标准差: sqrt(501) = 22.4



z很多都远远大于1, 或者远远小于-1, 根据sigmoid函数



输出的值都接近0和1, 当权重变化时, 更新量很小, 对于更新后面的层, 更新量很小,学习很慢,使隐藏层饱和了, 跟之前我们说的输出层饱和问题相似, 对于输出层,我们用改进的cost函数,比如cross-entropy, 但是对于隐藏层, 我们无法通过cost函数来改进。

更好的方法来初始化权重?

从正态分布均值=0, 标准差差等于 1/sqrt(n_in),即1/输入层神经元个数的开方

重复500个1, 500个0作为输入时, z分布的标准差变成了sqrt(3/2) = 1.22

证明: 标准差 = 1 / sqrt(n_in) => 方差 = 1 / n_in

n_in = 1000, 方差 = 1/ 1000



不等于0的x有500, z的方差500*(1/1000) + b = 1/2 + 1 = 3/2

z的标准差变成了 sqrt(3/2)



大部分z在1和-1之间, 神经元没有饱和, 学习过程不会被减慢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: