PyTorch入门实战教程笔记(二十一):卷积神经网络CNN 3

PyTorch入门实战教程笔记(二十一):卷积神经网络CNN 3

nn.Module

nn.Module在pytorch中使用的非常广泛,它是所有网络层次类的父类,即实现自己的层必须要继承这个类,对于现有的层,比如线性层、卷积层等等,也是继承这个类。如果要实现自己的类,也必须尊重这个规则,继承与nn.Module,在初始化(init)里面完成 自己要定义的逻辑,在forward()里面完成一个计算图的前向构建的过程。
在这里插入图片描述
nn.Module 在pytorch中是一个基本的父类,可以直接使用一些现成的类,比如nn.Linear,nn.BctchNorm2d,nn.Conv2d.等等。此外,还可以嵌套nn.Module。那么使用nn.Module有什么好处呢。

  1. embed current layers,提供了大量的现成的神经网络的计算模块,使用这些层直接调用初始化函数,然后在调用 .call方法类调用他的forward()函数,就可使用这些层的功能。
    在这里插入图片描述
  2. Container,容器,nn.Sequential(), 假设网络有152层,是不是要写152个变量,且在forward()中使用152个这样的串联的操作,但是对于常见的网络堆叠而成的话,我们使用nn.Sequential()容器,就意味着x从第0个元素开始处理forward(),处理到最后一个元素会得到一个输出。在这里面,不止可以调用自己写的,也不止可调用pytorch提供的,也可以调用自己的,比如MyLinear() (只要是继承自nn.Module),调用self.net(x), 就自动的完成了这样类的forward操作。**注:**只有类才能写到Sequential里,比如nn.ReLU是一个类,F.relu是一个函数,所以nn.ReLU可以写进去,而F.relu不可以写进去。
    在这里插入图片描述
  3. parameters,网络内部参数管理,比如我们使用Sequential(),将连个Linear容在一起,就能够调用nn.parameters()返回一个生成器,在转换成list,就能转换成每一个参数作为一个元素的list,打印[0]的shape为[2,4],刚好设置的前一个Linear(4,2) (因为这的w是先out后in,刚好相反),打印[3]的shape为[2],刚好是后一个Linear(2,2)的偏置。因此我们继承了nn.Module后,不需要管理额外的参数,只需要调用nn.parameters(),就可以返回这个参数。我们使用net.named_parameters(),可以返回参数的命名(pytorch自动命名的),属性,具体数据等。并且可以用nn.parameters()将参数传入到优化器里面去。
    在这里插入图片描述
  4. modules,对内部的module也非常方便管理,也就是可以父类module、子类module、子类的子类module继承,对于所有的节点加在一起为modules,我们看以下演示:
    对于父节点Net,里面包含nn.Sequential,在nn.Sequential又包含了BasicNet、ReLU、Linear(3,2)。BasicNet里面又包含了Linear(4,3)。所以这个父类Net,一共5个children,所有的module,包含Net为0号,Sequential为1号,BasicNet为2号,ReLU为3号,Linear(3,2)为4号,Linear(4,3)为5号。因为只有BasicNet和Linear(3,2)有参数,可以看到下图右边的观察结果。
    在这里插入图片描述
    可以看一下下图更为详细的module的关系:
    在这里插入图片描述
  5. to(device) 可以非常方便的把一个类的所有的操作转移到CPU或者cuda上。
    在这里插入图片描述
  6. save and load 能够非常方便的使用pytorch的一个加载ckpt.mdl和保存ckpt.mdl,这里指的是一个中间状态,为什么呢,比如AlexNet还要training 6天,如果中间断电或者系统崩溃了,那是不是意味着training要重新开始?所以我们每隔一个小时,每隔一天保存一下这个ckpt.mdl。保存的话,我们使用net.state_dict(),把当前的类所有状态返回,再通过torch.save把它保存到一个文件里。保存以后,我们在模型开始的时候检查是否有模型的保存,如果保存的话,我们使用torch.load(‘ckpt.dml’)加载成一个pytorch的类,然后使用net.load_state_dict(), 把这个数据加载加载到这个model的参数里面去,即网络参数的值每一个都初始化为已经train差不多的这个值,这样就不需要重新从0开始train。
    在这里插入图片描述
  7. train/test前面说过,对于如Dropout或BatchNorm等来说,它的train和test的行为是不一样的,因此我们需要对每一个nn.module的状态进行切换,这是非常不方便的。如果所有的类都继承与nn.module,那么我们调用net.train(), 这样子一行代码就能完成train状态的切换。同样,使用net.eval(),一行代码切换至test状态。
    在这里插入图片描述
  8. implement own layer 实现我们自己的层操作,就比如说使用非常多的展平功能(pytorch中没有),为什么需要呢,conv2d得到的是一个二维的操作,比如[b, 256, 3, 3],你要大平成[b, 25633],才能送到线性层中去对不对?因此,这个打平的操作,如果没有这类的话没需要吧nn.Sequential断开,在forward里面,调用一次nn.Sequential_1,在用view打平,再用一次nn.Sequential_2,比较麻烦。如果我们这功能继承于nn.Module,那直接在一个Sequential里就能实现上述功能,对吧。对于Flatten类,初始化参数不需要接收任何参数的,因此他默认是吧第一个维度保留下来(input.size(0)保存第一个维度),把其余的维度全部打平(-1的作用)。
    在这里插入图片描述
    下面我们自己实现一类,如下图,首先我们定义一个w和b的参数,因为它们是需要梯度信息的,但是我们并没有设置这个参数,反而把这个tensor传给了另外一个类的初始化,nn.Parameter(),原因是我们在初始化里面,定义一些torch.tensor,是不会加载到net.parameter中去的,如果不会自动加载到这里面去,我们就不能得到这个参数,更不能很好的优化这个参数,pytorch提供的nn.Parameter(),包装以后,定义的tensor就会自动的加载到模型的net.parameter中去,就能通过SGD等优化器优化。然后在forward()函数里面定义前向图的计算,再返回,一定要注意要返回,那么自定义的MyLinear就自动实现啦
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值