吴恩达深度学习deeplearning.ai学习笔记(一)2.7 2.9 2.10

2.7 计算图

一个神经网络的计算都是按前向和反向传播过程实现的。首先前向传播计算出神经网络的输出,再进行反向传播用于计算对应的导数,这些导数可以用于更新参数w,b

实际上,w:=w- \alpha dw在数学上是不太规范的,为了进一步说明,用问答来做思考:

J(w,b)wb的函数吗?

不是呀。w可是一个n_x维的列向量,什么时候见过有函数以列向量作为变量的;

所以一般是记w为:

w=\begin{bmatrix} w_1\\ w_2\\ w_3\\ \cdots\\ w_{n_x} \end{bmatrix}

然后说,J(w,b)w_1,w_2,w_3,\cdots,w_{n_x},b的函数,真正有数学意义的是以下等式:

w_1:=w_1-\alpha dw_1

w_2:=w_2-\alpha dw_2

w_3:=w_3-\alpha dw_3

\cdots

w_{n_x}:=w_{n_x}-\alpha dw_{n_x}

其中,dw_1=\frac{\partial}{\partial w_1}J(w,b)dw_2=\frac{\partial}{\partial w_2}J(w,b)\cdots

而编程时,仍然可以编为w:=w-\alpha dw这是因为能自动执行多行对应计算(向量化)

w=\begin{bmatrix} w_1\\ w_2\\ w_3\\ \cdots\\ w_{n_x} \end{bmatrix} := \begin{bmatrix} w_1-\alpha dw_1\\ w_2-\alpha dw_2\\ w_3-\alpha dw_3\\ \cdots\\ w_{n_x}-\alpha dw_{n_x} \end{bmatrix}=\begin{bmatrix} w_1\\ w_2\\ w_3\\ \cdots\\ w_{n_x} \end{bmatrix}-\alpha \begin{bmatrix} dw_1\\ dw_2\\ dw_3\\ \cdots\\ dw_{n_x} \end{bmatrix}

将最后一项记为:

dw=\begin{bmatrix} dw_1\\ dw_2\\ dw_3\\ \cdots\\ dw_{n_x} \end{bmatrix}

w:=w- \alpha dw,证毕;效果就是一行代码执行了n_x个式子;

2.9 logistic回归中的梯度下降法(单样本)

现在引入符号规定:

\hat{y}=a=\sigma(z)

因为只考虑单样本,所以不必加上标(i),并且为了简化例子,假设x是二维的,w也是二维的,即

x=\begin{bmatrix} x_1\\ x_2 \end{bmatrix},w=\begin{bmatrix} w_1\\ w_2 \end{bmatrix}

现在要计算所有导数,根据计算图可以知道要求da,dz,dw_1,dw_2,db注意,一般不对输入特征求偏导,因为在监督学习当中,将输入特征x_1,x_2,\cdots,x_{n_x}视作已知不变量;

L(a,y)=-[ylna+(1-y)ln(1-a)]

da=\frac{\partial}{\partial a}L(a,y)=-\frac{y}{a}-\frac{1-y}{1-a}\cdot(-1)=-\frac{y}{a}+\frac{1-y}{1-a}

dz=\frac{\partial}{\partial z}L(a,y)=\frac{\partial L(a,y)}{\partial a}\cdot\frac{\mathrm{d} a}{\mathrm{d} z}=[-\frac{y}{a}+\frac{1-y}{1-a}]\cdot\frac{\mathrm{d} a}{\mathrm{d} z}

\because a=\sigma(z)=\frac{1}{1+e^{-z}}

\therefore \frac{\mathrm{d} a}{\mathrm{d} z}=\frac{e^{-z}}{(1+e^{-z})^2}=\frac{\frac{1}{a}-1}{(\frac{1}{a})^2}=a(1-a)

\therefore dz=[-\frac{y}{a}+\frac{1-y}{1-a}]\cdot\frac{\mathrm{d} a }{\mathrm{d} z}=[-\frac{y}{a}+\frac{1-y}{1-a}]\cdot a(1-a)=a-y

dw_1=\frac{\partial L(a,y)}{\partial w_1}=\frac{\partial L(a,y)}{\partial z}\cdot\frac{\partial z}{\partial w_1}=dz\cdot\frac{\partial z}{\partial w_1}

\because z=w^Tx+b=w_1x_1+w_2x_2+b

\therefore \frac{\partial z}{\partial w_1}=x_1

\therefore dw_1=dz\cdot\frac{\partial z}{\partial w_1}=x_1dz

dw_2=x_2dz

db=dz

把计算的导数dw_1=x_1dzdw_2=x_2dzdb=dz应用到w_1:=w_1-\alpha dw_1w_2:=w_2-\alpha dw_2b:=b-\alpha db当中就可以了;在后面,会看到计算机是如何实现这一过程的,剧透一下就是前向传播中会储存z^{[l]}并在后向传播中用到,后向传播会逐层传播da并输出导数dz,dw_1,dw_2,db等,最后执行梯度下降;

