(四)Pytorch经典网络实现

前言

前面三节内容主要讲解了Pytorch的基础运算操作,如何去加载数据,还有神经网络训练过程的归纳,这一章主要是去实现一些经典的神经网络,包括Alexnet、VGG、googlenet、ResNet、mobilenet、xception,当然,Pytorch中已经定义好了这些网络,实际项目中,完全可以通过迁移学习的方式,来调用这些模型。

AlexNet

alexnet网络是2012年目标识别比赛的冠军,虽然随着时间的推移,被更多优秀的网络结构超越,但是其思想还是有很多可以借鉴的地方。
Alexnet网络一共有8层,前五层为卷积层,用于提取图像特征,后三层为全接连层,用于对图像进行分类。
该模型的主要特点如下:
1.提出了ReLU激励函数,可以减少梯度消失的风险;
2.池化层用于特征降维
3.局部归一化处理(LRN)

class AlexNet(nn.Module):

    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        return x

VGG

VGG网络是2014年图像识别大赛的第二名,改进了AlexNet网络,缺点是参数太多。
VGG的特点:

  • 小卷积核。作者将卷积核全部替换为3x3(极少用了1x1);

  • 小池化核。相比AlexNet的3x3的池化核,VGG全部为2x2的池化核;

  • 层数更深特征图更宽。基于前两点外,由于卷积核专注于扩大通道数、池化专注于缩小宽和高,使得模型架构上更深更宽的同时,计算量的增加放缓;

  • 全连接转卷积。网络测试阶段将训练阶段的三个全连接替换为三个卷积,测试重用训练时的参数,使得测试得到的全卷积网络因为没有全连接的限制,因而可以接收任意宽或高为的输入。

import torch 
import torch.nn as nn
cfg = {
    'A':[64,     'M', 128,      'M', 256, 256,           'M', 512, 512,           'M', 512, 512,           'M'],
    'B':[64, 64, 'M', 128, 128, 'M', 256, 256,           'M', 512, 512,           'M', 512, 512,           'M'],
    'C':[64, 64, 'M', 128, 128, 'M', 256, 256, 256,      'M', 512, 512, 512,      'M', 512, 512, 512,      'M'],
    'D':[64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M']
}
class VGG(nn.Module):
    def __init__(self,features,num_class=100):
        super().__init__()
        self.features = features
        self.classifier = nn.Sequential(
            nn.Linear(512,4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096,4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096,num_class)
        )
    def forward(self,x):
        output = self.features(x)
        output = output.view(output.size()[0],-1)
        output = self.classifier(output)
        return output

def make_layers(cfg,batch_norm=False):
    layers=[]
    input_channel = 3
    for l in cfg:
        if l == 'M':
            layers += [nn.MaxPool2d(kernel_size=2,stride=2)]
            continue
        layers += [nn.Conv2d(input_channel,l,kernel_size=3,padding=1)]
        if batch_norm:
            layers += [nn.BatchNorm2d(l)]
        layers += [nn.ReLU(inplace=True)]
        input_channel = l
    return nn.Sequential(*layers)

def vgg11_bn():
    return VGG(make_layers(cfg['A'], batch_norm=True))

def vgg13_bn():
    return VGG(make_layers(cfg['B'], batch_norm=True))

def vgg16_bn():
    return VGG(make_layers(cfg['C'], batch_norm=True))

def vgg19_bn():
    return VGG(make_layers(cfg['D'], batch_norm=True))

Googlenet

googlenet是2014年的冠军作品,提出了Inception结构,优化了网络的参数,并且在网络层数加深的情况下,可以抑制梯度消失。
Inceotion结构主要是通过使用1*1卷积核对输入特征进行降维操作,这样一来,参数就得到了下降,通过不同尺度下的特征最后进行融合。googlenet V1 中使用了9个线性堆叠的Inception模块,在不同深度处还引入了两个辅助损失函数,避免梯度回传失败。之后该研究组又推出了V2,V3,V4三个版本的网络。其中V2主要提出了著名的batchnorm,并且将较大尺寸的卷积核通过小卷积核相乘来代替;V3中提出,任意nxn的卷积都可以通过1xn卷积后接nx1卷积来替代。 V4结合了残差神经网络ResNet。

你可能感兴趣的:((四)Pytorch经典网络实现)