人工智能基础部分22-几种卷积神经网络结构的介绍,并用pytorch框架搭建模型

大家好,我是微学AI,今天给大家介绍一下人工智能基础部分22-几种卷积神经网络结构的介绍,本篇文章我将给大家详细介绍VGG16、VGG19、ResNet、SENet、MobileNet这几个卷积神经网络结构,以及pytorch搭建代码,利用通用数据输入到模型中。这些模型都是计算机视觉领域中非常重要和广泛应用的模型。

1. VGG16和VGG19模型

VGG(Visual Geometry Group)是由牛津大学的研究团队提出的深度卷积神经网络模型。VGG16和VGG19是两个版本,数字表示网络中的层数。这两个模型的结构非常相似,只是层数不同。它们都由卷积层、池化层和全连接层组成。

VGG模型的基本组成单元是3x3的卷积核和2x2的最大池化层。这种简单而重复的结构使得网络更加深层,有助于提取更具层次的特征。VGG模型的原理是通过堆叠多个卷积层和池化层来构建深度网络,最后通过全连接层进行分类。

VGG模型在图像分类任务中表现出色,尤其在大规模图像数据集上取得了很好的效果。然而,由于网络深度较大,参数量较大,计算资源要求较高。
在这里插入图片描述

pytorch搭建VGG16和VGG19:

import torch
import torch.nn as nn
import torchvision

def Conv3x3BNReLU(in_channels,out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=3,stride=1,padding=1),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )

class VGGNet(nn.Module):
    def __init__(self, block_nums,num_classes=1000):
        super(VGGNet, self).__init__()

        self.stage1 = self._make_layers(in_channels=3, out_channels=64, block_num=block_nums[0])
        self.stage2 = self._make_layers(in_channels=64, out_channels=128, block_num=block_nums[1])
        self.stage3 = self._make_layers(in_channels=128, out_channels=256, block_num=block_nums[2])
        self.stage4 = self._make_layers(in_channels=256, out_channels=512, block_num=block_nums[3])
        self.stage5 = self._make_layers(in_channels=512, out_channels=512, block_num=block_nums[4])

        self.classifier = nn.Sequential(
            nn.Linear(in_features=512*7*7,out_features=4096),
            nn.Dropout(p=0.2),
            nn.Linear(in_features=4096, out_features=4096),
            nn.Dropout(p=0.2),
            nn.Linear(in_features=4096, out_features=num_classes)
        )

        self._init_params()

    def _make_layers(self, in_channels, out_channels, block_num):
        layers = []
        layers.append(Conv3x3BNReLU(in_channels,out_channels))
        for i in range(1,block_num):
            layers.append(Conv3x3BNReLU(out_channels,out_channels))
        layers.append(nn.MaxPool2d(kernel_size=2,stride=2, ceil_mode=False))
        return nn.Sequential(*layers)

    def _init_params(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        x = self.stage1(x)
        x = self.stage2(x)
        x = self.stage3(x)
        x = self.stage4(x)
        x = self.stage5(x)
        x = x.view(x.size(0),-1)
        out = self.classifier(x)
        return out

def VGG16():
    block_nums = [2, 2, 3, 3, 3]
    model = VGGNet(block_nums)
    return model

def VGG19():
    block_nums = [2, 2, 4, 4, 4]
    model = VGGNet(block_nums)
    return model

if __name__ == '__main__':
    model = VGG16()
    print(model)

    input = torch.randn(1,3,224,224)
    out = model(input)
    print(out.shape)

2. ResNet模型

ResNet(Residual Network)是由何恺明提出的一种深度残差网络模型。ResNet的核心思想是引入了残差连接(shortcut connection)来解决深层网络中的梯度消失和梯度爆炸问题。

ResNet的基本结构是由多个残差块(residual block)组成,每个残差块中包含两个或三个卷积层。在残差块中,输入通过跳过一部分卷积层直接与输出相加,形成了残差连接。这样的设计可以让网络学习到残差部分,使得梯度能够更好地传播,有助于训练更深的网络。

ResNet在解决深层网络中的梯度问题方面取得了显著的突破,使得网络可以更深层次地进行训练。ResNet被广泛应用于图像分类、目标检测和图像分割等任务。
在这里插入图片描述

pytorch搭建ResNet:

import torch
import torch.nn as nn

class BasicBlock(nn.Module):
    expansion = 1
    def __init__(self, in_channels, out_channels, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)

        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != self.expansion*out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, self.expansion*out_channels, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(self.expansion*out_channels)
            )

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        out += self.shortcut(residual)
        out = self.relu(out)

        return out