值得注意的是即使扩展到多维,也能够将以上式子简写为两行代码:

w:=w-\alpha dw

dw=xdz

前者已经证明过,后者的证明:

dw=\begin{bmatrix} dw_1\\ dw_2\\ dw_3\\ \cdots\\ dw_{n_x} \end{bmatrix}=\begin{bmatrix} x_1dz\\ x_2dz\\ x_3dz\\ \cdots\\ x_{n_x}dz \end{bmatrix}=\begin{bmatrix} x_1\\ x_2\\ x_3\\ \cdots\\ x_{n_x} \end{bmatrix}dz=xdz

注意,这里a,z都是实数,一般daa保持一致的矩阵形式,dzz保持一致的矩阵形式,所以da,dz都是实数。

2.10 m个样本的梯度下降

为了不失一般性、清楚地加以证明,先定义如下: 

输入特征是多维的,维数记为n_x,这意味着所有样本的输入即x^{(1)},x^{(2)},x^{(3)},\cdots,x^{(m)}都是n_x维列向量,同理w也是n_x维列向量;并记:

x^{(1)}=\begin{bmatrix} x_1^{(1)}\\ x_2^{(1)}\\ x_3^{(1)}\\ \cdots\\ x_{n_x}^{(1)} \end{bmatrix},x^{(2)}=\begin{bmatrix} x_1^{(2)}\\ x_2^{(2)}\\ x_3^{(2)}\\ \cdots\\ x_{n_x}^{(2)} \end{bmatrix},x^{(3)}=\begin{bmatrix} x_1^{(3)}\\ x_2^{(3)}\\ x_3^{(3)}\\ \cdots\\ x_{n_x}^{(3)} \end{bmatrix},\cdots,x^{(m)}=\begin{bmatrix} x_1^{(m)}\\ x_2^{(m)}\\ x_3^{(m)}\\ \cdots\\ x_{n_x}^{(m)} \end{bmatrix}

w=\begin{bmatrix} w_1\\ w_2\\ w_3\\ \cdots\\ w_{n_x} \end{bmatrix}

难点在于研究对象由L(a,y)变成了J(w,b)

J(w,b)=\frac{1}{m}\sum_{i=1}^{m}L(a^{(i)},y^{(i)})

我们使用梯度下降法的式子还是不变:w_1:=w_1-\alpha dw_1w_2:=w_2-\alpha dw_2,……,w_{n_x}:=w_{n_x}-\alpha dw_{n_x}b:=b-db,所求的导数还是dw_1,dw_2,\cdots,dw_{n_x},db,但是含义已经发生了改变:

dw_1=\frac{\partial J(w,b)}{\partial w_1}=\frac{\partial }{\partial w_1}[\frac{1}{m}\sum_{i=1}^{m}L(a^{(i)},y^{(i)})]=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial w_1}L(a^{(i)},y^{(i)})

dw_2=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial w_2}L(a^{(i)},y^{(i)})

\cdots

dw_{n_x}=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial w_{n_x}}L(a^{(i)},y^{(i)})

db=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial b}L(a^{(i)},y^{(i)})

也就是说以dw_1为例,不过是一个样本均值,真正要求的是每个样本中损失函数对w_1的偏导数;

那么,在样本1中,\frac{\partial }{\partial w_1}L(a^{(1)},y^{(1)})是什么呢?

这就是我们在2.9对单样本已经证明过的公式,当时写的是这样的:

dw_1=\frac{\partial L(a,y)}{\partial w_1}=x_1dz

现在给它加上一个上标(1),表示这是来自样本1的数据:

dw_1^{(1)}=\frac{\partial L(a^{(1)},y^{(1)})}{\partial w_1}=x_1^{(1)}dz^{(1)}

这一步是最难理解的,多想一下,然后注意每一个都是带标签的项,除了对w_1求导;

同理,可以得到样本2,样本3,……,样本m的式子:

dw_1^{(2)}=\frac{\partial L(a^{(2)},y^{(2)})}{\partial w_1}=x_1^{(2)}dz^{(2)}

dw_1^{(3)}=\frac{\partial L(a^{(3)},y^{(3)})}{\partial w_1}=x_1^{(3)}dz^{(3)}

\cdots

dw_1^{(m)}=\frac{\partial L(a^{(m)},y^{(m)})}{\partial w_1}=x_1^{(m)}dz^{(m)}

将这m个式子总结成一般化公式:

dw_1^{(i)}=\frac{\partial L(a^{(i)},y^{(i)})}{\partial w_1}=x_1^{(i)}dz^{(i)},i=1,2,3,\cdots,m

\therefore dw_1=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial w_1}L(a^{(i)},y^{(i)})=\frac{1}{m}\sum_{i=1}^{m}dw_1^{(i)}=\frac{1}{m}\sum_{i=1}^{m}x_1^{(i)}dz^{(i)}

