AI课堂第16讲:DL深度学习-PyTorch计算图与模型构造

前面几节我们学习了深度学习模型的基本原理与实现,下面我们继续学习深度学习计算的各个组成部分,为后续学习复杂模型打下基础。

在学习模型构造之前,我们先了解一下什么是计算图。

计算图 (Computational Graph)

计算图是用来描述运算的有向无环图,有两个主要元素:

节点 (Node) :节点表示数据,如向量、矩阵、张量。

(Edge):边表示运算,如加减乘除卷积等。

用计算图表示:y=(x1+w)*(x2+w),如下图所示:


AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

计算图

其中,x1, x2, w, y 分别为节点,+ ,* 为节点之间的操作,即边。故y=a*b,其中a=x1+w, b=x2+w。

计算图与梯度求导

求上图y对w的导数,根据复合函数的求导法则,推理如下:

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

对应到计算图中,就是根节点y到叶子节点w有两条路径y->a->w和y->b->w。根节点依次对每条路径的子节点求导,直到叶子节点w,最后把每条路径的导数相加即可,其实就是我们前面讲过的反向传播求偏导。

总结为y对w求导,就是从计算图中找到所有y到w的路径,然后把各个路径的导数进行求和。

代码演示如下:

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

PyTorch动态计算图演示

计算图又分为静态计算图 (Static Computational Graph)和动态计算图 (Dynamic Computational Graph):

动态图就是运算和搭建同时进行,也就是可以先计算前面的节点的值,再根据这些值搭建后面的计算图。

静态图是先搭建图,然后再输入数据进行运算,是先定义后运行的方式,之后再次运行的时候就不再需要重新构建计算图,所以速度会比动态图更快,但是不灵活。

PyTorch因其动态图的特色吸引了很多使用者,而Tensorflow早期是用的静态图导致开发很不友好,后来也改成了动态图模式。

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

tensorflow静态计算图演示


AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

动态图和静态图对比

模型构造

PyTorch是基于动态图的模型搭建方式,我们可以随机的在网络中添加或者删除网络层。PyTorch为我们提供了非常方便的nn工具箱,我们搭建模型只需要定义一个继承自nn.module的类并实现其init和forward方法就可。

其中nn.Module类是nn模块中提供的一个模型构造类,是所有神经网络模块的基础类。我们需要继承它来定义我们的自己的网络结构。init方法中动态绑定成员变量,定义我们的网络结构和相关参数;forword方法中决定数据流经这些成员变量的顺序,即网络的前向传播方式。

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

PyTorch中nn工具箱的结构示意图

一般来说,我们构建网络模型时用到的卷积层、全连接层、Dropout层等含有可学习参数的层都是继承nn.Module,而激活函数、池化层等函数类型的层继承于nn.functional。

1.继承Module类来构造模型

下面定义的MLP 类中无须定义反向传播函数。系统将通过自动求梯度而自动生成反向传播所需的backward 函数。

我们可以实例化 MLP 类得到模型变量 net 。下的代码初始化 net 并传输数据 X 做次前向计算。其中, net(X) 会调用 MLP 继承 Module 类的 __call__ 函数,这个函数将调用 MLP 类定义的forward 函数来完成前向计算。

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

继承Module类的基础模型

这并没有将 Module 类命名为 Layer (层)或者 Model (模型)之类的名字,这是因为该类是一个可供自由组建的部件。它的子类既可以是一个层(如PyTorch提供的 Linear 类),又可以是个模型(如这定义的 MLP 类),或者是模型的一个部分。我们下面来展示它的灵活性。

2.Module的子类

PyTorch还提供了许多继承自Module的类,如:Sequential、ModuleList和ModuleDict等。

2.1Sequential类

当模型的前向计算为简单的串联各个网络层的时候,可以通过Sequential类以更加简单的方式来定义模型。Sequential可以接收一个子模块的有序字典(OrderedDict)或者一系列的子模块作为参数来逐一的添加Module的子类的实例。在前向传播计算的时候,可以将这些实例按照添加的顺序逐一计算,向前传播。这里实现一个MySequential类,其机制和Sequential类似。

举例如下:

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

Sequential类模型

2.2 ModuleList类

ModuleList类接收一个子模块的列表作为输入,也可以类似List那样进行append和extend操作。类似于我们建立一个list,list内部中的每一个元素代表一个网络层。

举例如下:

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

ModuleList类模型

ModuleList不同于一般的Python的list,加入到ModuleList里面的所有模块的参数会被自动添加到整个网络中。

2.3 ModuleDict类

ModuleDict类接收一个子模块的字典作为输入,然后按照类似于字典的形式进行添加访问操作,举例如下:

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

ModuleDict类模型

ModuleDict和ModuleList类似的是,ModuleDict实例仅仅是存放了一些模块的字典,并没有定义forward函数,前向传播的方式需要我们自己定义。同样,ModuleDict也与Python的Dict有所不同,ModuleDict里的所有模块的参数会被自动添加到整个网络结构的内部。

3.构造复杂的模型

上面介绍的Sequential使用简单,但灵活性不足。通常我们还是自定义类,继承nn.Module,去完成更复杂的模型定义和控制。下面的我们尝试构建一个复杂点的网络来总结上面的内容,该网络中包含不被迭代的参数,即常数参数,还多次调用相同的层。

AI课堂第16讲:DL深度学习——PyTorch计算图与模型构造

复杂模型构建

总结

PyTorch是基于动态图的模型搭建方式。

Module类是PyTorch中所有神经网络模块的基类,也是个可供自由构建的模块。它的子类既可以是个层(如PyTorch提供的 Linear 类),又可以是一个模型(如这里是定义的 MLP 类),或者是模型的一个部分。

Sequential、ModuleList、ModuleDict类都继承自Module类。

Sequential内的模块需要按照顺序排列,要保证相邻层的输入输出大小相匹配,内部forward功能已经实现。与Sequential不同,ModuleList和ModuleDict并没有定义一个完整的网络,它们只是将不同的模块存放在一起,这些模块之间没有联系也没有顺序(所以不用保证相邻层的输入输出维度匹配),需要自己定义forward函数。

虽然Sequential等类可以使模型构造更加简单,但直接继承Module类可以极大地拓展模型构造的灵活性。

展开阅读全文

页面更新:2024-04-14

标签:求导   模型   子类   节点   静态   函数   模块   深度   课堂   定义   参数   网络

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top