VGGNet的结构和复现

本文探讨了VGGNet架构(如VGG16D、VGG19等)中模型退化的问题,主要关注深度增加带来的抽象特征提取、梯度消失/爆炸和过拟合风险。通过代码实现,介绍了如何复现不同层次的VGGNet结构及其影响。
摘要由CSDN通过智能技术生成

1 结构以及模型退化问题

上述为VGGNet的结构图,左边是VGG16D的步骤 16代表16层,有参数的层,其他结构也是如此

对于这6个机构来说,D中的VGG16是最优的,而VGG19相比较而言,没有VGG16优,VGG16有16层(包括13个卷积层和3个全连接层),而VGG19有19层(包括16个卷积层和3个全连接层),对于出现了的模型退化问题,有几个原因:

1 网络层次越深,提取的特征越是高度抽象,这可以帮助模型理解复杂的、高级的模式。然而,如果网络过深,最后几层可能会从数据中提取过于抽象的特征,与具体的输入图像的关联性减弱,导致模型性能降低

2 在非常深的网络中,梯度在反向传播过程中可能会因为多层传递而变得非常小(梯度消失)或非常大(梯度爆炸),这会使得网络难以训练

3 更深的网络通常有更多的参数,这可能会使模型更容易发生过拟合,特别是当训练数据有限时

等等一些原因

2 代码复现(6种结构的复现)

只是简单的复现

import torch.nn as nn
import torch

class VggBlock(nn.Module):
    
    def __init__(self, in_channel, out_channel, n, use_11 = False, LRN = False) -> None:
        super().__init__()
        layers = []
        for i in range(n):
            if use_11 and (i == n-1):
                kernel_size = (1, 1)
                padding = 0    
            else:
                kernel_size = (3, 3)
                padding = 1

            conv = nn.Sequential(
                nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, stride=1, padding=padding),
                nn.ReLU()
            )
            layers.append(conv)
            in_channel = out_channel
        if LRN == True:
            layers.append(nn.LocalResponseNorm(size=5))
        layers.append(nn.MaxPool2d(2))
        self.block = nn.Sequential(*layers)
    
    def forward(self, x):
        return self.block(x)



class VGGNet(nn.Module):
    
    def __init__(self, num_classes, features, classify_input_channel) -> None:
        super().__init__()
        self.num_classes = num_classes
        self.features = features
        self.pooling = nn.AdaptiveMaxPool2d(7)
        self.classify = nn.Sequential(
            nn.Linear(in_features=7 * 7 * classify_input_channel, out_features=4096),
            nn.ReLU(),
            nn.Linear(in_features=4096, out_features=4096),
            nn.ReLU(),
            nn.Linear(in_features=4096, out_features=self.num_classes),
        )

    def forward(self, images):
        z = self.features(images)
        z = self.pooling(z)
        z = z.flatten(1)
        return self.classify(z) 
    

class VGGNet11A(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 1),
            VggBlock(64, 128, 1),
            VggBlock(128, 256, 2),
            VggBlock(256, 512, 2),
            VggBlock(512, 512, 2)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)
    

class VGGNet11ALRN(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 1, LRN=True),
            VggBlock(64, 128, 1),
            VggBlock(128, 256, 2),
            VggBlock(256, 512, 2),
            VggBlock(512, 512, 2)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)


class VGGNet13B(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 2),
            VggBlock(64, 128, 2),
            VggBlock(128, 256, 2),
            VggBlock(256, 512, 2),
            VggBlock(512, 512, 2)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)
    

class VGGNet16C(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 2),
            VggBlock(64, 128, 2),
            VggBlock(128, 256, 3, use_11=True),
            VggBlock(256, 512, 3, use_11=True),
            VggBlock(512, 512, 3, use_11=True)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)
    

class VGGNet16C(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 2),
            VggBlock(64, 128, 2),
            VggBlock(128, 256, 3),
            VggBlock(256, 512, 3),
            VggBlock(512, 512, 3)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)
    

class VGGNet16C(nn.Module):

    def __init__(self, num_classes) -> None:
        super().__init__()
        features = nn.Sequential(
            VggBlock(3, 64, 2),
            VggBlock(64, 128, 2),
            VggBlock(128, 256, 4),
            VggBlock(256, 512, 4),
            VggBlock(512, 512, 4)
        )
        self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)

    def forward(self, images):
        return self.vggnet(images)
    

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值