Pytorch源码学习之二:torchvision.models.vgg

0. VGG的网络结构

VGG网络结构

一、torchvision源码

这种通过配置文件一次性搭建相似网络的结构的方法十分值得学习和模仿.这也是相对于AlexNet的实现过程不同之处.
我对其做了一丁点修改,源码网址可见torchvision.models.vgg源码网址

'''
VGG的torchvison实现重写,
'''
import torch
import torch.nn as nn
try:
    from torch.hub import load_state_dict_from_url
except ImportError:
    from torch.utils.model_zoo import load_url as load_state_dict_from_url

__all__ = [
    'VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn',
    'vgg19_bn', 'vgg19',
]
model_urls = {
    'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth',
    'vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth',
    'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth',
    'vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth',
    'vgg11_bn': 'https://download.pytorch.org/models/vgg11_bn-6002323d.pth',
    'vgg13_bn': 'https://download.pytorch.org/models/vgg13_bn-abd245e5.pth',
    'vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth',
    'vgg19_bn': 'https://download.pytorch.org/models/vgg19_bn-c79401a0.pth',
}

class VGG(nn.Module):

    def __init__(self, features, num_classes=1000, init_weights=True):
        super(VGG, self).__init__()
        self.features = features
        self.init_weights= init_weights
        self.avgpool = nn.AdaptiveAvgPool2d((7,7))
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )
        if self.init_weights:
            self._initialize_weights()

        def forward(self, x):
            x = self.features(x)
            x = torch.avgpool(x)
            x = torch.flatten(x, start_dim=1)
            x = self.classifier(x)
            return x

        def _initialize_weights(self):
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, model='fan_out',
                                            nonlinearity='relu')
                    if m.bias is not None:
                        nn.init.constant_(m.bias, 0)
                    elif isinstance(m, nn.BatchNorm1d):
                        nn.init.constant_(m.weight, 1)
                        nn.init.constant_(m.bias, 0)
                    elif isinstance(m, nn.Linear):
                        nn.init.normal_(m.weight, 0, 0.01)
                        nn.init.constant_(m.bias, 0)

def make_layer(cfg, batch_norm=False):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels=in_channels, out_channels=v, kernel_size=3, stride=1, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
        in_channels = v
    return nn.Sequential(*layers)
cfgs = {
    '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'],
    'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
    }

def _vgg(arch, cfg, batch_norm, pretrained, progress, **kwargs):
    '''
    搭建vgg网络
    :param arch:网络名称,用来加载预训练模型
    :param cfg: 配置,用来搭建网络
    :param batch_norm: bool,是否采用BN
    :param pretrained: bool,是否采用Pretrained
    :param progress: bool,下载时是否显示进度条
    :param kwargs:其它参数
    :return:返回搭建的vgg网络
    '''
    if pretrained:
        kwargs['init_weights']  = False
    model = VGG(make_layer(cfg[cfg], batch_norm=batch_norm), **kwargs)
    if pretrained:
        state_dict = load_state_dict_from_url(model_urls[arch],
                                              progress=progress)
        model.load_state_dict(state_dict)
    return model

def vgg11(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg11', 'A', False, pretrained, progress, **kwargs)

def vgg11_bn(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg11_bn', 'A', True, pretrained, progress, **kwargs)

def vgg13(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg13', 'B', False, pretrained, progress, **kwargs)

def vgg13_bn(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg13_bn', 'B', True, pretrained, progress, **kwargs)

def vgg16(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg16', 'D', False, pretrained, progress, **kwargs)

def vgg16_bn(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg16_bn', 'D', True, pretrained, progress)

def vgg19(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg19', 'E', False, pretrained, progress, **kwargs)

def vgg19_bn(pretrained=False, progress=True, **kwargs):

    return _vgg('vgg19_bn', 'E', pretrained, progress, **kwargs)

二、一些值得学习的用法笔记

 #将start_dim至end_dim展成一维向量
torch.flatten(tenor, start_dim, end_dim)
x = torch.flatten(x, start_dim=1)
#效果同下
x = x.view(x.size(0), -1)
#使用何大佬在2015年提出的方法
torch.nn.init.kaiming_normal_(tensor, a=0, 
                          model='fan_in', nonlinearity='leaky_relu')
nn.init.kaiming_normal_(m.weight, model='fan_out',
                                            nonlinearity='relu')
#使用均值为mean,标准差为std的正态分布填充输入tensor
torch.nn.init.normal_(tensor, mean=0., std=1.) 
#使用浮点数val填充tensor
nn.init.constant_(tensor, val) 
#搭建网络的一种范式
layer = []
layer += [nn.Conv2d(...), nn.ReLU(inplace=True)]
layer += [nn.BatchNorm2d(...)]
nn.Sequential(*layers)
#从网络上加载参数
torch.hub.load_state_dict_from_url(url,  model_dir=None, map_location=None, progress=True)
#url-下载的目标网址
#model_dir - 保存参数的目录
#map_location - a function or a dict specifying how to remap storeage locations.
state_dict = load_state_dict_from_url(model_urls[arch],
                                              progress=progress)
#progress - 是否展示下载的进度条
#载入参数到模型
#torch.nn.modules.module.Module
#def load_state_dict(self, state_dict, strict=True)
model.load_state_dict(state_dict)
#*args 和 **kwargs都代表1个或多个参数的意思.*args传入tuple类型的无名参数,而**kwargs传入的参数是dict类型
def myprint(*args):
    print(*args)
myprint(10, 2) #10 2

def mykwprint(**kwargs):
    key = kwargs.keys()
    value = kwargs.values()
    print(key) #dict_keys(['epoch', 'LR'])
    print(value) #dict_values([10, 2])
mykwprint(epoch=10, LR=2)
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
torchvision.modelsPyTorch中用于图像分类的模型库。它提供了许多预训练的深度学习模型,包括AlexNet、VGG、ResNet等,以及它们的各种变种。这些模型经过在大规模图像数据上的预训练,并在各种图像分类任务上展示出了很好的性能。 torchvision.models源码主要包括两部分:网络结构定义和预训练模型参数加载。 首先,torchvision.models中定义了各种经典的深度学习网络结构。这些网络结构通过继承自torch.nn.Module类来实现,其中包括了网络的前向传播过程和可训练参数的定义。例如,在ResNet模型中,torchvision.models定义了ResNet类,其中包含多个残差块,每个残差块由多个卷积层和恒等映射组成。而在VGG模型中,torchvision.models定义了VGG类,其中包含多个卷积层和全连接层。这些定义好的网络结构可以用于构建和训练图像分类模型。 其次,torchvision.models还提供了预训练模型参数的加载功能。这些预训练模型参数可以通过调用torchvision.models的load_state_dict方法加载到网络结构中。这些参数在大规模图像数据集上进行了预训练,并且经过了反向传播过程进行了优化,因此可以作为初始化参数来训练新的图像分类模型。通过加载预训练模型参数,可以帮助新模型更快地收敛和获得更好的性能。 总之,torchvision.models是一个方便使用的图像分类模型库,提供了各种经典的深度学习网络结构和预训练的模型参数。通过使用这些网络结构和加载预训练模型参数,可以更轻松地构建和训练图像分类模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值