【图像分类】理论篇(2)经典卷积神经网络 Lenet~Resenet

news2024/11/18 21:40:50

目录

1、卷积运算

2、经典卷积神经网络

2.1 Lenet

网络构架

代码实现

2.2 Alexnet

网络构架

代码实现

2.3 VGG

VGG16网络构架

代码实现

2.4 ResNet

ResNet50网络构架

代码实现

1、卷积运算

 在二维卷积运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。 当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值。 在如上例子中,输出张量的四个元素由二维互相关运算得到,这个输出高度为2、宽度为2,如下所示:

import torch
from torch import nn

def Conv2d(X, K):  
    """计算二维卷积运算"""
    h, w = K.shape
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
    return Y

2、经典卷积神经网络

2.1 Lenet

网络构架:

代码实现:

import torch
import torch.nn as nn

class LeNet(nn.Module):
    def __init__(self, num_classes=10):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
        self.pool1 = nn.MaxPool2d(kernel_size=2)
        self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
        self.pool2 = nn.MaxPool2d(kernel_size=2)
        self.fc1 = nn.Linear(in_features=16*5*5, out_features=120)
        self.fc2 = nn.Linear(in_features=120, out_features=84)
        self.fc3 = nn.Linear(in_features=84, out_features=num_classes)

    def forward(self, x):
        x = self.pool1(torch.relu(self.conv1(x)))
        x = self.pool2(torch.relu(self.conv2(x)))
        x = x.view(-1, 16*5*5)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 创建LeNet模型
model = LeNet(num_classes=10)
print(model)

LeNet实现适用于MNIST数据集,其中输入图像大小为28x28,输出类别数为10(0-9的手写数字)。

2.2 Alexnet

网络构架:

 

代码实现:

import torch
import torch.nn as nn

class AlexNet(nn.Module):
    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

# 创建AlexNet模型
model = AlexNet(num_classes=1000)
print(model)

代码中的AlexNet实现适用于ImageNet数据集,其中输入图像大小为224x224,输出类别数为1000。

2.3 VGG

VGG16网络构架:

代码实现:

import torch
import torch.nn as nn

class VGG16(nn.Module):
    def __init__(self, num_classes=1000):
        super(VGG16, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

# 创建VGG16模型
model = VGG16(num_classes=1000)
print(model)

代码中的VGG16实现适用于ImageNet数据集,其中输入图像大小为224x224,输出类别数为1000。

2.4 ResNet

ResNet50网络构架:

代码实现:

import torch
import torch.nn as nn

# 定义残差块
class ResidualBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(ResidualBlock, 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)
        
        if stride != 1 or in_channels != out_channels:
            self.downsample = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels)
            )
        else:
            self.downsample = None
        
    def forward(self, x):
        identity = x
        
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        
        x = self.conv2(x)
        x = self.bn2(x)
        
        if self.downsample is not None:
            identity = self.downsample(identity)
            
        x += identity
        x = self.relu(x)
        
        return x