同理,对w_2,w_3,\cdots,w_{n_x}的导数也是如此推导,简洁起见在dw_1公式上改一下下标就可以了:

dw_2=\frac{1}{m}\sum_{i=1}^{m}x_2^{(i)}dz^{(i)}

dw_3=\frac{1}{m}\sum_{i=1}^{m}x_3^{(i)}dz^{(i)}

\cdots

dw_{n_x}=\frac{1}{m}\sum_{i=1}^{m}x_{n_x}^{(i)}dz^{(i)}

而对于b的导数推导简直一模一样,甚至更简单:

\because db^{(i)}=\frac{\partial L(a^{(i)},y^{(i)})}{\partial b}=dz^{(i)},i=1,2,3,\cdots,m

\therefore db=\frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial b}L(a^{(i)},y^{(i)})=\frac{1}{m}\sum_{i=1}^{m}db^{(i)}=\frac{1}{m}\sum_{i=1}^{m}dz^{(i)}

到此,大致总结一下:

dw_1=\frac{1}{m}\sum_{i=1}^{m}x_1^{(i)}dz^{(i)}

dw_2=\frac{1}{m}\sum_{i=1}^{m}x_2^{(i)}dz^{(i)}

dw_3=\frac{1}{m}\sum_{i=1}^{m}x_3^{(i)}dz^{(i)}

\cdots

dw_{n_x}=\frac{1}{m}\sum_{i=1}^{m}x_{n_x}^{(i)}dz^{(i)}

db=\frac{1}{m}\sum_{i=1}^{m}dz^{(i)}

那么,式子中未知的只有dz^{(i)}了,如何求呢?

其实在2.9节也早就求过了,当时是单样本下写成这样的:

dz=a-y

a=\sigma(z)

z=w^Tx+b

现在只不过要带上标了,以第i个样本为例,扩展到i=1,2,3,\cdots,m所有样本中去:

dz^{(i)}=a^{(i)}-y^{(i)}

a^{(i)}=\sigma(z^{(i)})

z^{(i)}=w^Tx^{(i)}+b

如何进行编程?

首先先从最容易的for loop开始构思,后续再用向量化把可以去掉的for loop去掉;

一开始,要对dw_1,dw_2,dw_3,\cdots,dw_{n_x}db进行初始化,可以初始化为0;

然后我们先从dw_1=\frac{1}{m}\sum_{i=1}^{m}x_1^{(i)}dz^{(i)}这个式子出发,可以用for loop把x_1^{(1)}dz^{(1)},x_1^{(2)}dz^{(2)},\cdots,x_1^{(m)}dz^{(m)}全部加到dw_1这个变量里,加完最后再将dw_1除以m即可;然后如法炮制到dw_2,dw_3,\cdots,dw_{n_x}db中;

最后就可以进行一次梯度下降了;如果要多次梯度下降,只能在所有的代码最外围再添加一个for loop,而且这个for loop是无法省略的;

版本1:

dw_1=0;dw_2=0;\cdots;dw_{n_x}=0;db=0

For\ i=1\ to\ m:

         z^{(i)}=w^Tx^{(i)}+b

         a^{(i)}=\sigma(z^{(i)})

         dz^{(i)}=a^{(i)}-y^{(i)}

         dw_1+=x_1^{(i)}dz^{(i)}

         dw_2+=x_2^{(i)}dz^{(i)}

         dw_3+=x_3^{(i)}dz^{(i)}

         \cdots

         dw_{n_x}+=x_{n_x}^{(i)}dz^{(i)}

         db+=dz^{(i)}

dw_1/=m;dw_2/=m;dw_3/=m;\cdots;dw_{n_x}/=m;db/=m

w_1:=w_1-\alpha dw_1;w_2:=w_2-\alpha dw_2;\cdots;w_{n_x}:=w_{n_x}-\alpha dw_{n_x}

b:=b-\alpha db

对中间的dw_1+=x_1^{(i)}dz^{(i)}等用for loop循环代替,并做好各处标记方便向量化,有:

版本2:

dw_1=0;dw_2=0;\cdots;dw_{n_x}=0;db=0\rightarrow (1)

For\ i=1\ to\ m:

         z^{(i)}=w^Tx^{(i)}+b

         a^{(i)}=\sigma(z^{(i)})

         dz^{(i)}=a^{(i)}-y^{(i)}

         for\ j=1\ to\ n_x:

                 dw_j+=x_j^{(i)}dz^{(i)}\rightarrow (2)

         db+=dz^{(i)}

dw_1/=m;dw_2/=m;dw_3/=m;\cdots;dw_{n_x}/=m;db/=m\rightarrow (3)

w_1:=w_1-\alpha dw_1;w_2:=w_2-\alpha dw_2;\cdots;w_{n_x}:=w_{n_x}-\alpha dw_{n_x}\rightarrow (4)

b:=b-\alpha db

深度学习中不用显式for loop是非常重要的,会极快地提升算法的速度。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值