《改善深层神经网络:超参数调试、正则化以及优化》笔记(1)

一、前言

本文主要分为 3 周分别了讲解其中视频讲到的难重点,第一周分为 2 个重要的部分:正则化和梯度检验。笔者将自己在学习过程中的不理解的地方记录下俩,希望能够帮助到各位读者,也希望文章有错漏的地方,还请各位读者海涵指正。

二、第一周——深度学习的使用方法

2.1 模型性能判断方法

还记得在西瓜书的第一章中,周志华老师就讲了可以使用测试集的性能来评估模型的预测性能,同时也说了模型的误差可以被分解为 偏差方差噪声这 3 个元素。
假设有训练集误差 E1 和 验证集E2,那么通常的判断方法有 2 个:

  • 高方差:E1低、E2高
  • 高偏差:E1高、E2更高
    PS:其实这里推荐大家去看吴恩达的机器学习公开课,那里对偏方差的讲解更好一点
    那么如何解决因为这 2 个结果带来的影响呢?
  • 偏差:查看训练集的性能,如果此时偏差高一般选择新的网络
  • 方差:查看验证集的性能,如果此时方差偏高可以通过增加训练数据或者正则化来降低

2.2 正则化

2.2.1 正则化基础

上面说到正则化可以降低方差,那么这一节来讲讲正则化。
我们一般会在损失函数中加入正则化项,一般的正则化项有 L1范数L2范数,其实分别对应的就是曼哈顿距离欧式距离,读者自行百度就明白这 2 个范数的计算方式和表达方式了
假设我们使用欧式距离来作为正则化,那么损失函数可以就是:
J(w,b)=\frac{1}m\sum_{i=1}^m{L(\hat{y},y)} + \frac{\lambda}{2m}||W||_2^2
其中,\lambda是正则化参数,||w||_2^2是矩阵 W 的L2范数,作者这里说不加上 b 的原因是因为 b 的影响很小,可加可不加。

在神经网络中的损失函数中通过包含了第 1 层的W^{[1]}到第 l 层的W^{[l]},参数b同理,因为损失函数是以矩阵为单位来计算的,那么如果正则化项使用矩阵来表示的话是如下所示:
\frac{\lambda}{2m}\sum_{1}^{L}|W^{[l]}|^2
其中|W^{[l]}|^2我们称为范数平方,被定义为矩阵中所有元素的平方和。
而矩阵W^{[l]}的维度通常是(n^{l}, n^{l-1}),这里对 n 定义不明的同学请看前面的文章,我们使用弗罗贝尼乌斯范数来称呼矩阵的范数平方,并用下标F著名,关于弗罗贝尼乌斯范数可在参数小节中查阅

如果我们使用的是L2范数正则化,那么我们可以推导出一个L2正则化后的梯度公式。
首先我们在不加正则化项前提下,计算出的对W^{[l]}导数成为dW^{[l]},那么增加了正则化项的导数我们表示为dW^{[l]}_L,那么有如下式子:
dW^{[l]}_L = dW^{[l]} + \frac{\lambda}{m}W^{[l]}\\ W^{[l]} = W^{[l]} - \alpha dW^{[l]}_L = W^{[l]} - \alpha (dW^{[l]} + \frac{\lambda}{m}W^{[l]})
最后有可得到
W^{[l]} = (1 - \frac{\alpha \lambda}{m})W^{[l]} - \alpha dW^{[l]}
从上式可以明显看得出,使用了正则化之后的梯度公式比原来多了系数(1 - \frac{\alpha \lambda}{m}),该系数小于 1,也就是先让矩阵W缩小在去减去梯度,所以L2正则化也叫权重衰减

这里我们知道了如何进行L2正则化,但是从代码上看是怎么进行的呢?因为我们推出的公式无法直接用于代码,下面举个例子说明
比如我们在要计算第 3 层dW_3,那么第三层的正则化项是a = \frac{\lambda}{m}W_3,那么在计算dW_3时我们就需要在等式后面加上a

我们一般在验证集调试超参\lambda

2.2.1 正则化原理

我们可以直观的理解,当\lambda设置得足够大的时候,可以将矩阵W 衰减到足够小,假设此时使用的是tanh激活函数,那么因为W矩阵很小,所以输出Z也很小。由tanh函数的性质可知,如果输入是数值在很小的时候,相当于线性函数。而此时 Z 很小,那么此时激活函数相当于线性函数,多个线性函数叠加还是线性函数,所以此时模型拟合接近线性函数。
当模型在过拟合和线性函数之间存在一个适当的矩阵W使之拟合程度最为适合,所以这就可以正则化其效果的原理

2.2.2 dropout随机失活

dropout是一种类似正则化的手段,但它并不是通过增加正则项,而是通过其他的方法来使模型达到正则化的效果。
为了说明其步骤,视频中以某个神经网络的第 3 层为例子。
在每一轮的前向计算中,我们对每一层的生成一个随机矩阵,第 3 层我们假设随机生成了一个矩阵

d3 = np.random.rand(a3.shape[0], a3.shape[1])

