文章来自公众号【机器学习炼丹术】,回复“炼丹”即可获得海量学习资料哦!

本章节缕一缕PyTorch的动态图机制与Tensorflow的静态图机制(最新版的TF也支持动态图了似乎)。

1 动态图的初步推导

  • 计算图是用来描述运算的有向无环图
  • 计算图有两个主要元素:结点(Node)和边(Edge);
  • 结点表示数据 ,如向量、矩阵、张量;
  • 边表示运算 ,如加减乘除卷积等;

上图是用计算图表示:

\(y=(x+w)∗(w+1)y=(x+w)∗(w+1)\)

其中呢,\(a=x+w\) ,\(b=w+1\) , \(y=a∗b\). (a和b是类似于中间变量的那种感觉。)

Pytorch在计算的时候,就会把计算过程用上面那样的动态图存储起来。现在我们计算一下y关于w的梯度:

\(\frac{\partial y}{\partial w} = \frac{\partial y}{\partial a} \frac{\partial a}{\partial w} + \frac{\partial y}{\partial b} \frac{\partial b}{\partial w}\)

\(=2\times w + x + 1=5\)

(上面的计算中,w=1,x=2)

现在我们用Pytorch的代码来实现这个过程:

import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True) a = w+x
b = w+1
y = a*b y.backward()
print(w.grad)

得到的结果:

2 动态图的叶子节点

这个图中的叶子节点,是w和x,是整个计算图的根基。之所以用叶子节点的概念,是为了减少内存,在反向传播结束之后,非叶子节点的梯度会被释放掉 , 我们依然用上面的例子解释:

import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True) a = w+x
b = w+1
y = a*b y.backward()
print(w.is_leaf,x.is_leaf,a.is_leaf,b.is_leaf,y.is_leaf)
print(w.grad,x.grad,a.grad,b.grad,y.grad)

运行结果是:

可以看到只有x和w是叶子节点,然后反向传播计算完梯度后(.backward()之后),只有叶子节点的梯度保存下来了。

当然也可以通过.retain_grad()来保留非任意节点的梯度值。

import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True) a = w+x
a.retain_grad()
b = w+1
y = a*b y.backward()
print(w.is_leaf,x.is_leaf,a.is_leaf,b.is_leaf,y.is_leaf)
print(w.grad,x.grad,a.grad,b.grad,y.grad)

运行结果:

3. grad_fn

torch.tensor有一个属性grad_fn,grad_fn的作用是记录创建该张量时所用的函数,这个属性反向传播的时候会用到。例如在上面的例子中,y.grad_fn=MulBackward0,表示y是通过乘法得到的。所以求导的时候就是用乘法的求导法则。同样的,a.grad=AddBackward0表示a是通过加法得到的,使用加法的求导法则。

import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True) a = w+x
a.retain_grad()
b = w+1
y = a*b y.backward()
print(y.grad_fn)
print(a.grad_fn)
print(w.grad_fn)

运行结果是:

叶子节点的.grad_fn是None。

4 静态图

两者的区别用一句话概括就是:

  • 动态图:pytorch使用的,运算与搭建同时进行;灵活,易调节。
  • 静态图:老tensorflow使用的,先搭建图,后运算;高效,不灵活。

静态图我们是需要先定义好运算规则流程的。比方说,我们先给出

\(a = x+w\) , \(b=w+1\) , \(y=a\times b\)

然后把上面的运算流程存储下来,然后把w=1,x=2放到上面运算框架的入口位置进行运算。而动态图是直接对着已经赋值的w和x进行运算,然后变运算变构建运算图。

在一个课程http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture08.pdf中的第125页,有这样的一个对比例子:

这个代码是Tensorflow的,构建运算的时候,先构建运算框架,然后再把具体的数字放入其中。整个过程类似于训练神经网络,我们要构建好模型的结构,然后再训练的时候再吧数据放到模型里面去。又类似于在旅游的时候,我们事先定要每天的行程路线,然后每天按照路线去行动。

动态图呢,就是直接对数据进行运算,然后动态的构建出运算图。很符合我们的运算习惯。

两者的区别在于,静态图先说明数据要怎么计算,然后再放入数据。假设要放入50组数据,运算图因为是事先构建的,所以每一次计算梯度都很快、高效;动态图的运算图是在数据计算的同时构建的,假设要放入50组数据,那么就要生成50次运算图。这样就没有那么高效。所以称为动态图

动态图虽然没有那么高效,但是他的优点有以下:

  1. 更容易调试。
  2. 动态计算更适用于自然语言处理。(这个可能是因为自然语言处理的输入往往不定长?)
  3. 动态图更面向对象编程,我们会感觉更加自然。

