一文看懂计算机神经网络与梯度下降

1. 计算机神经网络与神经元

要理解神经网络中的梯度下降算法,首先我们必须清楚神经元的定义。如下图所示,每一个神经元可以由关系式 y = f ( ∑ i = 1 n w i x i + b ) y = f(\sum_{i=1}^nw_ix_i + b) y=f(i=1nwixi+b)来描述,其中 X = [ x 1 , x 2 , . . . , x n ] X = [x_1,x_2,...,x_n] X=[x1,x2,...,xn]就是N维的输入信号, W = [ w 1 , w 2 , . . . , w n ] W =[w_1,w_2,...,w_n] W=[w1,w2,...,wn]是与输入向量一一对应的n维权重, b b b bias 偏斜, y y y对应该神经元的输出, f f f函数称为激励函数,例如sigmoid函数,softmax函数等等。

那么一个神经网络是如何进行学习的呢?以一个神经元为例,在一组输入信号 X X X经过该神经元后,我们得到了一个输出信号称之为 y e t o i l e y_{etoile} yetoile,而训练集中给出的实际输出例如为 y y y,那么显而易见地,想要提高正确率,即正确地学习对于一组输入应该获得的输出 y y y,一个神经元所做的计算,就是一个最优化(最小化)问题,通过改变权重 W W W来最小化损失(误差) l ( y , y e t o i l e ) l(y,y_{etoile}) l(y,yetoile)。当然,这个误差的定义可以根据问题的不同有所区别,例如简单的向量L1,L2距离,MSE均方误差。对于整个训练集而言,当然不止包含了一组输入输出。因此整体而言,误差Loss Function L ( W ) = 1 N ∑ t = 1 K l ( y t , y t e t o i l e ) L(W) = \frac{1} {N}\sum_{t=1}^{K}l(y_t,y_{t_{etoile}}) L(W)=N1t=1Kl(yt,ytetoile) 是所有K组训练数据误差的总和的平均数。

我们已经知道了,Loss Function损失函数与神经元的权重息息相关,神经元要做的计算,就是找到能最小化该损失函数的权重 W W W。优化的算法纷繁多样,使用的较为广泛的就是梯度下降 g r a d i e n t    d e s c e n t gradient\space\space descent gradient  descent 及其衍生算法SGD随机梯度下降,BGD批量梯度下降。

在这里插入图片描述

2. 梯度下降算法 g r a d i e n t    d e s c e n t gradient\space\space descent gradient  descent

梯度下降算法,一言以蔽之,就是沿着梯度下降的方向不断迭代,最终逼近函数最小值的优化方法。如下图所示,在最小化Loss Function损失函数的过程中,权重总是沿着损失函数梯度下降的方向变化,即 w i = w i − λ ∇ L ∣ w i w_i = w_i - \lambda\nabla L|_{w_i} wi=wiλLwi,其中 λ \lambda λ为学习率。当损失函数的梯度接近0时,可以终止迭代。大致理解了梯度下降算法的原理,接下我们看看在优化神经元的过程中,梯度下降算法是如何实现的。

在这里插入图片描述

3. backpropagation 反向传播算法

通过上一个部分,我们理解了使权重沿着Loss的梯度下降方向迭代,可以最终最小化损失函数。这个过程中,权重的更新 w i = w i − λ ∇ L ∣ w i w_i = w_i - \lambda\nabla L|_{w_i} wi=wiλLwi取决于损失函数的梯度。计算该梯度的最常用方法,就是反向传播算法。反向传播算法其实际原理类似于复合函数导数。我们通过链式法则,可以将所需求的梯度分割成子变量的梯度的乘积。
以单个神经元的神经网络的优化为例:
y e t o i l e = f ( ∑ i = 1 n w i x i + b ) y_{etoile} = f(\sum_{i=1}^nw_ix_i + b) yetoile=f(i=1nwixi+b)

e i = w i x i e_i = w_ix_i ei=wixi,

v = ∑ i e i + θ v=\sum_ie_i+ \theta v=iei+θ

默认使用sigmoid激励函数:

y e t o i l e = σ ( v )    y_{etoile} = \sigma(v)\space\space yetoile=σ(v)   经过激励函数后的输出

σ ( v ) = 1 1 + e − v    \sigma(v) = \frac{1}{1+e^{-v}}\space\space σ(v)=1+ev1   sigmoid函数

ϵ = y e t o i l e − y    \epsilon = y_{etoile} - y\space\space ϵ=yetoiley   y e t o i l e y_{etoile} yetoile与实际值 y y y的误差

L = ϵ 2 L = \epsilon^2 L=ϵ2

使用链式法则我们不难得到 :
∂ L ∂ w i = ∂ L ∂ e i ∂ e i ∂ w i    w h e r e   ∂ e i ∂ w i = x i \frac{\partial L}{\partial w_i} = \frac{\partial L}{\partial e_i}\frac{\partial e_i}{\partial w_i} \space\space where \space\frac{\partial e_i}{\partial w_i} = x_i wiL=eiLwiei  where wiei=xi

∂ L ∂ e i = ∂ L ∂ v ∂ v ∂ e i    w h e r e   ∂ v ∂ e i = 1 \frac{\partial L}{\partial e_i} = \frac{\partial L}{\partial v}\frac{\partial v}{\partial e_i} \space\space where \space\frac{\partial v}{\partial e_i} =1 eiL=vLeiv  where eiv=1