该矩阵是一个只有 0 和 1 的矩阵,其中矩阵元素为 1 的概率是0.8, 为 0 的概率是 0.2,为超参 keep-porb 控制,那么在这里 keep-porb 等于 0.8

通过 d3 * a3,我们可以消去一些神经网络节点的输出,从而使得网络更加精简,从结论上看,假设为 1 的概率是0.8,那么相乘只有 a3也是原来的0.8倍,即 d3 * a3 可以看做是 0.8a3,为了消除对下一层的影响,我们需要继续使用 a3 /= 0.8(这里是0.8是keep-porb )
下层是z4 = w4 * a3 + b4,为了不影响 z4的期望值,即不想影响该层次的梯度下降,所以需要还原a3的值,不要让第三层加入dropout后影响该层的梯度

那么问题来了,刚刚说的是前向传播如何使用dropout,那么在后向传播dropout又该如何处理,其实是一样,我们只需要使用在前向传播中生成的随机二值矩阵来乘dA即可,然后再让dA/keep-prob

笔者在做作业的过程中发现如果按照给的keep-prob训练出来的模型准确率只有70%多,但在调整keep-prob在0.5以下的时候真确率提高到了90%,这可谓让笔者体验到了调参的重要性

要注意的是。在测试时不使用dropout。因为我们不期望输出的结果是随机,如果输出结果不是随机的,那么就不会影响预测。我们在前面 a3 /= 0.8是确保在测试时不执行dropout也能让激活函数的期望输出在不会发生变化,这样就不用在测试阶段添加额外的参数,这段话是视频中给出的,但比较晦涩

这里笔者说一下自己的通俗理解:笔者参考中《理解dropout》的说法,理解的dropout是让模型在训练时摆脱各个神经元之间的依赖性,不让模型的某个神经元只在特定的特征下起作用,这样就可以让每一个神经元都能够在所有的特征下都能起作用。那么这样的话,我们如果训练时加入了dropout,则无法体现出dropout的结果,因为测试时输出的跟训练时输出的一样

2.2.3 其他正则化方法

2.2.3.1 数据扩增
1、将图片水平翻转并加入训练集
2、随意缩放和裁剪图像并加入训练集

2.2.3.2 提前停止
在验证集是画出损失函数的下降图形,横轴是迭代次数,纵轴是损失函数,对训练集和验证集都画出图像,通常验证集是先降后升,我们可以在降到最低点时停止训练,此时获得一组参数W。但提前停止有缺点就是无法进行正交化,正交化在后面会讲解到

2.3 归一化输入

我们先看看归一化输入的执行过程,我们知道执行过程后比较容易理解归一化的原理及作用

2.3.1 步骤

归一化输入的步骤有 2 个,设我们数据集如下


