吴恩达深度学习deeplearning.ai学习笔记(二)2.1 2.2

2.1 Mini-batch梯度下降法

下面将学习一些优化算法能让你的神经网络运行得更快;机器学习的应用是一个高度依赖经验的过程,伴随大量迭代过程,你要训练诸多模型才能找到合适的那一个;所以,优化算法可以帮你快速地训练模型;其中一个难点是深度学习没有在大数据领域发挥最大的效果,我们可以利用一个巨大的数据集来训练神经网络,而在巨大的数据集基础上进行训练速度很慢,所以使用快速的优化算法能大大提高团队效率;

之前所学的向量化能够让你有效地对所有m个样本进行计算,允许你训练整个训练集而无需某个明确的公式,这就是为何要构造巨大的矩阵:

X=\begin{bmatrix} x^{(1)}&x^{(2)} &\cdots &x^{(m)} \end{bmatrix}

Y=\begin{bmatrix} y^{(1)}&y^{(2)} &\cdots &y^{(m)} \end{bmatrix}

问题在于,当m很大时,比如mm=5,000,000时,这样进行向量化处理速度依旧很慢,因为在对整个训练集进行梯度下降时,你要做的是你必须处理整个训练集,然后才能进行一次梯度下降法,然后再重新处理500万个训练样本,再进行下一次梯度下降……

你完全可以得到一个更快的算法,如果你在处理完整个500万样本的训练集之前,先让梯度下降法处理其中的一部分,你的算法速度会更快;更具体地说,你可以将训练集分割为小一点的一些子训练集,这些子集被取名为mini-batch,假设每一个子集中都是只有1000个样本,那么就是将x^{(1)},x^{(2)},\cdots,x^{(1000)}抽出来当作第一个样本,将x^{(1001)},x^{(1002)},\cdots,x^{(2000)}抽出来当作第二个样本,……并将它记为带花括号的形式:

X^{\{1\}}=\begin{bmatrix} x^{(1)} &x^{(2)} &\cdots &x^{(1000)} \end{bmatrix}

X^{\{2\}}=\begin{bmatrix} x^{(1001)} &x^{(1002)} &\cdots &x^{(2000)} \end{bmatrix}

\cdots

X^{\{5000\}}=\begin{bmatrix} x^{(4,999,000)} &x^{(4,999,001)} &\cdots &x^{(5,000,000)} \end{bmatrix}

因此,当总共的样本数m=500万,而每个子集的样本数是1000,意味着将会有5000个mini-batch,相应地,对Y也进行拆分:

Y^{\{1\}}=\begin{bmatrix} y^{(1)} &y^{(2)} &\cdots &y^{(1000)} \end{bmatrix}

Y^{\{2\}}=\begin{bmatrix} y^{(1001)} &y^{(1002)} &\cdots &y^{(2000)} \end{bmatrix}

\cdots

Y^{\{5000\}}=\begin{bmatrix} y^{(4,999,000)} &y^{(4,999,001)} &\cdots &y^{(5,000,000)} \end{bmatrix}

一般地,我们将mini-batch用输入和输出对(X^{\{t\}},Y^{\{t\}})来表示,并且总结一下符号规定:

x^{(i)},y^{(i)}即圆括号表示第i个样本的输入、输出;

z^{[l]}即方括号表示神经网络第l层的量;

X^{\{t\}},Y^{\{t\}}即花括号表示第t个mini-batch;

并且上例中,X^{\{t\}}的维度是(n_x,1000)Y^{\{t\}}的维度是(1,1000)

以前讲的梯度下降法向量化后叫Batch\ gradient\ descent,即同时处理整个训练集;

mini\ batch\ gradient\ descent指的是每次同时处理的是单个的X^{\{t\}},Y^{\{t\}}

mini-batch gradient descent的原理:

repeat\{​

              for\ t=1\ to\ 5000:

                     \{Z^{[1]}=w^{[1]}X^{\{t\}}+b^{[1]}

                      A^{[1]}=g^{[1]}(Z^{[1]})

                      Z^{[2]}=w^{[2]}A^{​{[1]}{\{t\}}}+b^{[2]}

                      A^{[2]}=g^{[2]}(Z^{[2]})

                      \cdots

                      Z^{[L]}=w^{[L]}A^{​{[L-1]}{\{t\}}}+b^{[L]}

                      A^{[L]}=g^{[L]}(Z^{[L]})=\hat{y}^{(i)}

                      J^{\{t\}}=\frac{1}{1000}\sum_{i=1}^{1000}(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2\cdot 1000}\sum_{l=1}^{L}{​{\parallel w^{[l]}\parallel}_F}^2

                      Back\ prop\ from\ l=L\ to\ l=1:

                                  dZ^{[l]}=dA^{[l]}\ast {g^{[1]}}'(Z^{[l]})=w^{[l+1]T}dZ^{[l+1]}\ast {g^{[l]}}'(Z^{[l]})

                                  dw^{[l]}=\frac{1}{m}dZ^{[l]}A^{[l-1]T}

                                  dA^{[l-1]}=w^{[l]T}dZ^{[l]}

                                  w^{[l]}:=w^{[l]}-\alpha dw^{[l]}

                                  b^{[l]}:=b^{[l]}-\alpha db^{[l]}

                     \}

              \}

