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')

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

相关推荐
合方圆~小文15 小时前
不同画面,三个镜头实时监控拍摄方案
数据结构·数据库·人工智能
lx74160269815 小时前
change clip架构学习
人工智能·学习·计算机视觉
玄微云15 小时前
AI智能体开发公司推荐:玄微科技专注垂直场景的实践者
大数据·人工智能·软件需求
谷粒.16 小时前
测试数据管理难题的7种破解方案
运维·开发语言·网络·人工智能·python
一RTOS一16 小时前
“智”赋百业 | 东土科技:为工业人工智能铸造“中国根系”
人工智能·科技
周周爱喝粥呀16 小时前
向量检索:AI 是如何进行语义匹配的?
人工智能
深蓝电商API16 小时前
爬虫+大模型结合:让AI自动写XPath和清洗规则
人工智能·爬虫
WebGoC开发者16 小时前
【备赛指导】佛山市青少年科技创新大赛暨佛山市青少年人工智能科创节 智趣AI竞技赛 流程详解
人工智能·经验分享·科技·ai·青少年科技竞赛
大千AI助手16 小时前
模糊集合理论:从Zadeh奠基到现代智能系统融合
人工智能·机器学习·集合·模糊理论·大千ai助手·模糊集合·fuzzysets
数据门徒16 小时前
《人工智能现代方法(第4版)》 第7章 逻辑智能体 学习笔记
人工智能·笔记·学习