原始数据集
  1. 零均值化
    第一步是对数据集进行零均值化,设有参数
    u = \frac{1}{m}\sum^{m}_{i=1}x^{i}
    接着我们对每一个训练数据进行减去该参数,即
    x'^{i} = x^{i} - u
    其实就相当于移动数据集,使他们的均值为 0 ,也就是如下图

    零均值化

  2. 归一化方差
    第二部就是归一化方差,设有参数
    \sigma = \frac{1}{m}\sum^{m}_{i=1}(x'^i)^2
    我们上面已经完成了零均值化,那么可以得到如下
    \sigma = \frac{1}{m}\sum^{m}_{i=1}(x^{i} - u)^2
    从上式可知,\sigma是方差,然后我们让每一个数据都除以\sigma,得到:
    x''^i = \frac{x'^i}{\sigma}
    需要注意,如果用x''^i来调整训练数据,那么用相同的 μ 和 σ^2来归一化测试集。当然归一化测试集使用的参数u\sigma都是从训练集得来的

2.3.2 原理

在不归一化数据的情况下,如果特征x_1的范围是在[0, 1],而特征x_2在[0, 1000]。那么训练出来的w_1w_2的数量级就会相差非常远,从而看起来是类似的一个图形,图中的b和w应该分别是w_2w_1

未归一化

这样的话,如果我们学习率确定得不对,对模型的训练完全没有好处,比如有可能引起振荡之类的情况。
如果我们归一化数据集后可以得到如下的图像
归一化

无论在哪个点,只要我们设置的学习率不太奇怪,我们总能够找到最优点

2.4 梯度

这一节将的是梯度,梯度如果在训练不好的情况下虎发生梯度消失和梯度爆炸,如果不理解这 2 个概念可以参考链接《梯度消失和梯度爆炸》
这里简单说下引起梯度爆炸的 2 个原因

2.4.1 解决方法

初始化权值过大容易引起梯度爆炸,过小会引起梯度消失。
一般的,我们有公式如下:
z = w_1x_1 + w_2x_2 + w_3x_3 + ... + w_nx_n
当n越多时,也就是特征越多时,希望w越小
可以这样初始化,第 i 层一般有 n^{i-1} 个输入,我们可以用这样来初始化 W矩阵

WL = np.random.randn(shape) * \sqrt {\frac{1}{n^{i-1}}}

不同的激活函数有不同的初始化方法,对于tanh就有其他初始化公式 ,比如Xavier初始化

如果是ReLu,设置为 \sqrt {\frac{2}{n^{i-1}}} 效果更好。此时也叫HE初始化

这2个初始化的作用十分明显,笔者目前上了尚未理解,后面理解了再来讲述

我们这里的随机分布一般使用的是高斯分布

当然了,

2.4.2 梯度检验

梯度检验是为了确保后向传播的计算是正确的,保证我们的参数能够完成优化 。
在讲梯度检验之前,先看看导数的单边公差跟双边公差

  1. 单边公差,公式如下:
    f'(x) = \lim_{ \Delta x\to\ 0} \frac{f(x + \Delta x) - f(x)}{\Delta x}
  2. 双边公差,公式如下:
    f'(x) = \lim_{ \Delta x\to\ 0} \frac{f(x+\Delta x) - f(x-\Delta x)}{2\Delta x}

一般双边公差比单边公差更加接近梯度,在梯度检验时我们使用双边公差

进行梯度检验时,我们需要将矩阵W^{[1]}b^{[1]}....W^{[l]}b^{[l]} 转换为向量\theta(视频中没有说到 b矩阵也需要转换,但这里必须的理解是需要转换b矩阵的)

那么损失函数将变成
J(W, b) \Rightarrow J(\theta)
在运算完J(W, b)后我们得到dW^{[1]}db^{[1]}...dW^{[l]}db^{[l]},同样地我们需要将这些都转换为与\theta同维度的向量d\theta,因为dWW的维度是一样的,b矩阵同理。

展开可得:
J(\theta) = J(\theta _1, \theta _2, \theta _3,...)

视频中没有说明如何转换,也没说明J(\theta)的具体公式是什么。举个例子说明一下笔者的理解:即W _1b_1一起转换成\theta _1,其余同理

那么对于每一个\theta _i,我们去计算其双边公差:
d\theta_{approx}[i] = \frac{J(\theta _1,\theta _2,...\theta _i+\varepsilon,...) - J(\theta _1,\theta _2,...\theta _i,...)}{2\varepsilon}

所以计算出来的d\theta_{approx}是一个向量。从前面我们已经转换出了d\theta,那么我们可以用L2范数的计算方式计算
a = \frac{||d\theta _{approx} - d\theta||_2}{||d\theta _{approx}||_2+||d\theta||_2}
加入a的值小于或等于10^{-7},那么说明梯度是正确的,加入大于这个数,那么我们应该注意梯度是否有问题,当然这里的10^{-7}笔者理解是一个经验数值,大家可以按照各自的情况进行判断

使用梯度检验时有一些注意事项 :

  • 训练时不要使用梯度检验,它只用于调试
  • 如果算法的梯度检验失败,检查所有项 ,如果 2 个向量之间值相差太大,要查看哪个 i 值相差最大
  • 如果在梯度检验的过程中使用正则化,需要将正则项加入梯度检验中
  • 梯度检验和dropout不能同时使用,因为dropuout会使代价函数很难计算,此时我们可以先将Keep-prob设置为1
  • 在随机初始化进行梯度检验,再训练网络

2.4.3 转换方法

我们上面说过,需要将参数矩阵W和b转换为一个一维向量,但视频中没有提高如何转换吗,这里笔者从作业中看到转换的代码,如下

def dictionary_to_vector(parameters):
    """
    Roll all our parameters dictionary into a single vector satisfying our specific required shape.
    """
    keys = []
    count = 0
    for key in ["W1", "b1", "W2", "b2", "W3", "b3"]:
        
        # flatten parameter
        new_vector = np.reshape(parameters[key], (-1,1))
        keys = keys + [key]*new_vector.shape[0]
        
        if count == 0:
            theta = new_vector
        else:
            theta = np.concatenate((theta, new_vector), axis=0)
        count = count + 1

    return theta, keys

可以很明显地看到,只是简单地讲参数展开为一维数据然后拼接起来

2.4.4 第一周作业注意事项

  1. 关于错误
    因为库不兼容的原因,这里的作业画图时会出现错误

c of shape (1, 211) not acceptable as a color sequence for x with size 211, y with size 211

解决方法参考链接《课后作业错误解决》

  1. 二值化矩阵
    在dropout阶段,我们需要生成二值矩阵,可以使用下面的语句来实现,这里的大概意思就是D1中的元素如果小于keep_prob的话为 0 ,否则为 1
np.where(D1 < keep_prob, 0, 1) 
  1. relu导数
    在这一周的课后作业中,给的代码使用了下面的语句来作为relu的导数
dZ2 = np.multiply(dA2, np.int64(A2 > 0))

其中 np.int64(A2 > 0) 应该是生成一个A2同纬度的矩阵,但是这个矩阵是A2中大于 0 的书保持不变,其余的数为 0

参考

弗罗贝尼乌斯范数:https://blog.csdn.net/david_jett/article/details/77040087
理解dropout:http://www.pianshen.com/article/4175293217/
梯度消失和梯度爆炸:https://www.cnblogs.com/XDU-Lakers/p/10553239.html
课后作业错误解决:https://www.cnblogs.com/buchiyudemao/p/9028704.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343