class ResNet(nn.Module):
    def __init__(self, block, layers, num_classes=1000):
        super(ResNet, self).__init__()
        self.in_channels = 64

        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 = self._make_layer(block, 64, layers[0], stride=1)
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512*block.expansion, num_classes)

    def _make_layer(self, block, out_channels, blocks, stride=1):
        layers = []
        layers.append(block(self.in_channels, out_channels, stride))
        self.in_channels = out_channels * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.in_channels, out_channels))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)

        return x


def resnet50(num_classes=1000):
    return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes)

def resnet101(num_classes=1000):
    return ResNet(BasicBlock, [3, 4, 23, 3], num_classes=num_classes)

def resnet152(num_classes=1000):
    return ResNet(BasicBlock, [3, 8, 36, 3], num_classes=num_classes)

if __name__ == '__main__':
    model = resnet152(num_classes=20)
    print(model)

    input = torch.randn(1,3,224,224)
    out = model(input)
    print(out.shape)

3. SENet模型

SENet(Squeeze-and-Excitation Network)是由华为Noah’s Ark实验室提出的一种注意力机制网络模型。SENet的核心思想是通过自适应地调整通道间的特征重要性来提升网络的表达能力。

SENet的基本结构是在卷积层后添加了一个Squeeze-and-Excitation模块。该模块通过全局平均池化操作来获取通道间的特征关系,然后使用两个全连接层来学习通道的权重。最后,通过乘法操作将学习到的权重应用于输入特征图,以增强有用的特征并抑制无用的特征。

SENet在许多图像识别任务中取得了显著的性能提升,尤其是在参数相对较少的情况下。它能够自适应地学习通道间的特征关系,使得网络更加注重重要的特征,抑制冗余和噪声信息。
在这里插入图片描述

pytorch搭建SENet

import torch
import torch.nn as nn

class SELayer(nn.Module):
    def __init__(self, in_channels, reduction=16):
        super(SELayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(in_channels, in_channels // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(in_channels // reduction, in_channels, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y


class SEBasicBlock(nn.Module):
    expansion = 1

    def __init__(self, in_channels, out_channels, stride=1, reduction=16):
        super(SEBasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)
        self.se = SELayer(out_channels, reduction)

        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != self.expansion*out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, self.expansion*out_channels, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(self.expansion*out_channels)
            )

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        out = self.se(out)
        out += self.shortcut(residual)
        out = self.relu(out)

        return out


class SEResNet(nn.Module):
    def __init__(self, block, layers, num_classes=1000, reduction=16):
        super(SEResNet, self).__init__()
        self.in_channels = 64

        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 = self._make_layer(block, 64, layers[0], stride=1, reduction=reduction)
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2, reduction=reduction)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2, reduction=reduction)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2, reduction=reduction)

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512*block.expansion, num_classes)

    def _make_layer(self, block, out_channels, blocks, stride=1, reduction=16):
        layers = []
        layers.append(block(self.in_channels, out_channels, stride, reduction=reduction))
        self.in_channels = out_channels * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.in_channels, out_channels, reduction=reduction))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)

        return x


def se_resnet50(num_classes=1000, reduction=16):
    return SEResNet(SEBasicBlock, [3, 4, 6, 3], num_classes=num_classes, reduction=reduction)

def se_resnet101(num_classes=1000, reduction=16):
    return SEResNet(SEBasicBlock, [3, 4, 23, 3], num_classes=num_classes, reduction=reduction)

def se_resnet152(num_classes=1000, reduction=16):
    return SEResNet(SEBasicBlock, [3, 8, 36, 3], num_classes=num_classes, reduction=reduction)


if __name__ == '__main__':
    model = se_resnet152(num_classes=20)
    print(model)

    input = torch.randn(1,3,224,224)
    out = model(input)
    print(out.shape)

4. MobileNet模型

MobileNet是由Google提出的一种轻量级卷积神经网络模型,旨在在计算资源有限的设备上实现高效的图像识别。MobileNet的核心思想是使用深度可分离卷积(depthwise separable convolution)来减少计算量和参数量。

MobileNet的基本结构是由深度可分离卷积层和1x1卷积层组成。深度可分离卷积将标准卷积分解为深度卷积和逐点卷积,先对每个输入通道进行独立的空间卷积,然后使用1x1卷积进行通道间的线性组合。这种操作能够显著减少计算量和参数量,同时保持较好的准确性。

MobileNet在移动设备上具有轻量级和高效性能的优势,适用于图像分类、物体检测和图像分割等任务。它可以在资源受限的环境下实现实时的图像处理和分析。
在这里插入图片描述

pytorch搭建 MobileNet

import torch
import torch.nn as nn

class DepthwiseSeparableConv(nn.Module):
    def __init__(self, in_channels, out_channels, stride):
        super(DepthwiseSeparableConv, self).__init__()
        self.depthwise = nn.Sequential(
            nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=stride, padding=1, groups=in_channels, bias=False),
            nn.BatchNorm2d(in_channels),
            nn.ReLU(inplace=True)
        )
        self.pointwise = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        x = self.depthwise(x)
        x = self.pointwise(x)
        return x


class MobileNet(nn.Module):
    def __init__(self, num_classes=1000):
        super(MobileNet, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(32),
            nn.ReLU(inplace=True),
            DepthwiseSeparableConv(32, 64, stride=1),
            DepthwiseSeparableConv(64, 128, stride=2),
            DepthwiseSeparableConv(128, 128, stride=1),
            DepthwiseSeparableConv(128, 256, stride=2),
            DepthwiseSeparableConv(256, 256, stride=1),
            DepthwiseSeparableConv(256, 512, stride=2),
            DepthwiseSeparableConv(512, 512, stride=1),
            DepthwiseSeparableConv(512, 512, stride=1),
            DepthwiseSeparableConv(512, 512, stride=1),
            DepthwiseSeparableConv(512, 512, stride=1),
            DepthwiseSeparableConv(512, 512, stride=1),
            DepthwiseSeparableConv(512, 1024, stride=2),
            DepthwiseSeparableConv(1024, 1024, stride=1),
            nn.AdaptiveAvgPool2d(1)
        )
        self.fc = nn.Linear(1024, num_classes)

    def forward(self, x):
        x = self.model(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)
        return x


if __name__ == '__main__':
    model = MobileNet(num_classes=20)
    print(model)

    input = torch.randn(1,3,224,224)
    out = model(input)
    print(out.shape)

总结:

VGG16和VGG19是经典的深度卷积神经网络模型,适用于图像分类任务。ResNet通过引入残差连接解决了深层网络的梯度问题,SENet通过注意力机制提升了网络的表达能力。MobileNet是轻量级的模型,适用于资源受限的设备。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/179782.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript编程基础 – 对象

