DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、正则化以及优化--week3 超参数调试、Batch正则化和程序框架 一、调试处理 二、为超参数选择合适的范围 三、超参数训练的实践: Pandas VS Caviar 四、正则化网络的激活函数 五、将Batch Norm拟合进神经网络 六、Batch Norm为什么奏效 七、 测试的Batch Norm 八、 Softmax回归 九、 训练一个Softmax分类器 十、 深度学习框架 十一、 TensorFlow
week2中提到有如下的超参数:
- α
- hidden units
- mini-batch size
- β
- layers
- learning rate decay
- (β_1,β_2,ε)
颜色表示重要性,以及调试过程中可能会需要修改的程度。
那么如何选择超参数的值呢?
- 首先是粗略地随机地寻找最优参数
建议使用图右的方式,原因如下:
对于图左的超参数分布而言,可能会使得参考性降低,我们假设超参1是学习率α,超参2是ε,根据week2中Adam算法的介绍,我们知道ε的作用几乎可以忽略,所以对于图左25中参数分布来说,其本质只有5种参数分布。而右边则是25种随机分布,更能帮助我们选择合适的超参数。
- 其次在上面找到的最优参数分布周围再随机地寻找最有参数
二、为超参数选择合适的范围
上一节提到的的随机采样虽然能帮助我们寻找最优参数分布,但是这有点像大海捞针,如果能够指出参数取值的范围,然后再去寻找最优的参数分布岂不是更加的美滋滋?那如何为超参数选择合适的范围呢?
- (n^{[l]}=50,……,100)
- layers=2~4
- α=0.0001,……,1
此时需要注意了,如果按照线性划分的话(如下图),那么随机采样的值90%的数据来自[0.1,1]这个区间,这显然与不太符合随机性。
所以为了改进这一问题,我们需要将区间对数化来采样。例如我们将[0.0001,1]转化成四个区间[0.0001,0.001],[0.001,0.01],[0.01,0.1],[0.1,1],再转化成对数就是[-4,-3],[-3,-2],[-2,-1],[-1,0]。((10^{-4}=0.0001),其他同理取指数)。
然后我们可以用Python中提供的方法来实现随机采样:
r = -4*np.random.rand() # rand()表示在[0,1]上均匀采样, 最后的采样区间是[-4, 0]
a = pow(10, r)
- β=0.9,……,0.999
同理这里也不能使用线性轴来采样数据,我们可以通过对1-β=0.1,……,0.001来间接采样。转化成[0.1, 0.01],[0.01,0.001],转化成对数指数[-1,-2],[-2,-3]。
即(r∈[-3,-1],1-β=10^r,β=1-10^r),
三、超参数训练的实践: Pandas VS Caviar
-
Babysitting one model
这种方法适用于有足够的数据集,但是GPU,CPU资源有限的情况,所以可能只能训练一个模型,然后每天对模型做某一项超参数的修改,查看效果是否变得更好,如下图示
例如第一天令所有超参数随机初始化。到了第二天发现效果还不错,此时可以去增加学习率(也可以修改其他参数)。……,到了某一天加入修改了mini-batch size,结果效果明显减弱,这时则需要重新恢复到前一天的状态。
总的来说这一过程就像熊猫一样,只照顾一个宝宝,多的照顾不过来。
- Train many models in parallel
这种方法适用于财大气粗的情况,即并行训练多个模型,最后选出效果最好的一个即可。这就像鱼子酱一样,一下生多大一亿的孩子~~
四、正则化网络的激活函数
1.归一化输入数据
其实不仅仅只是归一化输入数据X,隐藏层的数据也是要归一化的。但是一般来说隐藏层数据有(Z)和(a)两种,在该视频教程中吴大大推荐归一化(z)。
- 输入数据归一化方法:
(μ=frac{1}{m}sum_{i}{x^{(i)}})
(σ^2=frac{1}{m}sum_{i}x^{(i)^2})
(x=frac{x-μ}{σ^2})
- 隐藏层数据归一化方法
(μ=frac{1}{m}sum_{i}{z^{(i)}-μ})
(σ^2=frac{1}{m}sum_{i}(z^{(i)^2}-μ)^2)
(z^{(i)}_{norm}=frac{z^{(i)}-μ}{sqrt{σ^2+ε}})
上面得到的归一化后的数据(z)都是服从均值为0,方差为1的,显然这样不能满足咱们的需求,所以还需要做进一步处理,如下:
( ilde{z}^{(i)}=γz^{(i)})+β
上式中的(γ)可以设置方差,(β)可以设置均值。
五、将Batch Norm拟合进神经网络
adding batch Norm to a network
working with mini-batches
一般的方法中
(z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]})
在上面归一化数据过程中需要减去均值,所以(b^{[l]})这一项可以省略掉,所以归一化后是
(z_{norm}^{[l]}=w^{[l]}a^{[l-1]})
为了能够使数据分布更加满足我们的要求,可以用如下公式
( ilde{z}^{[l]}=γ^{[l]}z_{norm}^{[l]}+β^{[l]})
Implementing gradient descent
for t= 1,……,numMinBatches
- 计算基于第t批数据的前向传播
- 在计算反向传播时使用( ilde{z}^{[l]}),得到(dw^{[l]},dβ^{[l]},dγ^{[l]})
- 更新参数
(w^{[l]}=w^{[l]}-αdw^{[l]})
(β^{[l]}=β^{[l]}-αdβ^{[l]})
(γ^{[l]}=γ^{[l]}-αdγ^{[l]})
六、Batch Norm为什么奏效
- 原因一
batch norm可以使得权重比你的网络更滞后或更深层,为了更好地理解可以看下面的例子:
如上图所示,假设我们现在要计算第三层隐藏层的值,很显然该层的计算结果依赖第二层的数据,但是第二层的数据如果未归一化之前是不可知的,分布是随机的。而如果进行归一化后,即( ilde{z}^{[2]}=γ^{[2]}z_{norm}^{[2]}+β^{[2]})可以将第二层数据限制为均值为(β^{[2]}),方差为(γ^{[2]})的分布,注意这两个参数并不需要人为设置,它会自动学习的。所以即使输入数据千变万化,但是经过归一化后分布都是可以满足我们的需求的,更简单地说就是归一化数据可以减弱前层参数的作用与后层参数的作用之间的联系,它使得网络每层都可以自己学习。
- 原因二
batch norm奏效的另一个原因则是它具有正则化的效果。其与dropout有异曲同工之妙,我们知道dropout会随机的丢掉一些节点,即数据,这样使得模型训练不会过分依赖某一个节点或某一层数据。batch norm也是如此,通过归一化使得各层之间的依赖性降低,并且会给每层都加入一些噪声,从而达到正则化的目的。
七、 测试的Batch Norm
前面提到的batch norm都是基于训练集的,但是在测试集上,有时候可能我们的测试数据很少,例如只有1个,在这个时候进行归一化则显得没多大意义了。那么该怎么办呢?均值(μ)和方差(σ^2)该如何确定呢?
方法还是有的,而且已经在上面提到过了。
没错,真聪明!!!就是第三节所介绍的指数加权平均啦,原理是类似的。
假设一共有如下(x^{{1}},x^{{2}},……,x^{{5000}})的批量数据,每组mini-batch都得到了对应的均值(μ)(方差同理,不详细说明了),即(μ^{{1}},μ^{{2}},……,μ^{{5000}}),如果测试集数据很少,那么就可以使用指数加权平均的方法来得到测试集的均值和方差。
之后就根据指数加权平均计算得到的值来计算归一化后的输入值即可。
注意:测试集的均值和方差生成的方式不一定非得是上面提到的指数加权平均,也可以是简单粗暴的计算所有训练集的均值和方差,视频中吴大大说这也是可行的~
八、 Softmax回归
前面教程中提到的分类算法例子都是二分类问题,即是或不是。但是当我们要区分多种事物时该怎么办呢?这时就需要softmax算法登场了。
假设第(l)层有(z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]}),激活函数为(a^{[l]}=frac{e^{z^{[l]}}}{sum_{j=1}^{n_l}e^{z^{[l]}_j}})
该节视频中吴大大并没有很详细的介绍softmax的原理和公式推导,感兴趣的可以戳如下链接进行进一步了解:
九、 训练一个Softmax分类器
具体实践项目可参见softmax分类算法原理(用python实现)
十、 深度学习框架
介绍了很多深度学习框架,这里不再详述。感兴趣的伙伴们可以Google一下,或者某度一下~~~。
十一、 TensorFlow
演示了一下TensorFlow使用方法,这里不再详述,不过我推荐一个比较好的TensorFlow的练手项目: