精华内容
下载资源
问答
  • 点击关注我哦一篇文章带你了解动态和静态图的区别优劣但凡我们接触深度学习框架,肯定都会听过“计算图”这个概念,如果有具体使用过某个框架,可以知道计算图又可以分为:静态图和动态图。深度学...

    点击关注我哦

    一篇文章带你了解动态图和静态图的区别和优劣

    但凡我们接触深度学习框架,肯定都会听过“计算图”这个概念,如果有具体使用过某个框架,可以知道计算图又可以分为:静态图和动态图。深度学习最大的区别也在于此:使用不同的计算图进行构造和运行。

    静态图意味着我们只需要定义一个计算图,然后对其进行编译,在后续过程中不断使用它。而动态图则相反,由于并没有预先定义,即在每次使用时建立,程序按照我们编写命令的顺序进行执行。

    静态图以TensorFlow为例,我们在模型运行前定义一个静态图,至此,所有和外部的通信都是通过tf.Session()对象和tf.Placeholder占位符执行的,其中tf.Seesion用来开启会话,tf.Placeholder是在运行时外部数据传入的占位符张量。

    鉴于静态图的这种构建机制,从理论上讲,容易在图上对其进行优化,因此其运算效率会比较高。

    动态图以Pytorch为例,事情就变得比较动态化:我们可以随时定义、更改和执行代码,而不需要特殊的会话窗口和占位符。并且该框架和Python语言紧密结合,省出了额度学习成本,用起来会感觉比TensorFlow更为原生和友好。

    动态图的构造原理使得调试过程变得更为容易,也能更直观地设计,因此比较方便我们将自己的想法快速进行复现,可以说是学术“利器”。

    借用网络上一个小伙伴的有趣比喻,假如我们让TensorFlow和Pytorch分别造一座房子:

    TensorFlow会先将造房子的流程预演一遍,设计好流程图,看下都需要什么资源,提前规划好什么时候需要做什么,最后找到一个可以建造这种房子的工程队。最后把上面那些全部交给工程队搞定。

    Pytorch会先将造房子分成几个项目,每一个项目相互独立。等到开始建造房子的时候,写一个TODO list把需要做的事情安装所需顺序串起来,然后分别去执行每个项目。

    注:很多网络模型可能使用动态图或者静态图更为友好,读者可以根据自己的网络结构恰当选择。

    我们用一张表格对其进行比较:

    大家如果在Pytorch的学习过程中有什么疑问,也可以后台留言告诉小蓝~有时间会给大家一一回复~

    ·  END  ·

    RECOMMEND

    推荐阅读

     1. 深度学习——入门PyTorch(一)

     2. 深度学习——入门PyTorch(二)

     3. PyTorch入门——autograd(一)

     4. PyTorch入门——autograd(二)

     5. PyTorch入门——autograd(三)

    展开全文
  • 目前神经网络框架分为静态图框架和动态图框架,PyTorch TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 TensorFlow 使用静态图,这意味着我们先定义计算图,然后不断使用它,而在 ...
  • Pytorch Note5 动态和静态图动态和静态图TensorFlowPyTorch 动态和静态图 目前神经网络框架分为静态图框架和动态图框架,PyTorch TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 ...

    Pytorch Note5 动态图和静态图

    全部笔记的汇总贴:Pytorch Note 快乐星球

    动态图和静态图

    目前神经网络框架分为静态图框架和动态图框架,PyTorch 和 TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 TensorFlow 使用静态图,这意味着我们先定义计算图,然后不断使用它,而在 PyTorch 中,每次都会重新构建一个新的计算图。通过这次课程,我们会了解静态图和动态图之间的优缺点。

    对于使用者来说,两种形式的计算图有着非常大的区别,同时静态图和动态图都有他们各自的优点,比如动态图比较方便debug,使用者能够用任何他们喜欢的方式进行debug,同时非常直观,而静态图是通过先定义后运行的方式,之后再次运行的时候就不再需要重新构建计算图,所以速度会比动态图更快。

    下面我们比较 while 循环语句在 TensorFlow 和 PyTorch 中的定义

    TensorFlow

    # tensorflow
    import tensorflow as tf
    
    first_counter = tf.constant(0)
    second_counter = tf.constant(10)
    
    def cond(first_counter, second_counter, *args):
        return first_counter < second_counter
    
    def body(first_counter, second_counter):
        first_counter = tf.add(first_counter, 2)
        second_counter = tf.add(second_counter, 1)
        return first_counter, second_counter
    
    c1, c2 = tf.while_loop(cond, body, [first_counter, second_counter])
    
    with tf.Session() as sess:
        counter_1_res, counter_2_res = sess.run([c1, c2])
    
    print(counter_1_res)
    print(counter_2_res)
    

    20
    20

    可以看到 TensorFlow 需要将整个图构建成静态的,换句话说,每次运行的时候图都是一样的,是不能够改变的,所以不能直接使用 Python 的 while 循环语句,需要使用辅助函数 tf.while_loop 写成 TensorFlow 内部的形式

    这是非常反直觉的,学习成本也是比较高的

    下面我们来看看 PyTorch 的动态图机制,这使得我们能够使用 Python 的 while 写循环,非常方便

    PyTorch

    # pytorch
    import torch
    first_counter = torch.Tensor([0])
    second_counter = torch.Tensor([10])
    
    while (first_counter < second_counter)[0]:
        first_counter += 2
        second_counter += 1
    
    print(first_counter)
    print(second_counter)
    

    20
    [torch.FloatTensor of size 1]
    20
    [torch.FloatTensor of size 1]

    可以看到 PyTorch 的写法跟 Python 的写法是完全一致的,没有任何额外的学习成本

    PyTorch的动态图框架主要是由torch/csrc/autograd下的代码实现的。这个目录下定义了3个主要的基类:Variable、Function、Engine,这三个基类及其继承体系共同构成了PyTorch动态图的根基。

    为什么叫作动态图呢?图容易理解,Function是nodes/vertices,(Function, input_nr)是edges。那么动态体现在什么地方呢?每一次前向时构建graph,反向时销毁。

    上面的例子展示如何使用静态图和动态图构建 while 循环,看起来动态图的方式更加简单且直观。

    下一章传送门:Note6 自动求导Autograd

    展开全文
  • PyTorch 采用的是动态图机制 (Dynamic Computational Graph),而 Tensorflow 采用的是静态图机制 (Static Computational Graph)。 动态图是运算搭建同时进行,也就是可以先计算前面的节点的值,再根据这些值搭建...

    https://zhuanlan.zhihu.com/p/191648279

    PyTorch 的动态图机制

    PyTorch 采用的是动态图机制 (Dynamic Computational Graph),而 Tensorflow 采用的是静态图机制 (Static Computational Graph)。

    动态图是运算和搭建同时进行,也就是可以先计算前面的节点的值,再根据这些值搭建后面的计算图。优点是灵活,易调节,易调试。PyTorch 里的很多写法跟其他 Python 库的代码的使用方法是完全一致的,没有任何额外的学习成本。

    静态图是先搭建好图,然后再输入数据进行运算。优点是高效,因为静态计算是通过先定义后运行的方式,之后再次运行的时候就不再需要重新构建计算图,所以速度会比动态图更快。但是不灵活。TensorFlow 每次运行的时候图都是一样的,是不能够改变的,所以不能直接使用 Python 的 while 循环语句,需要使用辅助函数 tf.while_loop 写成 TensorFlow 内部的形式。

    使用静态图和动态图时他们的代码区别:

    # pytorch
    import torch
    first_counter = torch.Tensor([0])   # tensor([0.])
    second_counter = torch.Tensor([10]) # tensor([10.])
    
    while (first_counter < second_counter)[0]:
        first_counter += 2
        second_counter += 1
    
    print(first_counter)
    print(second_counter)
    
    
    # tensorflow
    import tensorflow as tf
    
    first_counter = tf.constant(0)
    second_counter = tf.constant(10)
    
    def cond(first_counter, second_counter, *args):
        return first_counter < second_counter
    
    def body(first_counter, second_counter):
        first_counter = tf.add(first_counter, 2)
        second_counter = tf.add(second_counter, 1)
        return first_counter, second_counter
    
    c1, c2 = tf.while_loop(cond, body, [first_counter, second_counter])
    
    with tf.Session() as sess:
        counter_1_res, counter_2_res = sess.run([c1, c2])
    
    print(counter_1_res)
    print(counter_2_res)

     

    展开全文
  • title: TensorFlow-静态图和PyTorch-动态图区别 categories: Knowledge PyTorch tags: Knowledge PyTorch TensorFlow 计算图 TensorFlow-静态图和PyTorch-动态图区别 最近在重新学习一遍pytorch,之前对于自动...

    title: TensorFlow-静态图和PyTorch-动态图区别

    categories:

    • Knowledge
    • PyTorch

    tags:

    • Knowledge
    • PyTorch
    • TensorFlow
    • 计算图

    TensorFlow-静态图和PyTorch-动态图区别

    最近在重新学习一遍pytorch,之前对于自动求导中的计算图的概念不是很清楚,这里从头看了一遍,有了解一下,简单的写一下自己的笔记。

    PyTorch自动求导看起来非常像TensorFlow,这两个框架中,我们都定义了计算图,使用自动微分来计算梯度,但是两者之间最大的不同是TensorFlow的计算图是静态的,而PyTorch使用的是动态的计算图。
    在TensorFlow中,我们定义计算图一次,然后后续就会重复执行这个相同的图,后面的话可能只是会提供不同的输入数据,而在PyTorch中,每一个前向通道(forward)定义一个新的计算图。

    静态图的好处在于你可以预先对图进行优化。例如:一个框架可能要融合一些图的运算来提升效率,或者产生一个策略来将图分布到多个GPU或者机器上,如果重复使用相同的图,那么再重复运行一个图时,前期潜在的代价高昂的预先优化的消耗就会被分摊开。

    静态图和动态图的一个区别是控制流。对于一些模型,我们希望对每个数据点执行不同的计算。例如:一个递归神经网络可能对每个数据点执行不同的时间步数,这个展开(unrolling)可以作为一个循环来实现。
    对于一个静态图,循环结构要作为图的一部分,因此TensorFlow提供了运算符来把循环嵌入到图当中。对于动态图来说,情况更加简单,既然我们为每个例子即时创建计算图,我们可以使用普通的命令式控制流来为每个输入执行不同的计算。

    tensorflow的forward只会根据第一次模型前向传播来构建一个静态的计算图, 后面的梯度自动求导都是根据这个计算图来计算的, 但是pytorch则不是, 它会为每次forward计算都构建一个动态图的计算图, 后续的每一次迭代都是使用一个新的计算图进行计算的.

    PyTorch应用控制流的动态图实例

    作为动态图(网络结构发生变化并不影响计算图计算梯度)和权重共享的一个例子,我们实现了一个非常奇怪的模型:一个全连接的ReLU网络,在每一次前向传播时,它的隐藏层的层数为随机1到4之间的数,这样可以多次重用相同的权重来计算。

    因为这个模型可以使用普通的Python流控制来实现循环,并且我们可以通过定义转发时多次重用同一个模块来实现最内层的权重共享。

    下面是例子的代码:

    import torch
    import torch.nn as nn
    import random
    
    # fixme: 定义网络
    class DynamicNet(nn.Module):
        def __init__(self, D_in, H, D_out):
            """
            构造函数,在这里需要将网络的各个模块进行实例化, 并把他们作为成员变量
            :params D_in: 输入维度
            :params H: 隐藏层维度
            :params D_out: 输出维度
            """
            super(DynamicNet, self).__init__()
            
            self.input_layer = nn.Linear(D_in, H)
            self.hidden_layer = nn.Linear(H, H)
            self.output_layer = nn.Linear(H, D_out)
            
            self.relu = nn.ReLU()
            
        def forward(self, x):
            x1 = self.input_layer(x)
            t_relu = self.relu(x1)
            
            # 定义0-3个隐藏层,利用pytorch动态图的特征,这种做法是可行的
            ## 重复调用self.hidden_layer 0-3次,由于pytorch是采用动态图的,因此每一次forward都会创建一个新的动态图,不影响梯度计算
            for _ in range(random.randint(0, 3)):
                t_relu = self.relu(self.hidden_layer(t_relu))
            
            pred = self.output_layer(t_relu)
            
            return pred
    
    # fixme: 参数配置
    dtype = torch.float
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    N, D_in, H, D_out = 64, 1000, 100, 10 # N为批量大小,D_in是输入维度,H是隐藏层维度,D_out是输出层维度
    learning_rate = 1e-4
    epochs = 100
    
    # fixeme: 创建输入和输出随机张量
    input = torch.randn(N, D_in)
    label = torch.randn(N, D_out)
    
    # fixme: 实例化模型
    model = DynamicNet(D_in, H, D_out)
    
    # fixme: 损失函数的定义
    loss_fn = torch.nn.MSELoss(reduction='sum')
    
    # fixme: 使用torch.optim定义参数优化器
    optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate) # 这里用的是Adam
    
    # fixme: 训练
    for epoch in range(epochs):
        # 前向过程
        pred = model(input)
        
        # 计算loss
        loss = loss_fn(pred, label)
        print('当前代数:{},当前loss为:{}'.format(epoch,loss.item()))
        
        # 模型参数梯度置零
        optimizer.zero_grad()
        
        # loss反向传播
        loss.backward()
        
        # 更新权重
        optimizer.step()
    
    当前代数:0,当前loss为:702.3717651367188
    当前代数:1,当前loss为:700.1735229492188
    当前代数:2,当前loss为:697.996826171875
    当前代数:3,当前loss为:701.37646484375
    当前代数:4,当前loss为:745.0324096679688
    当前代数:5,当前loss为:686.2260131835938
    当前代数:6,当前loss为:729.3468017578125
    当前代数:7,当前loss为:719.3234252929688
    当前代数:8,当前loss为:700.3496704101562
    当前代数:9,当前loss为:697.38720703125
    当前代数:10,当前loss为:676.840576171875
    当前代数:11,当前loss为:674.8969116210938
    当前代数:12,当前loss为:667.5950927734375
    当前代数:13,当前loss为:657.723388671875
    当前代数:14,当前loss为:668.5684814453125
    当前代数:15,当前loss为:691.20361328125
    当前代数:16,当前loss为:629.1569213867188
    当前代数:17,当前loss为:662.6659545898438
    当前代数:18,当前loss为:611.5732421875
    当前代数:19,当前loss为:602.4924926757812
    当前代数:20,当前loss为:698.65625
    当前代数:21,当前loss为:583.9902954101562
    当前代数:22,当前loss为:655.1369018554688
    当前代数:23,当前loss为:566.2965087890625
    当前代数:24,当前loss为:557.3516845703125
    当前代数:25,当前loss为:547.8927001953125
    当前代数:26,当前loss为:650.374755859375
    当前代数:27,当前loss为:648.9633178710938
    当前代数:28,当前loss为:697.7493286132812
    当前代数:29,当前loss为:515.4136962890625
    当前代数:30,当前loss为:507.982421875
    当前代数:31,当前loss为:500.00030517578125
    当前代数:32,当前loss为:491.6020812988281
    当前代数:33,当前loss为:482.8730163574219
    当前代数:34,当前loss为:697.01220703125
    当前代数:35,当前loss为:687.0211791992188
    当前代数:36,当前loss为:638.8866577148438
    当前代数:37,当前loss为:696.5703735351562
    当前代数:38,当前loss为:636.4703369140625
    当前代数:39,当前loss为:685.7159423828125
    当前代数:40,当前loss为:685.2298583984375
    当前代数:41,当前loss为:684.5957641601562
    当前代数:42,当前loss为:695.6959228515625
    当前代数:43,当前loss为:427.000732421875
    当前代数:44,当前loss为:682.4891967773438
    当前代数:45,当前loss为:419.1412048339844
    当前代数:46,当前loss为:681.0149536132812
    当前代数:47,当前loss为:694.716552734375
    当前代数:48,当前loss为:406.95831298828125
    当前代数:49,当前loss为:678.7310180664062
    当前代数:50,当前loss为:623.3473510742188
    当前代数:51,当前loss为:395.0804443359375
    当前代数:52,当前loss为:693.6585083007812
    当前代数:53,当前loss为:675.7344360351562
    当前代数:54,当前loss为:618.6995239257812
    当前代数:55,当前loss为:616.9414672851562
    当前代数:56,当前loss为:614.5744018554688
    当前代数:57,当前loss为:692.4542236328125
    当前代数:58,当前loss为:609.0692138671875
    当前代数:59,当前loss为:691.904052734375
    当前代数:60,当前loss为:603.1943359375
    当前代数:61,当前loss为:669.9990234375
    当前代数:62,当前loss为:691.0020141601562
    当前代数:63,当前loss为:594.264892578125
    当前代数:64,当前loss为:591.1102294921875
    当前代数:65,当前loss为:666.8950805664062
    当前代数:66,当前loss为:665.9771728515625
    当前代数:67,当前loss为:689.326171875
    当前代数:68,当前loss为:688.93701171875
    当前代数:69,当前loss为:688.5073852539062
    当前代数:70,当前loss为:574.0647583007812
    当前代数:71,当前loss为:661.115234375
    当前代数:72,当前loss为:660.0462036132812
    当前代数:73,当前loss为:566.465576171875
    当前代数:74,当前loss为:360.7765197753906
    当前代数:75,当前loss为:685.8043212890625
    当前代数:76,当前loss为:357.83026123046875
    当前代数:77,当前loss为:556.7740478515625
    当前代数:78,当前loss为:684.478515625
    当前代数:79,当前loss为:683.9954223632812
    当前代数:80,当前loss为:683.468994140625
    当前代数:81,当前loss为:650.9133911132812
    当前代数:82,当前loss为:545.8726806640625
    当前代数:83,当前loss为:543.443359375
    当前代数:84,当前loss为:540.5396118164062
    当前代数:85,当前loss为:342.5977478027344
    当前代数:86,当前loss为:645.627685546875
    当前代数:87,当前loss为:644.410888671875
    当前代数:88,当前loss为:642.9930419921875
    当前代数:89,当前loss为:641.402099609375
    当前代数:90,当前loss为:524.3102416992188
    当前代数:91,当前loss为:521.52880859375
    当前代数:92,当前loss为:518.2946166992188
    当前代数:93,当前loss为:676.001220703125
    当前代数:94,当前loss为:633.2501220703125
    当前代数:95,当前loss为:674.614501953125
    当前代数:96,当前loss为:673.8367919921875
    当前代数:97,当前loss为:628.274169921875
    当前代数:98,当前loss为:626.4828491210938
    当前代数:99,当前loss为:325.72052001953125
    
    展开全文
  • PyTorch学习:动态和静态图

    万次阅读 2018-11-09 15:20:21
    目前神经网络框架分为静态图框架和动态图框架,PyTorch TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 TensorFlow 使用静态图,这意味着我们先定义计算图,然后不断使用它,而在 ...
  • pytorch 动态图与静态图pytorch动态图与静态图动态图初步推导动态图的叶子节点grad_fn静态图 动态图初步推导 计算图是用来描述运算的有向无环图 计算图有两个主要元素:结点(Node)和边(Edge) 结点表示数据 ,如...
  • Pytorch学习(二):动态和静态图

    千次阅读 2019-11-24 21:51:29
    ​ 目前神经网络框架分为静态图框架和动态图框架,PyTorch TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 TensorFlow 使用静态图,这意味着我们先定义计算图,然后不断使用它,而在 ...
  • 静态图动态图    计算图分为静态图和动态图。静态图,顾名思义就是图是确定的,即整个运算过程预先定义好了,然后再次运行的过程中只运算而不再搭建计算图,看起来就是数据在规定的图中流动。动态图,就是计算...
  • 动态和静态图的区别,可以理解为解释执行编译执行的区别,动态图就是原生python编程习惯,而静态图其实是加了编译层,理论上编译的要比解释的快,但实际上有些任务速度区别不大,因为原生python也可以优化的很快...
  • PyTorch之三—动态图

    千次阅读 2019-02-21 19:06:06
    目前神经网络框架分为静态图框架和动态图框架,PyTorch TensorFlow、Caffe 等框架最大的区别就是他们拥有不同的计算图表现形式。 TensorFlow 使用静态图,这意味着我们先定义计算图,然后不断使用它,中间是不...
  • PyTorch系列5 ---动态和静态图

    千次阅读 2019-05-22 10:28:04
    #目前,神经网络框架分为静态图框架和动态图框架,,PyTorch TensorFlow、 Caffe等框架最大的区别就是他们拥有不同的计算图表现形式。 # TensorFlow使用静态图,这意味着我们先定义计算图,,然后不断地使用它。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,159
精华内容 1,663
关键字:

pytorch静态图和动态图