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

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

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

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

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

在这里插入图片描述

2. 梯度下降算法 gradientdescentgradient\space\space descentgradient  descent

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

在这里插入图片描述

3. backpropagation 反向传播算法

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

ei=wixie_i = w_ix_iei=wixi,

v=∑iei+θv=\sum_ie_i+ \thetav=iei+θ

默认使用sigmoid激励函数:

yetoile=σ(v)y_{etoile} = \sigma(v)\space\spaceyetoile=σ(v)   经过激励函数后的输出

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

ϵ=yetoile−y\epsilon = y_{etoile} - y\space\spaceϵ=yetoiley   yetoiley_{etoile}yetoile与实际值yyy的误差

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

使用链式法则我们不难得到 :
∂L∂wi=∂L∂ei∂ei∂wiwhere∂ei∂wi=xi\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∂ei=∂L∂v∂v∂eiwhere∂v∂ei=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∂yetoile∂yetoile∂vwhere∂yetoile∂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∂yetoile=∂L∂ϵ∂ϵ∂yetoilewhere∂ϵ∂yetoile=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∣wi=2(ϵ)σ′(v)xi\nabla L|_{w_i} = 2(\epsilon)\sigma'(v)x_iLwi=2(ϵ)σ(v)xi

首先对于每个训练集中的数据XXX,以及对应的当前权重WWW,我们首先通过正向传播,计算出各个关键值并储存在内存中。
在这里插入图片描述
如下所示,通过正向传播以及各个变量之间的数值关系,我们可以很简单地计算出每次迭代各个变量对应的值。
在这里插入图片描述
接着就是反向传播计算梯度的过程了,如下图所示,例如我们有∂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
又有
∂ϵ∂yetoile=1\frac{\partial \epsilon}{\partial y_{etoile}} =1yetoileϵ=1
因此
∂L∂yetoile=∂L∂ϵ∂ϵ∂yetoile=−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∂wi\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=x2y = x^2y=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 + bloss = 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∂wi\frac{\partial L}{\partial w_i}wiL与使用反向传播算法的计算结果是一致的。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vs2015web项目无法加载64位c++的dll,提示试图加载不正确的格式

vs2015无法加载64位c的dll,提示试图加载不正确的格式! 开始用winform引用64位的c的dll,在项目的属性设置生成里面选择any cpu或者x64都可以成功! 但在web项目和接口里面运行就提示试图加载不正确的格式,想办法找了一天也没处理掉&…

使用Rancher搭建K8S测试环境

环境准备(4台主机,Ubuntu16.04Docker1.12.6 SSH): rancher1 192.168.3.160 只做管理节点 node1 192.168.3.161 K8S的节点1 node2 192.168.3.162 K8S的节点2 node3 192.168.3.163 K8S的节点3 此时如…

Anaconda安装tensorflow报错问题解决方法

最近脱离了googlecolab想使用本地的anaconda进行机器学习课题的演练,在安装tensorflow时报错 : UnsatisfiableError: The following specifications were found。下面给出解决方法。 发现实际原因是由于anaconda的python环境,当前版本的tensorflow只能适…

yml的mybatis的sql查看

yml的mybatis的sql查看 控制台输出结果:

unity如何让canvas总是显示在所有层的最上方?

由于unity中的图层都是从上至下渲染的,那么在渲染的过程中,只需要将canvas所在的UI层的渲染优先级order排在其他层之后,就可以保证UI画面总是最后加载出来的了。 在canvas的inspector中修改order in layer 或者 sorting layer都可以实现这一…

关于同时可用git命令clone和TortoiseGit拉取代码不需要密码

工作需要在windows7下使用git分布式版本控制系统,需要同时可以在git命令行模式或TortoiseGit拉取代码而不需要每次输入密码。 这时候需要同时安装git和TortoiseGit。 git使用命令ssh-keygen -C “邮箱地址” -t rsa产生的密钥在TortoiseGit中不能用。TortoiseGit 使…

