深度学习入门(二)-反向传递

机器学习是数据套公式,但是深度学习不是这样的,虽然也是"节点映射成为节点"的方法最后得到结果,但是训练方法却很不一样,直到目前我依旧有一些不明白的地方,所以准备整理看一看

链式法则

自动求导要用到链式法则,这个是高数的内容,大致是:
∂ y ∂ x = ∂ y ∂ u n ∂ u n ∂ u n − 1 . . . ∂ u 1 ∂ x \frac{\partial y}{\partial x} =\frac{\partial y}{\partial u_n}\frac{\partial u_n}{\partial u_{n-1}}...\frac{\partial u_1}{\partial x} xy=unyun1un...xu1
如果x,y是向量或者矩阵,那么拆开也是,不过公式上差不多都是这样
首先给一个公式,举个例子:
z = ( < x , w > − y ) 2 z=(<x,w>-y)^2 z=(<x,w>y)2
这里 < x , w > <x,w> <x,w>是向量乘法(其实例子里用不用这样都没关系)
然后:
a = < x , w > ⇒ z = ( a − y ) 2 a=<x,w>\Rightarrow z=(a-y)^2 a=<x,w>z=(ay)2
b = a − y ⇒ z = b 2 b=a-y\Rightarrow z=b^2 b=ayz=b2
那么如果对 w w w求导:
∂ z ∂ w \frac{\partial z}{\partial w} wz
= ∂ z ∂ b ∂ b ∂ a ∂ a ∂ w =\frac{\partial z}{\partial b}\frac{\partial b}{\partial a}\frac{\partial a}{\partial w} =bzabwa
代入:
= ∂ b 2 ∂ b ∂ ( a − y ) ∂ a ∂ < x , w > ∂ w =\frac{\partial b^2}{\partial b}\frac{\partial {(a-y)}}{\partial a}\frac{\partial {<x,w>}}{\partial w} =bb2a(ay)w<x,w>
= 2 b ⋅ 1 ⋅ x T =2b\cdot 1\cdot x^T =2b1xT
= 2 ( < x , w > − y ) x T =2(<x,w>-y)x^T =2(<x,w>y)xT
所以不管原式如何,用链式法则都可以求个导(李沐老师在后面的章节表示,基本不存在不可导的函数,最多是无法处处可导)
(如果有很多项相乘,那么把不准备求的几项合为一项就行了,毕竟是服务于深度学习的,不会太复杂)
例子里用不用 < x , w > <x,w> <x,w>都一样,但是后面学习神经网络的时候都会尽可能变成矩阵相乘的情况,也就是 < x , w > <x,w> <x,w>,所以李沐老师讲的时候都是用这样的例子说明的

计算图

计算图形状有点像一棵树,不过根节点是函数的"结果",子节点则是输入
示例:
在这里插入图片描述
理论上一个函数的公式都可以画成计算图,而反向传递就是在计算图上进行的操作

梯度下降

机器学习中常常使用梯度下降法来求损失函数的最小值,当损失函数最小时的参数就是模型效率最高时的函数(我之前文章提到过,不理解可以自行百度)
大致公式是:
θ = θ − η ∇ J ( θ ) \theta = \theta - \eta \nabla J(\theta) θ=θηJ(θ)
然后用数学方法求出具体公式,进行梯度下降

反向传递

不同于机器学习梯度下降是"提前计算出公式然后套用公式",深度学习的梯度下降是直接算,因为不管怎么求导,最后也是要算成是数值的
具体如何操作呢?首先按照计算图算出函数结果,同时保留每一步结果,然后反向传播并求导,算出 ∇ J ( θ ) \nabla J(\theta) J(θ)
用例子进行说明(我也不记得在哪看到的例子了):
方程:
y = 1 1 + e − ( ω 0 x 0 + ω 1 x 1 + ω 2 ) y=\frac{1}{1+e^{-(\omega_0x_0+\omega_1x_1+\omega_2)}} y=1+e(ω0x0+ω1x1+ω2)1
参数为 ω 0 = 2 , ω 1 = − 3 , ω 2 = − 3 , x 0 = − 1 , x 1 = − 2 , y = 1.73 \omega_0=2,\omega_1=-3,\omega_2=-3,x_0=-1,x_1=-2,y=1.73 ω0=2,ω1=3,ω2=3,x0=1,x1=2,y=1.73
首先肯定不是给一个代入之后完全相等的等式给你,因为有噪声,我们的任务是求出这个等式
那么如何用反向传递对其进行调整呢?
先画出计算图:
在这里插入图片描述
然后进行顺序计算:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
可以看出来这里算出来的是1.73
但是我们的数据是0.73
这就产生了一个数值为1的差值
然后就是反向传播了:
将1返回去
在这里插入图片描述

因为我们求的是导数,所以对 1 x \frac{1}{x} x1求导,注意,这里求导时的x是1.37,然后乘以我们反向传播过来的数值:
在这里插入图片描述
得到-0.53,再将-0.53传向上一个节点,对(x+1)进行求导,此处x是0.37
在这里插入图片描述
继续直到参数段:
在这里插入图片描述
注意在这里,我们把上面一个看成 z z z,下面是 ω 2 \omega_2 ω2,这里就是 ω 2 + z \omega_2+z ω2+z无论是对 z z z求导还是 ω 2 \omega_2 ω2求导,结果都是1,所以返回去的值不变都是0.2:
在这里插入图片描述
同理:
在这里插入图片描述
再到乘法了,对 x , ω x,\omega x,ω求导时,另一个数视作常数,故求导后的结果不一样
在这里插入图片描述
最终得到的数值就是要对参数进行调整的值,也就是梯度下降法的"下降"

神经网络中…

看得出来,没有正向传播,反向传播无法运作
对神经网络进行训练时,每次训练都要进行backwards,就是为了保存正向传播时的数据,同时清零上一次反向传播储存的参数,还要更新新的参数
而进行预测时则要设定为预测模式,减少内存占用
(以下是每次训练)

# net是已经定义好的神经网络
# 设为训练模式
net.train() 
# 在每一个epoch中
for X,y in train_iter:
	# 只用直到X是训练数据,y是训练数据对应的结果即可,如何合成一起并不重要
	y_hat = net(X)
	# 对训练数据进行预测
	l = loss(y_hat, y)
	# l是损失函数(通常另外定义),计算预测试和实际值的损失
	trainer.zero_grad()
	# 梯度归0
	l.backward()
	# 对损失函数求导
	trainer.step()
	# 参数自更新

而单纯的看预测结果的模式(这样不会保留梯度,也就不会存那么复杂一个计算图了)

net.eval()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值