您当前的位置:首页 > IT编程 > python
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:浅谈Pytorch 定义的网络结构层能否重复使用

51自学网 2021-10-30 22:34:47
  python
这篇教程浅谈Pytorch 定义的网络结构层能否重复使用写得很实用,希望能帮到您。

前言:最近在构建网络的时候,有一些层参数一样,于是就没有定义新的层,直接重复使用了原来已经有的层,发现效果和模型大小都没有什么变化,心中产生了疑问:定义的网络结构层能否重复使用?因此接下来利用了一个小模型网络实验了一下。

一、网络结构一:(连续使用相同的层)

1、网络结构如下所示:

class Cnn(nn.Module):    def __init__(self):        super(Cnn, self).__init__()        self.conv1 = nn.Sequential(          nn.Conv2d(            in_channels = 3,  #(, 64, 64, 3)            out_channels = 16,            kernel_size = 3,            stride = 1,            padding = 1          ),   ##( , 64, 64, 16)          nn.ReLU(),          nn.MaxPool2d(kernel_size = 2)        )  ##( , 32, 32, 16)        self.conv2 = nn.Sequential(          nn.Conv2d(16,32,3,1,1),          nn.ReLU(),          nn.MaxPool2d(2)        )        self.conv3 = nn.Sequential(          nn.Conv2d(32,64,3,1,1),          nn.ReLU(),          nn.MaxPool2d(2)        )        self.conv4 = nn.Sequential(          nn.Conv2d(64,64,3,1,1),          nn.BatchNorm2d(64),          nn.ReLU(),        )        self.out = nn.Linear(64*8*8, 6)    def forward(self, x):        x = self.conv1(x)        x = self.conv2(x)        x = self.conv3(x)        x = self.conv4(x)        x = x.view(x.size(0),-1)        out = self.out(x)        return out

定义了一个卷积层conv4,接下来围绕着这个conv4做一些变化。打印一下网络结构:

和想象中的一样,其中

nn.BatchNorm2d # 对应上面的 module.conv4.1.*

激活层没有参数所以直接跳过

2、改变一下forward():

连续使用两个conv4层:

def forward(self, x):        x = self.conv1(x)        x = self.conv2(x)        x = self.conv3(x)        x = self.conv4(x)        x = self.conv4(x)        x = x.view(x.size(0),-1)        out = self.out(x)        return out

打印网络结构:

和1.1中的结构一样,conv4没有生效。

二、网络结构二:(间断使用相同的层)

网络结构多定义一个和conv4一样的层conv5,同时间断使用conv4:

    self.conv4 = nn.Sequential(      nn.Conv2d(64,64,3,1,1),      nn.BatchNorm2d(64),      nn.ReLU(),    )    self.conv5 = nn.Sequential(      nn.Conv2d(64,64,3,1,1),      nn.BatchNorm2d(64),      nn.ReLU(),    )    self.out = nn.Linear(64*8*8, 6)def forward(self, x):    x = self.conv1(x)    x = self.conv2(x)    x = self.conv3(x)    x = self.conv4(x)    x = self.conv5(x)    x = self.conv4(x)    x = x.view(x.size(0),-1)    out = self.out(x)    return out

打印网络结构:

果不其然,新定义的conv5有效,conv4还是没有生效。

本来以为,使用重复定义的层会像conv4.0,conv4.1,…这样下去,看样子是不能重复使用定义的层。

Pytorch_5.7 使用重复元素的网络--VGG

5.7.1 VGG块

VGG引入了Block的概念 作为模型的基础模块

import timeimport torchfrom torch import nn, optimimport pytorch_deep as pyddevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')def vgg_block(num_convs, in_channels, out_channels):    blk = []    for i in range(num_convs):        if i == 0:            blk.append(nn.Conv2d(in_channels, out_channels,kernel_size=3, padding=1))        else:            blk.append(nn.Conv2d(out_channels, out_channels,kernel_size=3, padding=1))        blk.append(nn.ReLU())    blk.append(nn.MaxPool2d(kernel_size=2, stride=2)) # 这⾥会使宽⾼减半    return nn.Sequential(*blk)

实现VGG_11网络

8个卷积层和3个全连接

def vgg_11(conv_arch, fc_features, fc_hidden_units=4096):    net = nn.Sequential()    # 卷积层部分    for i, (num_convs, in_channels, out_channels) in enumerate(conv_arch):        # 每经过⼀个vgg_block都会使宽⾼减半        net.add_module("vgg_block_" + str(i+1),vgg_block(num_convs, in_channels, out_channels))    # 全连接层部分    net.add_module("fc", nn.Sequential(                    pyd.FlattenLayer(),                    nn.Linear(fc_features,fc_hidden_units),                    nn.ReLU(),                    nn.Dropout(0.5),                    nn.Linear(fc_hidden_units,fc_hidden_units),                    nn.ReLU(),                    nn.Dropout(0.5),                    nn.Linear(fc_hidden_units, 10)                    ))    return net
ratio = 8small_conv_arch = [(1, 1, 64//ratio), (1, 64//ratio, 128//ratio),(2, 128//ratio, 256//ratio),(2, 256//ratio, 512//ratio), (2, 512//ratio,512//ratio)]fc_features = 512 * 7 * 7 # c *fc_hidden_units = 4096 # 任意net = vgg_11(small_conv_arch, fc_features // ratio, fc_hidden_units //ratio)print(net)
Sequential(  (vgg_block_1): Sequential(    (0): Conv2d(1, 8, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (1): ReLU()    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)  )  (vgg_block_2): Sequential(    (0): Conv2d(8, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (1): ReLU()    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)  )  (vgg_block_3): Sequential(    (0): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (1): ReLU()    (2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (3): ReLU()    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)  )  (vgg_block_4): Sequential(    (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (1): ReLU()    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (3): ReLU()    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)  )  (vgg_block_5): Sequential(    (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (1): ReLU()    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))    (3): ReLU()    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)  )  (fc): Sequential(    (0): FlattenLayer()    (1): Linear(in_features=3136, out_features=512, bias=True)    (2): ReLU()    (3): Dropout(p=0.5)    (4): Linear(in_features=512, out_features=512, bias=True)    (5): ReLU()    (6): Dropout(p=0.5)    (7): Linear(in_features=512, out_features=10, bias=True)  ))

训练数据

batch_size = 32# 如出现“out of memory”的报错信息,可减⼩batch_size或resizetrain_iter, test_iter = pyd.load_data_fashion_mnist(batch_size,resize=224)lr, num_epochs = 0.001, 5optimizer = torch.optim.Adam(net.parameters(), lr=lr)pyd.train_ch5(net, train_iter, test_iter, batch_size, optimizer,device, num_epochs)
training on  cudaepoch 1, loss 0.5166, train acc 0.810, test acc 0.872,time 57.6 secepoch 2, loss 0.1557, train acc 0.887, test acc 0.902,time 57.9 secepoch 3, loss 0.0916, train acc 0.900, test acc 0.907,time 57.7 secepoch 4, loss 0.0609, train acc 0.912, test acc 0.915,time 57.6 secepoch 5, loss 0.0449, train acc 0.919, test acc 0.914,time 57.4 sec

以上为个人经验,希望能给大家一个参考,也希望大家多多支持51zixue.net。


教你如何使用Python快速爬取需要的数据
PyQt5中QTimer定时器的实例代码
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。