for循环中基本要做的是:对X^{\{t\}},Y^{\{t\}}执行一步梯度下降法,这很像之前向量化处理m个样本的公式,只是m=1000而已,也就是说for循环里执行的本质仍然是向量化,这些代码执行一次就处理了1000个样本;

首先,对X^{\{t\}}进行前向传播,即:

Z^{[1]}=w^{[1]}X^{\{t\}}+b^{[1]}

A^{[1]}=g^{[1]}(Z^{[1]})

Z^{[2]}=w^{[2]}A^{​{[1]}{\{t\}}}+b^{[2]}

A^{[2]}=g^{[2]}(Z^{[2]})

\cdots

Z^{[L]}=w^{[L]}A^{​{[L-1]}{\{t\}}}+b^{[L]}

A^{[L]}=g^{[L]}(Z^{[L]})=\hat{y}^{(i)}

接下来要计算成本函数:

J^{\{t\}}=\frac{1}{1000}\sum_{i=1}^{1000}(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2\cdot 1000}\sum_{l=1}^{L}{​{\parallel w^{[l]}\parallel}_F}^2

值得注意的是,这个式子里的\hat{y}^{(i)},y^{(i)}是来自mini-batchX^{\{t\}},Y^{\{t\}}的,并且i=1表示的是X^{\{t\}},Y^{\{t\}}中的第一个样本,比如,如果for loop运行到X^{\{3\}},Y^{\{3\}}了,那么求和公式中\hat{y}^{(1)},y^{(1)}实际是指所有样本中的\hat{y}^{(3001)},y^{(3001)},如果觉得这个表达并不严谨,那就改下上下标:

J^{\{t\}}=\frac{1}{1000}\sum_{i=1+1000(t-1)}^{1000t}(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2\cdot 1000}\sum_{l=1}^{L}{​{\parallel w^{[l]}\parallel}_F}^2

而这个式子后半项指的是正则项;所有上述在for loop中所做的正如之前对X,Y进行梯度下降一样,只是变成了对X^{\{t\}},Y^{\{t\}}进行梯度下降;

最后执行反向传播计算J^{\{t\}}的梯度,仍然用的是X^{\{t\}},Y^{\{t\}},更新权重参数:

对神经网络的第l层而言:

dZ^{[l]}=dA^{[l]}\ast {g^{[1]}}'(Z^{[l]})=w^{[l+1]T}dZ^{[l+1]}\ast {g^{[l]}}'(Z^{[l]})

dw^{[l]}=\frac{1}{m}dZ^{[l]}A^{[l-1]T}

dA^{[l-1]}=w^{[l]T}dZ^{[l]}

w^{[l]}:=w^{[l]}-\alpha dw^{[l]}

b^{[l]}:=b^{[l]}-\alpha db^{[l]}

然后要一层一层地传递将整个神经网络的参数都更新;

上述三步实现了对一个mini-batch的训练,也叫一代训练(One\ epoch)

然后接着对下一个mini-batch进行训练,……,直到对所有mini-batch都训练完成;

epoch这个词意味着:

遍历一次训练集,在batch中仅仅意味着你做了一次梯度下降,而在mini-batch中却做了5000次梯度下降;

而如果想要多次遍历训练集,应该在for loop的外面再加一个for loop循环;

2.2 理解mini-batch梯度下降法

Batch gradient descent中一次迭代就只做一次梯度下降,一次性遍历整个训练集,因此可以预期每次迭代成本函数都会下降;

但对于mini-batch gradient descent而言,如果你作出成本函数在整个过程中的图,则并不是每次迭代都是下降的,因为一次迭代,也就是一次梯度下降只是遍历了可能1000个样本,只是遍历了子集,只是针对X^{\{t\}},Y^{\{t\}}的处理,每次迭代都会使用不同的训练子集;

