人工智能基础部分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 torchvisiondef 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 outdef VGG16():block_nums = [2, 2, 3, 3, 3]model = VGGNet(block_nums)return modeldef VGG19():block_nums = [2, 2, 4, 4, 4]model = VGGNet(block_nums)return modelif __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 nnclass BasicBlock(nn.Module):expansion = 1def __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 = xout = 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 outclass ResNet(nn.Module):def __init__(self, block, layers, num_classes=1000):super(ResNet, self).__init__()self.in_channels = 64self.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.expansionfor _ 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 xdef 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 nnclass 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 * yclass SEBasicBlock(nn.Module):expansion = 1def __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 = xout = 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 outclass SEResNet(nn.Module):def __init__(self, block, layers, num_classes=1000, reduction=16):super(SEResNet, self).__init__()self.in_channels = 64self.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.expansionfor _ 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 xdef 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 nnclass 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 xclass 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 xif __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是轻量级的模型,适用于资源受限的设备。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【tomcat】java.lang.Exception: Socket bind failed: [730048

项目中一些旧工程运行情况处理 问题 1、启动端口占用 2、打印编码乱码 ʮһ�� 13, 2023 9:33:26 ���� org.apache.coyote.AbstractProtocol init ����: Fa…

基于python人脸性别年龄检测系统-深度学习项目

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介简介技术组成1. OpenCV2. Dlib3. TensorFlow 和 Keras 功能流程 二、功能三、系统四. 总结 一项目简介 # Python 人脸性别年龄检测系统介绍 简介 该系统基…

Android : ListView + BaseAdapter-2简单应用

​​容器与适配器:​​​​​ http://t.csdnimg.cn/ZfAJ7 实体类 News.java package com.example.mylistviewadapter2.entity;public class News {private String title;private String content;private int img;public News(String title, String conte…

Linux中的进程程序替换

Linux中的进程程序替换 1. 替换原理2. 替换函数3. 函数解释4. 命名理解程序替换的意义 1. 替换原理 替换原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的…

智慧法院档案数字化解决方案

智慧法院档案数字化解决方案可以采用以下步骤: 1. 确定数字化目标:明确数字化的目标和范围,比如将所有的案件相关文件、纸质档案和材料进行数字化。 2. 确定数字化流程:制定数字化的流程和标准,比如采用哪些设备和软件…

解决requests库进行爬虫ip请求时遇到的错误的方法

目录 一、超时错误 二、连接错误 三、拒绝服务错误 四、内容编码错误 五、HTTP错误 在利用requests库进行网络爬虫的IP请求时,我们可能会遇到各种错误,如超时、连接错误、拒绝服务等等。这些错误通常是由目标网站的限制、网络问题或我们的爬虫代码中…

docker、elasticsearch8、springboot3集成备忘

目录 一、背景 二、安装docker 三、下载安装elasticsearch 四、下载安装elasticsearch-head 五、springboot集成elasticsearch 一、背景 前两年研究了一段时间elasticsearch,当时也是网上找了很多资料,最后解决个各种问题可以在springboot上运行了…

Java核心知识点整理大全8-笔记

Java核心知识点整理大全7-笔记-CSDN博客文章浏览阅读1.2k次,点赞27次,收藏26次。但是如果锁的竞争激烈,或者持有锁的线程需要长时间占用锁执行同步块,这时候就不适合 使用自旋锁了,因为自旋锁在获取锁前一直都是占用 c…

C语言--判断年月日是否合理

一.题目描述 比如输入2001,2,29,输出: 不合理 。因为平年的二月只有28天 比如输入2000,6,31,输出:不合理。因为6月是小月,只有30天。 二.思路分析 本题主要注意两个问…

优先级队列(priority_queue)

文章目录 优先级队列的定义定义:接口头文件优先队列和堆的关系使用:排序的规则容器 仿函数应用 队列存指针问题: 优先级队列的定义 定义: 黄色部分是仿函数 接口 头文件 这里不需要包含其他的头文件只需要使用队列的头文件就可以…

Mybatis plus 简介

简介 MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 官网:https://baomidou.com/pages/24112f/ 特性 无侵入&…

基于STM32的烟雾浓度检测报警仿真设计(仿真+程序+讲解视频)

这里写目录标题 📑1.主要功能📑2.仿真📑3. 程序📑4. 资料清单&下载链接📑[资料下载链接](https://docs.qq.com/doc/DS0VHTmxmUHBtVGVP) 基于STM32的烟雾浓度检测报警仿真设计(仿真程序讲解) 仿真图prot…