# 定义ResNet-50
class ResNet50(nn.Module):
    def __init__(self, num_classes=1000):
        super(ResNet50, 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(64, 3, stride=1)
        self.layer2 = self._make_layer(128, 4, stride=2)
        self.layer3 = self._make_layer(256, 6, stride=2)
        self.layer4 = self._make_layer(512, 3, stride=2)
        
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512 * 4, num_classes)
        
    def _make_layer(self, out_channels, num_blocks, stride):
        layers = []
        layers.append(ResidualBlock(self.in_channels, out_channels, stride))
        self.in_channels = out_channels
        for _ in range(1, num_blocks):
            layers.append(ResidualBlock(out_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 = x.view(x.size(0), -1)
        x = self.fc(x)
        
        return x

# 创建ResNet-50模型
model = ResNet50(num_classes=1000)
print(model)

代码中的ResNet50实现适用于ImageNet数据集,其中输入图像大小为224x224,输出类别数为1000。

【图像分类】 理论篇(1) 图像分类的测评指标_TechMasterPlus的博客-CSDN博客

【图像分类】理论篇(3)交叉熵损失函数的理解与代码实现_TechMasterPlus的博客-CSDN博客

【图像分类】理论篇(4)图像增强opencv实现_TechMasterPlus的博客-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python系统学习1-9-类三之特征

一、封装 数据角度:将一些基本数据类型复合成一个自定义类型。 优势:将数据与对数据的操作相关联。 代码可读性更高(类是对象的模板)。 行为角度:向类外提供必要的功能,隐藏实现的细节。 优势&#xff…

工具推荐:Chat2DB一款开源免费的多数据库客户端工具

文章首发地址 Chat2DB是一款开源免费的多数据库客户端工具,适用于Windows和Mac操作系统,可在本地安装使用,也可以部署到服务器端并通过Web页面进行访问。 相较于传统的数据库客户端软件如Navicat、DBeaver,Chat2DB具备了与AIGC…

第58步 深度学习图像识别:Transformer可视化(Pytorch)

一、写在前面 (1)pytorch_grad_cam库 这一期补上基于基于Transformer框架可视化的教程和代码,使用的是pytorch_grad_cam库,以Bottleneck Transformer模型为例。 (2)算法分类 pytorch_grad_cam库中包含的…

在变暖的北极,冰冻的河岸可能会被更快地侵蚀

冷冻水槽实验揭示了多年冻土河岸侵蚀对水温、河岸粗糙度和孔隙冰含量的敏感性。 阿拉斯加胡斯利亚社区附近科尤库克河沿岸 1.5 米高的河岸照片。河流横向侵蚀永久冻土层,使冻土和沉积物暴露在相对温暖的水和气温下,导致其解冻。这张银行暴露显示了一层棕…

python入门知识:分支结构

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 1.内容导图 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python资料、视频教程、代码、插件安装教程等我都准备好了,直接在文末名片自…

MsrayPlus多功能搜索引擎采集软件

MsrayPlus多功能搜索引擎采集软件 摘要: 本文介绍了一款多功能搜索引擎软件-MsrayPlus,该软件能够根据关键词从搜索引擎中检索相关数据,并提供搜索引擎任务、爬虫引擎任务和联系信息采集三大功能。我们将分析该软件在不同领域的应用&#xf…

【实战】十一、看板页面及任务组页面开发(二) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十四)

文章目录 一、项目起航:项目初始化与配置二、React 与 Hook 应用:实现项目列表三、TS 应用:JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

Scratch 游戏 之 随机大地图生成教程

在很多生存 / 沙盒类游戏中,地图往往是随机生成的,例如:饥荒、我的世界等。那我们该如何在scratch中实现这一点呢? 在scratch中有两种办法可以实现——画笔和克隆体。我们这次先聊克隆体。 我们可以先将克隆体设置为方形的&#x…

快解析内网穿透便捷访问内网私有云

快解析内网穿透软件的首要优势在于其不改变企业现有IT架构的特点。传统的内网穿透解决方案常常需要对企业网络进行重构,这不仅增加了工作量,还可能带来不稳定的因素。而快解析则巧妙地绕过了这一问题,让您能够在保持原有网络设备和配置的前提…

【Unity每日一记】Physics.Raycast 相关_Unity中的“X光射线”

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

spss---如何使用信度分析以及案例分析

信度分析 问卷调查法是教育研究中广泛采用的一种调查方法,根据调查目的设计的调查问卷是问卷调查法获取信息的工具,其质量高低对调查结果的真实性、适用性等具有决定性的作用。 为了保证问卷具有较高的可靠性和有效性,在形成正式问卷之 前&…

Python基础知识:类的属性查找教程

目录标题 前言正文尾语 前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 正文 有需要python源码/安装包/教程/电子书/资料等 点击此处跳转文末名片免费获取 先从对象自己的名称空间找,没有则取类里找,如果类里也没有则程序报错 class Student1:# …

JS中对象数组深拷贝方法

structuredClone() JavaScript 中提供了一个原生 API 来执行对象的深拷贝:structuredClone。它可以通过结构化克隆算法创建一个给定值的深拷贝,并且还可以传输原始值的可转移对象。 当对象中存在循环引用时,仍然可以通过 structuredClone()…

【Hibench 】完成 HDP-Spark 性能测试

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的…

0基础学习VR全景平台篇 第87篇:智慧眼-公告有什么作用?

一、功能说明 公告,即政府、团体对有关事件或者行动发布的通告。公告内容由管理员在后台添加,智慧眼成员在场景中添加热点时可以选择引用此公告,引用后会在热点详情页中展示。 二、后台编辑界面 点击【新增】,填写公告的标题和…

[Raspberry Pi]如何用VNC遠端控制樹莓派(Ubuntu desktop 23.04)?

之前曾利用VMware探索CentOS,熟悉Linux操作系統的指令和配置運作方式,後來在樹莓派價格飛漲的時期,遇到貴人贈送Raspberry Pi 4 model B / 8GB,這下工具到位了,索性跳過樹莓派官方系統(Raspberry Pi OS),直…

牛客OJ题 打印日期

⭐️ 题目描述 🌟 OJ链接:https://www.nowcoder.com/practice/b1f7a77416194fd3abd63737cdfcf82b?tpId69&&tqId29669&rp1&ru/activity/oj&qru/ta/hust-kaoyan/question-ranking 思路: 默认从一月的天数开始&#xff0c…

一键批量修改文件夹名称,中文瞬间变日语,轻松搞定重命名

大家好!现在为了更好地适应全球化发展,许多人都有了海外交流、旅行、学习的需求。但是难免遇到一个问题:在电脑中的中文文件夹名称如何快速翻译成日语? 首先,第一步,我们需要打开文件批量改名,…

编译老版本c++程序 报错 msvcrt.dll 以及 0x000000 内存 不能为 “read“ 问题 已解决

一般 win10 编译 xp对应老版本软件 调试采用 虚拟机形式进行测试,但是虚拟机中,无独立显卡,运行程序提示有,无法调用动态库,或者 内存无法读取,炸一看以为 winxp32位 内存识别只能3.7G.其实是显存无法使用…

【C++】STL---list

STL---list 一、list 的介绍二、list 的模拟实现1. list 节点类2. list 迭代器类(1)前置(2)后置(3)前置- -、后置- -(4)! 和 运算符重载(5)* 解引用重载 和 …