小白学PyTorch 动态图与静态图的浅显理解的更多相关文章

  1. Deeplearning——动态图 vs. 静态图

    动态图 vs. 静态图 在 fast.ai,我们在选择框架时优先考虑程序员编程的便捷性(能更方便地进行调试和更直观地设计),而不是框架所能带来的模型加速能力.这也正是我们选择 PyTorch 的理由, ...

  2. 【小白学PyTorch】20 TF2的eager模式与求导

    [新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx64501661 ...

  3. 【小白学PyTorch】11 MobileNet详解及PyTorch实现

    文章来自微信公众号[机器学习炼丹术].我是炼丹兄,欢迎加我微信好友交流学习:cyx645016617. @ 目录 1 背景 2 深度可分离卷积 2.2 一般卷积计算量 2.2 深度可分离卷积计算量 2 ...

  4. 【小白学PyTorch】18 TF2构建自定义模型

    [机器学习炼丹术]的炼丹总群已经快满了,要加入的快联系炼丹兄WX:cyx645016617 参考目录: 目录 1 创建自定义网络层 2 创建一个完整的CNN 2.1 keras.Model vs ke ...

  5. 【小白学PyTorch】4 构建模型三要素与权重初始化

    文章目录: 目录 1 模型三要素 2 参数初始化 3 完整运行代码 4 尺寸计算与参数计算 1 模型三要素 三要素其实很简单 必须要继承nn.Module这个类,要让PyTorch知道这个类是一个Mo ...

  6. 【小白学PyTorch】7 最新版本torchvision.transforms常用API翻译与讲解

    文章来自:微信公众号[机器学习炼丹术].欢迎关注支持原创 也欢迎添加作者微信:cyx645016617. 参考目录: 目录 1 基本函数 1.1 Compose 1.2 RandomChoice 1. ...

  7. 【小白学PyTorch】8 实战之MNIST小试牛刀

    文章来自微信公众号[机器学习炼丹术].有什么问题都可以咨询作者WX:cyx645016617.想交个朋友占一个好友位也是可以的~好友位快满了不过. 参考目录: 目录 1 探索性数据分析 1.1 数据集 ...

  8. 【小白学PyTorch】12 SENet详解及PyTorch实现

    文章来自微信公众号[机器学习炼丹术].我是炼丹兄,有什么问题都可以来找我交流,近期建立了微信交流群,也在朋友圈抽奖赠书十多本了.我的微信是cyx645016617,欢迎各位朋友. 参考目录: @ 目录 ...

  9. 【小白学PyTorch】13 EfficientNet详解及PyTorch实现

    参考目录: 目录 1 EfficientNet 1.1 概述 1.2 把扩展问题用数学来描述 1.3 实验内容 1.4 compound scaling method 1.5 EfficientNet ...

随机推荐

  1. Android Zero (基础介绍篇)

    开发Android首先你得先配置好环境,配置的文章网上一大把,这里就不重复造轮子说了,配置好JAVA下载好AndroidStudio后我们先对基本的项目结构做一下了解! 首先介绍下你必须得知道的文件夹 ...

  2. 第四章 常用API(下)

    4.1.String类 描述:该类代表字符串 构造方法: 方法 描述 public String() 初始化构造一个空白字符串 public String(char[] value) 通过字符数组初始 ...

  3. Hexo博客美化之蝴蝶(butterfly)主题魔改

      Hexo是轻量级的极客博客,因为它简便,轻巧,扩展性强,搭建部署方便深受广大人们的喜爱.各种琳琅满路的Hexo主题也是被各种大佬开发出来,十分钦佩,向大佬仰望,大声称赞:流批!!! 我在翻看各种主 ...

  4. Python long() 函数

    描述 long() 函数将数字或字符串转换为一个长整型.高佣联盟 www.cgewang.com 语法 long() 函数语法: class long(x, base=10) 参数 x -- 字符串或 ...

  5. PHP uksort() 函数

    ------------恢复内容开始------------ 实例 使用用户自定义的比较函数对数组 $arr 中的元素按键名进行排序: <?phpfunction my_sort($a,$b){ ...

  6. PHP strtolower() 函数

    实例 把所有字符转换为小写: <?php高佣联盟 www.cgewang.comecho strtolower("Hello WORLD.");?> 定义和用法 str ...

  7. luogu P2252 威佐夫博弈 模板 博弈

    LINK:威佐夫博弈 四大博弈 我都没有好好整理 不过大致可以了解一下. 在这个博弈中 存在一些局面 先手遇到必胜. 不过由于后手必胜的局面更具规律性这里研究先手遇到的局面后手必胜的情况. 这些局面分 ...

  8. luogu P3412 仓鼠找sugar II 期望 树形dp

    LINK:仓鼠找sugar II 以前做过类似的期望题目 加上最后的树形dp不算太难 还是可以推出来的. 容易发现 当固定起点和终点的时候 可以先固定根 这样就不用分到底是正着走还是倒着走了. 1为根 ...

  9. Kaggle-pandas(4)

    Grouping-and-sorting 教程 映射使我们可以一次将整个列中的数据转换为DataFrame或Series中的一个值. 但是,通常我们希望对数据进行分组,然后对数据所在的组进行特定的操作 ...

  10. UI自动化填写问卷(selenium)+定时任务(懒人必备)

    1.自动填报 UI自动化 selenium 开发程序动机:天天有人催着填写问卷,弄的头大.主要还是懒的每天一个个去填写内容. 开发总时长:2个小时:学习+开发+修改 遇到的小问题: 在自动化填写地图的 ...