JavaScript编程基础 – 对象 JavaScript Programming Essentials – Object 本文简要介绍JavaScript面向对象编程,如何实现其中的对象以及实例演示,希望对大家学习JavaScript有所帮助。 1. 面向对象编程特点 面向对象编程(Object-Oriented Programmi…

阿里云服务器ECS产品知识及购买和使用常见问题及答案汇总

本文总结了阿里云用户在购买和使用阿里云服务器中的一些常见的问题,包括什么是云服务器ECS,特性与优势,应用场景,基本概念,使用限制等众多问题,让您全方位了解阿里云服务器,并根据自己的需求选择…

在ASP.NET Core 中使用 .NET Aspire 消息传递组件

前言 云原生应用程序通常需要可扩展的消息传递解决方案,以提供消息队列、主题和订阅等功能。.NET Aspire 组件简化了连接到各种消息传递提供程序(例如 Azure 服务总线)的过程。在本教程中,小编将为大家介绍如何创建一个 ASP.NET …

Lora学习资料汇总

目录 LoRa联盟 Semtech lora网关供应商: LoRaMAC API文档 论坛 开发板 主流技术对比分析 LoRa网络距离模拟测试方法 LoRa应用 LoRa联盟 LoRa联盟:LoRaWAN规范的制定组织 https://www.lora-alliance.org/ LoRa技术白皮书:https://www.lora-alli…

vue2指令的使用和自定义指令

前言 个人认为vue的指令,对比react来说,给开发者节省了很大的学习成本。比如在react中,你想渲染一个列表,需要用Array.map的方法return<div>,而在vue中,一个简单的v-for就解决了问题。 在学习成本和入手体验上,vue的作者确实后来者居上,能让人更快的使用vue开发。不过也…

【unity实战】如何更加规范的创建各种Rogue-Lite(肉鸽)风格的物品和BUFF效果(附项目源码)

文章目录 前言定义基类实现不同的BUFF效果一、回血BUFF1. 简单的回血效果实现2. BUFF层数控制回血量 二、攻击附带火焰伤害三、治疗领域1. 简单的治疗领域实现2. 添加技能冷却时间 通过拾取物品获取对应的BUFF参考源码完结 前言 当创建各种Rogue-Lite&#xff08;肉鸽&#xf…

接口传参数list的时候,items里面放个​​​​​​​list

item里面放个list 先定义一个 list&#xff0c;循环add加入参数

xorm源码学习

文章目录 XORM源码浅析及实践ORMORM vs. SQLXORM软件架构 ORM 引擎 Engine——DBM*core.DB Golang&#xff1a;database/sql 源码基本结构连接复用&#xff0c;提高性能。增加数据库连接池数量连接管理 database/sql主要内容&#xff1a;sql.DB创建数据库连接sql.Open()DB.conn…

状态设计模式是什么?什么是 State 状态设计模式?Python 状态设计模式示例代码

什么是 State 状态设计模式&#xff1f; 状态设计模式是一种行为型设计模式&#xff0c;它允许一个对象在其内部状态发生改变时改变其行为&#xff0c;使其看起来好像改变了其类。状态模式主要解决的问题是&#xff1a;当一个对象的行为取决于它的状态&#xff0c;并且在运行时…

2023年亚太地区数学建模大赛

中国新能源电动汽车的发展趋势 新能源汽车是指采用先进的技术原理、新技术和新结构&#xff0c;以非常规车用燃料&#xff08;非常规车用燃料是指汽油和柴油以外的燃料&#xff09;为动力源&#xff0c;集成先进的汽车动力控制和驱动技术的汽车。新能源汽车包括四大类型&#…

人工智能带来的各方面影响

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术在各个领域中的应用越来越广泛&#xff0c;已经开始对我们的生活方式、社会和经济结构产生深远的影响。 1.人工智能家庭化。人工智能技术使我们的生活变得更加便利和智能化。在家庭日常中&#xff0c;智能家居、智能…

WPF绘图使用介绍

文章目录 WPF绘图基本用法绘制直线在XAML中绘制直线在C#代码中绘制直线使用Path绘制直线注意 矩形绘制在XAML中绘制矩形在C#代码中绘制矩形设置矩形的位置使用圆角矩形 画刷1. SolidColorBrush2. LinearGradientBrush3. RadialGradientBrush4. ImageBrush5. DrawingBrush6. Vis…

FDG6306P PowerTrench® MOSFET P沟道 特点及其应用详解

关于PowerTrench MOSFET&#xff1f; 它是一种MOS场效应晶体管&#xff0c;可以提高系统效率和功率密度。该技术采用了屏蔽栅极技术&#xff0c;可以减少开关损耗和导通损耗&#xff0c;从而提高了系统效率。此外&#xff0c;PowerTrench MOSFET还具有低导通电阻和高开关速度的…

Python---函数的应用案例(多个)涉及函数、字符串翻转修改

案例&#xff1a;使用print方法打印一条横线 下面是最原始的方法&#xff1a; print(- * 40) 案例&#xff1a;对上个案例进行升级&#xff0c;可以根据输入的num数值&#xff0c;生成指定数量的横线 相关链接Python----range方法&#xff08;函数&#xff09;-CSDN博客 Pyt…

现代计算与光学的跨界机遇——

时至今日&#xff0c;互补氧化金属半导体&#xff08;CMOS&#xff09;技术的飞速发展促进了集成电路的空前成功。 晶体管的创新与时俱进 正如戈登-E-摩尔&#xff08;Gordon E. Moors&#xff09;在1965年预测的那样&#xff0c;每隔18-24个月&#xff0c;计算芯片上的晶体管数…

手把手教你通过CODESYS V3进行PLC编程(二)

教程背景 在上一期教程中&#xff0c;我们已经完成了控制器设备的连接和配置。接下来的教程将继续以宏集MC-Prime为例&#xff0c;假设控制器已经配置并连接到开发者的PC上&#xff0c;为您演示如何为控制器安装合适的CODESYS V3版本并创建第一个程序。 一、安装CODESYS &…

TikTok青年领袖:短视频如何塑造新一代

在数字时代的潮流中&#xff0c;短视频平台TikTok崭露头角&#xff0c;成为年轻一代最喜爱的社交媒体之一。这个平台不仅改变了用户的娱乐方式&#xff0c;更在其中催生了一批富有创造力和影响力的青年领袖。 本文将深入探讨TikTok如何通过短视频内容塑造新一代的青年领袖&…

Modbus转Profinet改变局面,PLC与电力仪表秒级响应

Modbus转Profinet改变了传统的局面&#xff0c;实现了PLC与电力仪表之间的秒级响应。在过去&#xff0c;由于Modbus通信协议的限制&#xff0c;PLC与电力仪表之间的数据传输速度受到了很大的限制&#xff0c;无法满足工业自动化领域对实时性的要求。然而&#xff0c;随着Modbus…

加班做报表被嘲低效!快用大数据分析工具

做数据分析报表很耗时间&#xff0c;因为不仅要解决多业务系统数据质量标准不一问题&#xff0c;还需要进行大量的公式计算、报表设计与制作。但那是以前&#xff0c;在大数据分析工具强势崛起的当下&#xff0c;这些工作都能交给大数据分析工具来做了。以前是花90%的时间做报表…

快慢指针判断环形链表

我们在前面文章中写过用快慢指针判断链表是否带环&#xff1a; leetcode&#xff1a;环形链表-CSDN博客 我们用的是slow指针一次走一步&#xff0c;fast指针一次走两步&#xff0c;当slow入环后开始了追击&#xff0c;每走一次距离缩短1&#xff0c;最终就会相遇 思考问题 …