【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块

nn.Module

【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块

调试

【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
1、以LeNet为例,我们在第72行设置断点,并进行Debug。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
2、点击C按钮,我们进入到LeNet,可以发现LeNet是继承于nn.Module的,所以LeNet是一个module,代码super(LeNet, self).init()实现父类函数调用的功能,父类为nn.Mudule,所以它会调用nn.Module的__init__()函数。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
3、点击C按钮进入该行代码,观察__init__()的函数操作,我们可以发现__init__()实现了8个有序字典的初始化。self.training表示我们模型的训练状态。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
4、点击E按钮,我们返回到LeNet模型类当中,我们构建好了一个module的基本属性,可以发现LeNet中有了8个有序字典。

【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
5、接下来构建子模块,点击B按钮再点击C按钮,进入nn.Conv2d卷积层,我们可以发现我们跳转到了conv.py文件中的Conv2d类中,而Conv2d继承于_ConvNd类。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
6、根据第330行代码我们知道Conv2d调用了父类的__init__()函数,因此我们运行至332行查看_ConvNd都有什么操作。由下图可以看出来,Conv2d继承于_ConvNd,而_ConvNd继承于Module,所以Conv2d还是一个Module,所以Conv2d会调用Module的__init__()函数,所以Conv2d会构建8个有序的字典。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
7、返回至步骤2的文件中,点击B按钮向下运行,这样我们的第一个网络层self.conv1就初始化完毕。,由于self.conv1属于Module,因此它会记载在LeNet的module中,key=conv1, value=Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))。由于Conv2d是Module,因此Conv2d有8个有序字典。由于卷积层没有子网络,因此conv1的_modules为空,但是_parameters存储了卷积层包含的可学习参数:权值和bias。Parameter类继承于张量,所以这些可学习参数为张量。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
8、接下来我们通过构建第二个网络层来观察,Module是如何将子module存储到_modules字典中的。点击B按钮,进入__init__()函数,然后点击E按钮退出。到这里我们发现我们的_modules还没有conv2这个属性,这是因为我们刚刚只是实现了等号右边的实例化,还未赋值到LeNet类属性conv2中,只是构建了这个网络层,下一步才是赋值到conv2中,因为再Module中有个机制会拦截所有的类属性赋值操作,所以它还会跳转到下一个函数。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
9、接下来我们继续点击B按钮,程序跳转到module.py的__setattr__()函数,它的功能为拦截所有类属性的赋值。运行至594行,他会对我们的value和name进行一个类型判断,先判断是否为Parameter,若为Parameter则会存储到Parameter这个有序字典中。此时value为一个Conv2d,所以它是一个Module。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
10、运行至608行,程序会进行一个Module的判断,由于是Module所以他会把value存到_modules中,命名为类属性conv2。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
11、点击E按钮进行返回,此时我们的LeNet的_modules中就有了conv2。后面以此类推。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
12、继续点击E按钮,返回主程序,此时net中的_modules中就有了我们刚刚构建的子模块,_parameters为空,这是因为LeNet进行属性赋值时,并由构建Parameter类。

【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
在conv1中的_paramters存放了可学习的参数weight和bias
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块
以上为nn.Module属性构建的机制。
【深度之眼】Pytorch框架班第五期-通过调试了解nn.Module模块