∂ L ∂ v = ∂ L ∂ y e t o i l e ∂ y e t o i l e ∂ v    w h e r e   ∂ y e t o i l e ∂ v = σ ′ ( v ) = e − v ( 1 + e − v ) 2 \frac{\partial L}{\partial v} = \frac{\partial L}{\partial y_{etoile}}\frac{\partial y_{etoile}}{\partial v} \space\space where \space\frac{\partial y_{etoile}}{\partial v} =\sigma'(v) = \frac{e^{-v}}{(1+e^{-v})^2} vL=yetoileLvyetoile  where vyetoile=σ(v)=(1+ev)2ev

∂ L ∂ y e t o i l e = ∂ L ∂ ϵ ∂ ϵ ∂ y e t o i l e    w h e r e   ∂ ϵ ∂ y e t o i l e = 1 \frac{\partial L}{\partial y_{etoile}} = \frac{\partial L}{\partial \epsilon}\frac{\partial \epsilon}{\partial y_{etoile}} \space\space where \space\frac{\partial \epsilon}{\partial y_{etoile}} =1 yetoileL=ϵLyetoileϵ  where yetoileϵ=1

最后, ∂ L ∂ ϵ = 2 ϵ \frac{\partial L}{\partial \epsilon} = 2\epsilon ϵL=2ϵ

通过链式法则,我们将复杂的复合函数的梯度拆解为一个个基础的梯度,他们的乘积就是我们需要的损失函数Loss Function关于权重的梯度:
∇ L ∣ w i = 2 ( ϵ ) σ ′ ( v ) x i \nabla L|_{w_i} = 2(\epsilon)\sigma'(v)x_i Lwi=2(ϵ)σ(v)xi

首先对于每个训练集中的数据 X X X,以及对应的当前权重 W W W,我们首先通过正向传播,计算出各个关键值并储存在内存中。
在这里插入图片描述
如下所示,通过正向传播以及各个变量之间的数值关系,我们可以很简单地计算出每次迭代各个变量对应的值。
在这里插入图片描述
接着就是反向传播计算梯度的过程了,如下图所示,例如我们有 ∂ L ∂ ϵ = 2 ϵ = − 1.37 ∗ 2 = − 2.75 \frac{\partial L}{\partial \epsilon} = 2\epsilon = -1.37 * 2 = -2.75 ϵL=2ϵ=1.372=2.75
又有
∂ ϵ ∂ y e t o i l e = 1 \frac{\partial \epsilon}{\partial y_{etoile}} =1 yetoileϵ=1
因此
∂ L ∂ y e t o i l e = ∂ L ∂ ϵ ∂ ϵ ∂ y e t o i l e = − 2.75 \frac{\partial L}{\partial y_{etoile}} = \frac{\partial L}{\partial \epsilon}\frac{\partial \epsilon}{\partial y_{etoile}} = -2.75 yetoileL=ϵLyetoileϵ=2.75


依此类推,我们不难通过链式法则,一步一步反向传播,直到计算出我们最终需求的梯度值: ∂ L ∂ w i \frac{\partial L}{\partial w_i} wiL在这里插入图片描述
理解了梯度下降算法在训练神经元过程中的应用,以及反向传播算法如何计算出复合梯度的过程,接下来分享一个Tensorflow模块中非常好用的计算梯度的类,这大大简化了我们计算反向传播的过程。

4. Tensorflow GradientTape

用几个简单的例子介绍一下功能强大的GradientTape类,可以帮助我们在深度学习中简便地计算函数的梯度。

import tensorflow as tf
with tf.GradientTape(watch_accessed_variables=True) as t:
	x = tf.Variable(3.0)
	y = x ** 2
	# t.watch(x)
	dy_dx = t.gradient(y,x)
	print(type(dy_dx))
	print(dy_dx.numpy())
	print(dy_dx)

上述代码计算了 y = x 2 y = x^2 y=x2这个函数在 x = x= x=
输出结果如下 :
在这里插入图片描述
Tensorflow库中的GradientTape类使用简单,其中输入输出都推荐定义为张量tensor的形式,即可训练的变量形式。GradientTape类中的watch_accessed_variables参数决定了类是否会自动观测保存可训练的变量,当这个参数值为False时,我们可以使用 t.watch()方法指定类观察的具体变量。

如下例子,调用t.gradient()方法时,变量也可以是高维的tensor。

w = tf.Variable(tf.random.normal((3,2)),name='w')
b = tf.Variable(tf.zeros(2,dtype=tf.float32),name='b')
x = [[1.,2.,3.]]

with tf.GradientTape() as tape:
  y = x @ w + b
  loss = tf.reduce_mean(y**2)
  # 可以用张量的形式同时计算多个变量tensor对应的梯度
  [dl_dw, dl_db] = tape.gradient(loss,[w,b])
  
  print(dl_dw)
  print(dl_db)

输出结果如下:
在这里插入图片描述
以我们在上一部分做的反向传播算法为例 :

with tf.GradientTape() as tape:
  W = tf.Variable([[-1.,-1.5]])
  X = tf.Variable([[-3.],[2.]])
  thelta = tf.Variable(0.5,dtype=tf.float32)
  y_etoile = tf.sigmoid(W @ X + thelta)
  y = tf.Variable(2,dtype=tf.float32)
  loss = (y_etoile - y) ** 2
  (dl_dx, dl_dw, dl_dthe) = tape.gradient(loss,[X,W,thelta])
  print(dl_dw)

输出结果如下:

可以看到,我们使用tensorflow计算出的梯度 ∂ L ∂ w i \frac{\partial L}{\partial w_i} wiL与使用反向传播算法的计算结果是一致的。
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:点我我会动 设计师:我叫白小胖 返回首页
评论

打赏作者

Cy_coding

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值