交叉验证 cross validation 与 K-fold Cross Validation K折叠验证

交叉验证,cross validation是机器学习中非常常见的验证模型鲁棒性的方法。其最主要原理是将数据集的一部分分离出来作为验证集,剩余的用于模型的训练,称为训练集。模型通过训练集来最优化其内部参数权重,再在验证集上检验其表现。…

第十一周总结

这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/computer-scienceclass4-2018/homework/3203 我在这个课程的目标是 理解与使用递归函数。 参考文献 基础题 2-1 宏定义“#define DIV(a, b) a/b”,经DIV(x …

softmax函数与交叉熵损失函数

本文主要介绍了当前机器学习模型中广泛应用的交叉熵损失函数与softmax激励函数。 这个损失函数主要应用于多分类问题,用于衡量预测值与实际值之间的相似程度。 交叉熵损失函数定义如下: LCE(y^,y∗)−∑i1Nclassesyi∗log(yi^)L_{CE}(\hat{y}, y^*) - \sum_{i1}^…

unity如何让物体与特定物体之间不发生碰撞

unity中我们普遍使用的是碰撞器来实现各个物体的碰撞体积,例如Box collider, Sphere Collider。 在实现游戏的过程中,如果不想要物体与特定物体产生碰撞,或反之,只想让碰撞发生在特定物体之间时,我们就需要配置layer …

jenkins的JAVA简单顺序配置git仓库

后台Java的发布配置 1、从源码管理下载项目内容 2、构建触发器 3 、构建下环境 4、构建后处理

SQLyog连接数据库报错plugin caching_sha2_password could not be loaded

打开cmd:mysql -uroot -p 进入mysql依次执行下面语句 ALTER USER rootlocalhost IDENTIFIED BY password PASSWORD EXPIRE NEVER; #修改加密规则 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY password; #更新一下用户的密码 FLUSH PRIVI…

unity导入素材时材质丢失素材变成粉红色的解决方法

有很多时候,当我们通过unity asset store或者blender等等外源导入素材时,会出现材质缺失的bug,如下图所示 : 一个很可能的原因,是由于unity本身管线在每个版本的更新过程中,材质的渲染编码发生了改变。由于这种原因引…

Jenkins 部署vue到服务器

链接github名称 2、从源码管理下载 3、更新最新前端模块 4、进行构建和打包

numpy数组提取一定规律的数据

numpy数组的索引也是符合start stop step规律的,因此可以通过索引提取出一系列索引有规律的元素,如下例子: import numpy as np i np.linspace(1,100,100, dtypeint)-1 print(i) i_train i[0:100:10] print(i_train)输出结果如下 : 可以看到通过索引…

CRM、用户管理权限

CRM目录结构 from django.shortcuts import HttpResponse,render,redirect from django.conf.urls import url from django.utils.safestring import mark_safe from django.urls import reverse from django.forms import ModelForm from stark.utils.my_page import Paginat…

GAN生成对抗网络基本概念及基于mnist数据集的代码实现

本文主要总结了GAN(Generative Adversarial Networks) 生成对抗网络的基本原理并通过mnist数据集展示GAN网络的应用。 GAN网络是由两个目标相对立的网络构成的,在所有GAN框架中都至少包含了两个部分,生成模型部分和判别模型部分。生成模型的目标是制造出…

autoencoder自编码器原理以及在mnist数据集上的实现

Autoencoder是常见的一种非监督学习的神经网络。它实际由一组相对应的神经网络组成(可以是普通的全连接层,或者是卷积层,亦或者是LSTMRNN等等,取决于项目目的),其目的是将输入数据降维成一个低维度的潜在编…

vscode编写插件详细过程

vscode编写插件详细过程 前言 之前编写了一个vscode插件用vscode写博客和发布,然后有园友要求写一篇来介绍如何开发一个vscode扩展插件,或者说介绍开发这个插件的过程。然而文章还没有写,园子里面已经有人发布一个文章,是园友上…