使用PyTorch构建神经网络以及反向传播计算
使用PyTorch构建神经网络以及反向传播计算
前一段时间南京出现了疫情,大概原因是因为境外飞机清洁处理不恰当,导致清理人员感染。话说国外一天不消停,国内就得一直严防死守。沈阳出现了一例感染人员,我在22号乘坐飞机从沈阳乘坐飞机到杭州,恰好我是一位密切接触人员的后三排,就这样我成为了次密切接触人员,人下飞机刚到杭州就被疾控中心带走了,享受了全免费的隔离套餐,不得不说疾控中心大数据把控是真的有力度。在这一段时间,也让我沉下心来去做了点事,之前一直鸽的公众号也开始写上了。。。不过隔离期间确实让我这么宅的人都感觉很憋。。。唠唠叨叨这么多,言归正传,这节将从反向传播算法进一步分析基于PyTorch的神经网络算法。
构建神经网络
在训练神经网络时,常用的算法是反向传播。该算法中,参数根据损失函数相对应的给定的参数的梯度进行调整。为了计算这些梯度,使用PyTorch的内置函数torch.autograd。它支持任何网络的梯度计算。
通过构建一层神经网络来进行细致的分析;
import torch
x = torch.ones(5) # input tensor
y = torch.zeros(3) # expected output
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)
z = torch.matmul(x, w)+b
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)
通过PyTorch定义具有输入x,参数w,b以及损失函数,进而构建一层神经网络。
张量,函数,计算图
print('Gradient function for z =',z.grad_fn)
print('Gradient function for loss =', loss.grad_fn)
输出结果如下;
我们通过张量来构建计算图函数本质是Function的对象。该对象定义了前向计算函数,在反向传播中计算导数。将反向传播函数存储在grad_fn中。
参考PyTorch文档https://pytorch.org
在整个网络中,w,b是需要优化的参数。为了计算这些参数的损失函数的梯度,设置了requires_grad这些张量的属性。
计算梯度
梯度,本意是一个向量,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大。
为了优化神经网络参数的权重,需要计算损失函数关于参数的导数,通过loss.backward() 进行计算。
loss.backward()
print(w.grad)
print(b.grad)
输出结果如下;
我们只能获取grad计算图的叶子节点的requeires_grad属性,这些属性设置为True。backward只能在图中使用一次梯度计算,如果需要backward在同一个图多次调用,我们需要传递retain_graph-True和backward调用
更多图计算
从概念上讲,autograd 在由Function 对象组成的有向无环图 (DAG) 中保存数据(张量)和所有已执行操作(以及生成的新张量)的记录 。在这个 DAG 中,叶子是输入张量,根是输出张量。通过从根到叶跟踪此图,可以使用链式法则自动计算梯度。
在前向传递过程,autograd需要计算结果张量,在DAG中保持梯度函数
在DAG中调用abckward() 需要计算各自的梯度,将其累计在各自的grad属性中,使用链式法则,传递到叶张量。
DAG是动态的,每次调用backward()函数,autograd开始填充新图形,如果需要可以在每次迭代时进行操作。
梯度以及雅可比积
梯度,张量在任意常数c方向上的梯度:n阶张量的梯度是n+1张量场。
雅可比积是表示两个向量的所有可能偏导数的矩阵。它是一个向量相对于另一个向量的梯度,Autograd可以对张量进行微分,从一个变量开始执行反向传播。在深度学习中,这个变量通常保存成本函数的值,自动计算所有反向传播梯度
计算雅可比乘积而不是计算雅可比矩阵本身;
计算成绩如下所示
inp = torch.eye(5, requires_grad=True)
out = (inp+1).pow(2)
out.backward(torch.ones_like(inp), retain_graph=True)
print("First call\n", inp.grad)
out.backward(torch.ones_like(inp), retain_graph=True)
print("\nSecond call\n", inp.grad)
inp.grad.zero_()
out.backward(torch.ones_like(inp), retain_graph=True)
print("\nCall after zeroing gradients\n", inp.grad)
当backward使用相同的参数进行第二次调用时,梯度的值是不同的。发生这种情况是因为在进行反向传播时,PyTorch会积累梯度,即将梯度的值添加到grad图计算中所有节点的属性中。如果要计算适当的梯度,需要将grad归零。
结语
关于禁用渐变跟踪问题上,有时我们不需要跟踪计算所有计算历史,将神经网络某些参数固定是微调神经网络常用方法,而且在仅向前传递时加快计算速度。
在图计算问题上,autograd 在由Function 对象组成的有向无环图 (DAG) 中保存数据(张量)和所有已执行操作(以及生成的新张量)的记录 。在这个 DAG 中,叶子是输入张量,根是输出张量。通过从根到叶跟踪此图,您可以使用链式法则自动计算梯度。前向传递,autograd计算结果张量,在dag中维护操作的梯度函数,在反向传递中,计算每个梯度.grad_fn,将他们积累到.grad属性中,使用链式法则传播到叶张量。下一节将从优化模型参数角度进行学习
参考开发文档:https://pytorch.org/tutorials/beginner/basics/buildmodel_tutorial.html
推荐阅读
使用PyTorch构建神经网络以及反向传播计算的更多相关文章
- 深度学习与CV教程(4) | 神经网络与反向传播
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...
- 关于 RNN 循环神经网络的反向传播求导
关于 RNN 循环神经网络的反向传播求导 本文是对 RNN 循环神经网络中的每一个神经元进行反向传播求导的数学推导过程,下面还使用 PyTorch 对导数公式进行编程求证. RNN 神经网络架构 一个 ...
- Andrej Karpathy | 详解神经网络和反向传播(基于 micrograd)
只要你懂 Python,大概记得高中学过的求导知识,看完这个视频你还不理解反向传播和神经网络核心要点的话,那我就吃鞋:D Andrej Karpathy,前特斯拉 AI 高级总监.曾设计并担任斯坦福深 ...
- 使用pytorch构建神经网络的流程以及一些问题
使用PyTorch构建神经网络十分的简单,下面是我总结的PyTorch构建神经网络的一般过程以及我在学习当中遇到的一些问题,期望对你有所帮助. PyTorch构建神经网络的一般过程 下面的程序是PyT ...
- 神经网络之反向传播算法(BP)公式推导(超详细)
反向传播算法详细推导 反向传播(英语:Backpropagation,缩写为BP)是"误差反向传播"的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见 ...
- NLP教程(3) | 神经网络与反向传播
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www.showmeai.tech/article-det ...
- PyTorch深度学习实践——反向传播
反向传播 课程来源:PyTorch深度学习实践--河北工业大学 <PyTorch深度学习实践>完结合集_哔哩哔哩_bilibili 目录 反向传播 笔记 作业 笔记 在之前课程中介绍的线性 ...
- AI之旅(7):神经网络之反向传播
前置知识 求导 知识地图 神经网络算法是通过前向传播求代价,反向传播求梯度.在上一篇中介绍了神经网络的组织结构,逻辑关系和代价函数.本篇将介绍如何求代价函数的偏导数(梯度). 梯度检测 在 ...
- 神经网络中误差反向传播(back propagation)算法的工作原理
注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...
随机推荐
- webpack打包报错 ERROR in ./js/ww.js from UglifyJs Unexpected token keyword «function», expected punc «,» [src/page/ww/view/xx/xx.vue:119,0][./js/ww.js:55218,17]
找了好多解决办法 你可以试着将babel-loader的exclude注释掉,然后看能否打包成功.如果可以,那就是这个问题.你只需要在vue.config.js中配置transpileDependen ...
- 容器之分类与各种测试(三)——list部分用法
list是一个双向链表 例程 #include<stdexcept> #include<memory.h> #include<string> #include< ...
- SQL count和sum
count(1).count(*)与count(列名)的执行区别 count(1) and count(字段) 两者的主要区别是 (1) count(1) 会统计表中的所有的记录数,包含字段为null ...
- Dubbo服务调用超时
服务降级的发生,其实是由于消费者调用服务超时引起的,即从发出调用请求到获取到提供者的响应结果这个时间超出了设定的时限.默认服务调用超时时限为1秒.可以在消费者端与提供者端设置超时时限. 一.创建提供者 ...
- Vue局部组件和全局组件
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 【Matlab】快速傅里叶变换/ FFT/ fftshift/ fftshift(fft(fftshift(s)))
[自我理解] fft:可以指定点数的快速傅里叶变换 fftshift:将零频点移到频谱的中间 用法: Y=fftshift(X) Y=fftshift(X,dim) 描述:fftshift移动零频点到 ...
- ctypes与numpy.ctypeslib的使用
numpy ctypeslib 与 ctypes接口使用说明 作者:elfin 目录 一.numpy.ctypeslib使用说明 1.1 准备好一个C++计算文件 1.2 ctypeslib主要的五个 ...
- 用Navicat连接数据库-数据库连接(MySQL演示)
用Navicat连接数据库-数据库连接(MySql演示) 已成功连接,连接方式步骤如下: 开始之前首先准备连接信息: [ 一般你可以自己去配置文件中找 或者 问连接过该数据库的人/所有者(负责人/同学 ...
- pthread_cond_signal与pthread_cond_wait详解
转:http://blog.chinaunix.net/uid-11572501-id-3456343.html //pthread_cond_signal 只发信号,内部不会解锁,在Linux 线程 ...
- QT QApplication干了啥?
------------恢复内容开始------------ QCoreApplicationPrivate 会取得current thread; 在windows平台创建TLS变量,记录线程信息,并 ...