而遍历一遍完整的、全部的训练集,意味着已经做了可能5000次梯度下降,也就是5000次迭代,所以如果按进行梯度下降的次数和顺序作为横轴的正轴画图,画出J^{\{t\}},当然这不严谨,它只是代表成本函数和t即mini-batch有关,将是以下的图像:总体走向朝下,但是有很多的噪声;

噪声产生的原因是什么?

也许X^{\{1\}},Y^{\{1\}}是比较容易训练的mini-batch,所以成本函数的值会低一些,但也许由于偶然,X^{\{2\}},Y^{\{2\}}是比较难训练的mini-batch,或许里面有一些残缺样本或出错的标签,因此成本函数的值会高一些,总之,与计算J^{\{t\}}的时候使用的那个批次的X^{\{t\}},Y^{\{t\}}有关,才会让成本函数出现上下摆动类似噪声的样子;

一个重要的事情是你要定义mini-batch的大小mini-batch\ size

一个极端情况是mini-batch\ size=m,此时就只有一个子集,效果和batch gradient descent一样:

(X^{\{1\}},Y^{\{1\}})=(X,Y)

X=\begin{bmatrix} x^{(1)} &x^{(2)} &\cdots & x^{(m)} \end{bmatrix}

Y=\begin{bmatrix} y^{(1)} &y^{(2)} &\cdots & y^{(m)} \end{bmatrix}

另一个极端情况是mini-batch\ size=1,这时把它叫做“随机梯度下降”(Stochastic\ gradient\ descent),此时每一个样本都是一个独立的mini-batch:

(X^{\{1\}},Y^{\{1\}})=(x^{(1)},y^{(1)})

(X^{\{2\}},Y^{\{2\}})=(x^{(2)},y^{(2)})

\cdots

(X^{\{m\}},Y^{\{m\}})=(x^{(m)},y^{(m)})

这两个极端情况在优化成本函数的时候有何不同?

假设下图是你想要最小化的成本函数的轮廓(等高线图),最小值在中心处,batch gradient descent从某点处开始,相对的噪声低一些幅度也大一些,不断向最小值靠近,如蓝线所属;而stochastic gradient decent从某点开始,每次迭代只对一个样本进行梯度下降,大部分时候你朝着全局最小值前进,有时却会远离最小值,可能因为那个样本给你指的方向不对,所以会有很多噪声,如紫线所示;

从平均来看,随机梯度下降最终会靠近最小值,不过有时也会方向错误,且随机梯度下降法永远不会收敛,而是会一直在最小值附近波动,不会停留在最小值处或者某个固定的位置;

实际上选择的mini-batch size应该介于1和m之间,为什么?

因为如果使用mini-batch size=1即batch gradient descent,那么在处理训练样本数量特别大的情况时,会使单次迭代过程所花的时间过长,而如果训练样本数量并不是很大比如100或1000左右,那么使用batch gradient descent也是效果很好的;

如果使用mini-batch size即stochastic gradient descent,针对每一个样本都进行一次梯度下降,并选择较小的学习率可以减小噪声,但一个巨大的缺点就是失去了所有向量化带给你的加速运算的机会,一次迭代(一次梯度下降)只能处理一个样本,导致效率比较低;

所以实际中,选择不大不小的mini-batch size,能使训练达到最快;并且好处是:

(1)可以利用向量化进行加速;

(2)不需要等待整个训练集都被处理完就可以开始进行后续的梯度下降工作,前例中,每代训练集允许我们采取5000个梯度下降步骤,并且相比于随机梯度下降,它的噪声更小,更持续地往靠近最小值的方向前进,也不一定会在小范围内波动,可以通过减小学习率来解决波动问题使他收敛到最小值处,如绿线所示。

如何选择这个中间的mini-batch size呢?

(1)如果训练集较小,一般是m\leq 2000,采用batch gradient descent;

(2)如果训练集很大,要选用经典的值:64,128,256,512,1024(少用),这是因为计算机内存的布局和访问方式,所以将它设置为2的幂次,你的代码会运行得更快一些;

(3)确保mini-batch设置得能让你所有的X^{\{t\}},Y^{\{t\}}可以放进你的CPU/GPU当中,这当然也和你的配置以及一个训练样本的大小有关,但如果你设置的mini-batch超过了CPU/GPU的容量,不管怎么做结果都会很糟糕;

当然,mini-batch size也是一个超参数,可能要做一个快速搜索去确定哪一个值可以让成本函数下降得最快,尝试几个2的幂次看看能否找到合适的那个值;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值