VGG16神经网络搭建

一、定义提取特征网络结构

将要实现的神经网络参数存放在列表中,方便使用。

数字代表卷积核的个数,字符代表池化层的结构

python 复制代码
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'],
}

二、 定义提取特征网络

如果遍历过程中 v== 'M',就是定义池化层,后面的卷积核与stride步距都是网络的默认参数。

数字代表的就是定义卷积层,然后与激活函数链接在一起。

最后返回时,以非关键字参数的形式传入。

python 复制代码
def make_features(cfg: list):
    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, v, kernel_size=3, padding=1)
            layers += [conv2d, nn.ReLU(True)]
            in_channels = v
    return nn.Sequential(*layers)

三、初始化网络

传入参数features,class_num,是否需要初始化权重。

定义分类网络结构,dropout方法缓解过拟合问题,再全连接核relu激活函数链接起来。

如果需要初始化权重,那么就会进入初始化权重的函数中。

python 复制代码
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(p=0.5),
            nn.Linear(512*7*7, 2048),
            nn.ReLU(True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(True),
            nn.Linear(2048, class_num)
        )
        if init_weight:
            self._initialize_weights()

四、初始化权重函数

这个函数会遍历网络的每一个子模块。

如果遍历的当前层是一个卷积层,那么这个方法会初始化卷积核的权重,如果采用了偏置,那就默认初始化为0.

如果遍历的当前层是全连接层,也是用这个方法去初始化全连接层的权重,并将偏置设置为0.

python 复制代码
    def _initialize_weights(self):
        for m in self.modules():  # 遍历模块中的每一个子模块
            if isinstance(m, nn.Conv2d):
                nn.init.xavier_uniform_(m.weight)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                nn.init.constant_(m.bias, 0)

五、定义正向传播

x:输入的图像数据

features:提取网络特征结构

flatten:展平处理。因为第0个维度是batch,所以我们从第一个维度开始展平

经过分类网络结构后返回

python 复制代码
    def forword(self, x):
        x = self.features(x)
        x = torch.flatten(x, strat_dim=1)
        x = self.classifier(x)
        return x

六、实例化模型

传入参数model_name:实例化给定的配置模型。

将key值传入字典当中

通过VGG这个类来实例化这个网络

features通过make_features这个函数来实现

最后创建对象实现VGG神经网络的搭建。

python 复制代码
def vgg(model_name="vgg16", **kwargs):
    try:
        cfg = cfgs[model_name]
    except:
        print("waring: model number {} not in cfgs dict".format(model_name))
    model = VGG(make_features(cfg), **kwargs)
    return  model

vgg_model = vgg(model_name='vgg13')

运行成功,网络搭建成功。

全部代码

python 复制代码
import torch.nn as nn
import torch


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(p=0.5),
            nn.Linear(512*7*7, 2048),
            nn.ReLU(True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(True),
            nn.Linear(2048, class_num)
        )
        if init_weight:
            self._initialize_weights()

    def forword(self, x):
        x = self.features(x)
        x = torch.flatten(x, strat_dim=1)
        x = self.classifier(x)
        return x


    def _initialize_weights(self):
        for m in self.modules():  # 遍历模块中的每一个子模块
            if isinstance(m, nn.Conv2d):
                nn.init.xavier_uniform_(m.weight)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                nn.init.constant_(m.bias, 0)



def make_features(cfg: list):
    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, v, kernel_size=3, padding=1)
            layers += [conv2d, nn.ReLU(True)]
            in_channels = v
    return nn.Sequential(*layers)


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 vgg(model_name="vgg16", **kwargs):
    try:
        cfg = cfgs[model_name]
    except:
        print("waring: model number {} not in cfgs dict".format(model_name))
    model = VGG(make_features(cfg), **kwargs)
    return  model

vgg_model = vgg(model_name='vgg13')

全部代码与分开模块的顺序不同,但不影响最终实现。

相关推荐
欧阳码农43 分钟前
盘点这两年我接触过的副业赚钱赛道,对于你来说可能是信息差
前端·人工智能·后端
CoovallyAIHub1 小时前
突破跨模态识别瓶颈!火箭军工程大学提出MFENet:让AI在白天黑夜都能准确识人
深度学习·算法·计算机视觉
CoovallyAIHub1 小时前
TypeScript超越Python,以66%增速跃升第一,Python稳居AI领域王座
深度学习·算法·计算机视觉
亚马逊云开发者1 小时前
Agentic AI基础设施实践经验系列(七):可观测性在Agent应用的挑战与实践
人工智能
cwh_rs_giser1 小时前
如何高效设置机器学习超参数?——借鉴成熟AutoML框架的实践
人工智能·python·机器学习
逻极1 小时前
Scikit-learn 入门指南:从零到一掌握机器学习经典库(2025 最新版)
人工智能·python·机器学习·ai·scikit-learn·agent
草莓熊Lotso1 小时前
C++ 抽象类与多态原理深度解析:从纯虚函数到虚表机制(附高频面试题)
java·运维·服务器·开发语言·c++·人工智能·笔记
XINVRY-FPGA1 小时前
5CEFA9F23I7N Altera CycloneV E(Enhanced)FPGA
人工智能·嵌入式硬件·计算机视觉·fpga开发·硬件工程·dsp开发·fpga
Wayfreem2 小时前
Spring AI Alibaba 学习之最简单的快速入门
人工智能·学习·spring
shayudiandian2 小时前
图像分类深度学习
人工智能