03-01-模型创建步骤与nn.Module.mp4

torch nn 是pytorch的神经网络模块
子模块:

nn.Module最重要的两个属性:

基于LeNet观察nn.module的创建(RMB2)


class LeNet(nn.Module):
#LeNet继承于nn.Module
def __init__(self, classes):
#初始化属性
super(LeNet, self).__init__()
#super实现父类函数调用功能
步入nn.Module的__init__()初始化,可以看到LeNet调用了nn.Module一系列有序字典的初始化,其中
self.training = True 表示模型的训练模式


以上就构建好了一个Module的基本属性
可以看到已经初始化完毕

接下来,构建子模块

第一个网络层是Conv2d的卷积层,步入
class Conv2d(_ConvNd):
Conv2d继承于ConvNd类
进入到了ConvNd类的初始化

可以看到调用super进入到了ConvNd的父类
class _ConvNd(Module):
可知Conv2d其实是一个Module

先实现ConvNd的初始化
接着调用super进入到ConvNd的父类Module

又到了module的init初始化属性(毕竟conv2d也和LeNet一样,也是一个Module)

构建好之后,跳出之后查看,LeNet中会记录一个'conv1'网络层,因为'conv1'也是一个Module,所以会记录到modules字典中

既然conv2d也是一个module,故也有初始化的有序字典

接下图

modules没有内容是因为已经没有子module了,而参数parameters存储了权重和偏置这两个可学习参数,parameter类是继承于tensor,所以paramter是一个特殊的张量tensor,所以会包含张量的基本属性
以上就实现了一个子网络层的构建,同时把conv2d存储到了modules当中进行有效的管理
观察LeNet这个module是如何把子module(conv2d)存储到LeNet的有序字典modules当中

如图,当执行一系列操作之后回到lenet.py
只是实现了conv2d的实例化,构建了conv2d网络层,还没赋值给LeNet的类属性conv2当中,可以看到有序字典modules还没有conv2

下一步才是赋值给类属性
在module当中,setattr函数会拦截所有类属性赋值操作,下一步进入setattr函数

其中,name、value的值如下图

用isinstance函数判断是否是parameter类型
若是,赋值给name,并且储存到parameter的有序字典中

value是一个con2d类型,也就是一个module
往下会判断是否是module

判断为True进行赋值

走完所有子网络层,LeNet构建完毕


总结

例如,LeNet是一个大的module,它可以包含很多个子module,如卷积层、池化层、全连接层,都可以包含在LeNet这个大的module当中
一个module接受一个复杂的tensor,进行一系列运算,输出分类概率或者其他的数据,所以要对module进行forward前向传播操作。

