VGG网络模型搭建-Pytorch

【Pytorch】

⭐ vgg

官网vgg学习传送门

vgg特点

堆叠多个3 * 3 卷积核来替代大尺度卷积核 (减少所需的参数)

并且,论文中提出 堆叠 2个 3 * 3 卷积核 可以代替 5 * 5 的卷积核, 3个 3 * 3 卷积核 可代替 7 * 7

说明

我们假设 输入输出的channel数为C :

对于 7 * 7 的卷积核来说,它所需要的参数为: 7 * 7 * C * C = 49C^2

而对于1个 3 * 3 的卷积核来说, 需要的参数为: 3 * 3 * C * C = 9C^2

3个即为: 27C^2 < 49C^2

很显然,所需的参数大大减少!

注意,这边的代替是指 他们具有相同的感受野。

补充

感受野: 卷积神经网络每层输出的特征图上的一个点映射到输入图片的一块区域。

计算:从最后一层开始向上算。 F(i) = (F(i+1) - 1) * Stride + Ksize

F(i) : 第i层的感受野 Stride : 第i层的步距 Ksize :卷积核或采样核的个数

详情可参考这里

vgg模型解析

下图是 vgg模型图

VGG网络模型搭建-Pytorch

vgg16 为例

首先输入是一张 224 * 224 的RGB三通道图片, 经过 两层 3 * 3 卷积层 –> 最大池化 –> 三层 3 * 3 卷积层 –> 最大池化 –> 三层 3 * 3 卷积层 –> 最大池化 –> 3 * 3 卷积层 –> 最大池化 –> 三个全连接层 –> softmax

这里卷积层的stride = 1, padding = 1

最大池化 kernel_size = 2,stride = 2

VGG网络模型搭建-Pytorch

pytorch 实现 vgg搭建

@Time : 2021/11/15
@Author: J1ay
@File : vgg_model.py

import torch
from torch import nn

vgg后面都是经过三个全连接层以及soft-max函数
采用前面参数区分,后面统一构建

class VGG(nn.Module):
    def __init__(self, features, class_num=1000, init_weight=False):
        super(VGG, self).__init__()
        self.features = features
        # 全连接
        self.classifier = nn.Sequential(
            nn.Dropout(),  # 减小过拟合,50%失活神经元
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Linear(4096, class_num)
        )
        if init_weight:
            self._initialize_weights()

    def forward(self, x):
        # 前面模型搭建
        x = self.features(x)
        # 展平操作
        # N * 512 * 7 * 7
        x = torch.flatten(x, start_dim=1)
        # 全连接
        x = self.classifier(x)
        return x

    # 初始化权重函数
    def _initialize_weights(self):
        for m in self.modules:
            # 若是卷积层,则利用xavier进行初始化
            if isinstance(m, nn.Conv2d):
                nn.init.xavier_uniform_(m.weight)
                # 若使用偏置
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0) # 将偏置置为0
            # 若是全连接层
            elif isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                nn.init.constant_(m.bias, 0)

以列表形式记录vgg各个模型的参数
cfgs = {
    'vgg11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'vgg13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'vgg16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'vgg19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M']
}

构建前半部分模型
def make_feature(cfgs):
    layers = []
    in_channels = 3 # 最初输入cannel为3
    for v in cfgs:
        # 最大池化
        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, padding=1)
            layers += [conv2d, nn.ReLU(inplace=True)] # 采用ReLu激活函数
            in_channels = v  # 卷积后,卷积层输入channel变成上一层的channel
    # torch.nn.Sequential(* args) 按顺序添加到容器
    return nn.Sequential(*layers)

实例化vgg
def vgg(model_name="vgg16", **kwargs):
    try:
        cfg = cfgs[model_name]
    except:
        print("Warning: Model {} not in cfs dict!".format(model_name))
        exit(-1)

    model = VGG(make_feature(cfg), **kwargs)
    return model

if __name__ == '__main__':
    # 默认是vgg16,可修改model名字
    vgg_model = vgg(model_name="vgg13")
    print(vgg_model)

Original: https://www.cnblogs.com/Jlay/p/pytorch_vgg.html
Author: J1ay
Title: VGG网络模型搭建-Pytorch

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574156/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球