深度学习网络模型——ConvNeXt网络详解、ConvNeXt网络训练花分类数据集整体项目实现

news2024/11/17 23:32:45

深度学习网络模型——ConvNeXt网络详解、ConvNeXt网络训练花分类数据集整体项目实现

  • 1、介绍
  • 2、设计方案
  • 3、Macro design
  • 4、ResNeXt-ify
  • 5、Inverted Bottleneck
  • 7、Large Kernel Sizes
  • 8、Micro Design
  • 9、ConvNeXt variants
  • 10、ConvNeXt-T 结构图
  • 11、网络代码实现:

ConvNeXt
论文名称:A ConvNet for the 2020s
论文下载链接:https://arxiv.org/abs/2201.03545

1、介绍

在这里插入图片描述

2、设计方案

在这里插入图片描述

3、Macro design

在这里插入图片描述

4、ResNeXt-ify

在这里插入图片描述

5、Inverted Bottleneck

在这里插入图片描述

7、Large Kernel Sizes

在这里插入图片描述

8、Micro Design

在这里插入图片描述

9、ConvNeXt variants

在这里插入图片描述
在这里插入图片描述

10、ConvNeXt-T 结构图

在这里插入图片描述
在这里插入图片描述

11、网络代码实现:

convnext_tiny
convnext_small
convnext_base
convnext_large
convnext_xlarge

model.py

"""
original code from facebook research:
https://github.com/facebookresearch/ConvNeXt
"""

import torch
import torch.nn as nn
import torch.nn.functional as F


def drop_path(x, drop_prob: float = 0., training: bool = False):
    """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).

    This is the same as the DropConnect impl I created for EfficientNet, etc networks, however,
    the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper...
    See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for
    changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use
    'survival rate' as the argument.

    """
    if drop_prob == 0. or not training:
        return x
    keep_prob = 1 - drop_prob
    shape = (x.shape[0],) + (1,) * (x.ndim - 1)  # work with diff dim tensors, not just 2D ConvNets
    random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)
    random_tensor.floor_()  # binarize
    output = x.div(keep_prob) * random_tensor
    return output


class DropPath(nn.Module):
    """Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).
    """
    def __init__(self, drop_prob=None):
        super(DropPath, self).__init__()
        self.drop_prob = drop_prob

    def forward(self, x):
        return drop_path(x, self.drop_prob, self.training)


class LayerNorm(nn.Module):
    r""" LayerNorm that supports two data formats: channels_last (default) or channels_first.
    The ordering of the dimensions in the inputs. channels_last corresponds to inputs with
    shape (batch_size, height, width, channels) while channels_first corresponds to inputs
    with shape (batch_size, channels, height, width).
    """

    def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(normalized_shape), requires_grad=True)
        self.bias = nn.Parameter(torch.zeros(normalized_shape), requires_grad=True)
        self.eps = eps
        self.data_format = data_format
        if self.data_format not in ["channels_last", "channels_first"]:
            raise ValueError(f"not support data format '{self.data_format}'")
        self.normalized_shape = (normalized_shape,)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        if self.data_format == "channels_last":
            return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps)
        elif self.data_format == "channels_first":
            # [batch_size, channels, height, width]
            mean = x.mean(1, keepdim=True)
            var = (x - mean).pow(2).mean(1, keepdim=True)  # 得到的是方差
            x = (x - mean) / torch.sqrt(var + self.eps)    # 减去均值除以标准差
            x = self.weight[:, None, None] * x + self.bias[:, None, None]
            return x


class Block(nn.Module):
    r""" ConvNeXt Block. There are two equivalent implementations:
    (1) DwConv -> LayerNorm (channels_first) -> 1x1 Conv -> GELU -> 1x1 Conv; all in (N, C, H, W)
    (2) DwConv -> Permute to (N, H, W, C); LayerNorm (channels_last) -> Linear -> GELU -> Linear; Permute back
    We use (2) as we find it slightly faster in PyTorch

    Args:
        dim (int): Number of input channels.
        drop_rate (float): Stochastic depth rate. Default: 0.0
        layer_scale_init_value (float): Init value for Layer Scale. Default: 1e-6.
    """
    def __init__(self, dim, drop_rate=0., layer_scale_init_value=1e-6):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim)  # depthwise conv  此处使用的是depthwise卷积
        self.norm = LayerNorm(dim, eps=1e-6, data_format="channels_last")
        self.pwconv1 = nn.Linear(dim, 4 * dim)  # pointwise/1x1 convs, implemented with linear layers  此处使用的是全连接层,代替1x1的卷积层,效果一样
        self.act = nn.GELU()
        self.pwconv2 = nn.Linear(4 * dim, dim)
        # 定义layer scale层的scale因子
        self.gamma = nn.Parameter(layer_scale_init_value * torch.ones((dim,)),
                                  requires_grad=True) if layer_scale_init_value > 0 else None   # 其元素的个数与输入特征层channel的个数是一样的
        self.drop_path = DropPath(drop_rate) if drop_rate > 0. else nn.Identity()

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        shortcut = x
        x = self.dwconv(x)
        x = x.permute(0, 2, 3, 1)  # [N, C, H, W] -> [N, H, W, C]
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.pwconv2(x)
        if self.gamma is not None:
            x = self.gamma * x    # 对每个通道的数据进行缩放
        x = x.permute(0, 3, 1, 2)  # [N, H, W, C] -> [N, C, H, W]

        x = shortcut + self.drop_path(x)
        return x


class ConvNeXt(nn.Module):
    r""" ConvNeXt
        A PyTorch impl of : `A ConvNet for the 2020s`  -
          https://arxiv.org/pdf/2201.03545.pdf
    Args:
        in_chans (int): Number of input image channels. Default: 3
        num_classes (int): Number of classes for classification head. Default: 1000
        depths (tuple(int)): Number of blocks at each stage. Default: [3, 3, 9, 3]
        dims (int): Feature dimension at each stage. Default: [96, 192, 384, 768]
        drop_path_rate (float): Stochastic depth rate. Default: 0.
        layer_scale_init_value (float): Init value for Layer Scale. Default: 1e-6.
        head_init_scale (float): Init scaling value for classifier weights and biases. Default: 1.
    """
    def __init__(self, in_chans: int = 3, num_classes: int = 1000, depths: list = None,
                 dims: list = None, drop_path_rate: float = 0., layer_scale_init_value: float = 1e-6,
                 head_init_scale: float = 1.):
        super().__init__()
        self.downsample_layers = nn.ModuleList()  # stem and 3 intermediate downsampling conv layers   #  最初的下采样部分
        stem = nn.Sequential(nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4),
                             LayerNorm(dims[0], eps=1e-6, data_format="channels_first"))
        self.downsample_layers.append(stem)

        # 对应stage2-stage4前的3个downsample
        for i in range(3):
            downsample_layer = nn.Sequential(LayerNorm(dims[i], eps=1e-6, data_format="channels_first"),
                                             nn.Conv2d(dims[i], dims[i+1], kernel_size=2, stride=2))
            self.downsample_layers.append(downsample_layer)

        self.stages = nn.ModuleList()  # 4 feature resolution stages, each consisting of multiple blocks
        dp_rates = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))]  # 即表示每一个block会使用一个dropPathRate,并且其是递增的
        cur = 0
        # 构建每个stage中堆叠的block
        for i in range(4):
            stage = nn.Sequential(
                *[Block(dim=dims[i], drop_rate=dp_rates[cur + j], layer_scale_init_value=layer_scale_init_value)
                  for j in range(depths[i])]
            )
            self.stages.append(stage)
            cur += depths[i]

        self.norm = nn.LayerNorm(dims[-1], eps=1e-6)  # final norm layer
        self.head = nn.Linear(dims[-1], num_classes)
        self.apply(self._init_weights)   # 调用父类的方法,初始化各层参数
        self.head.weight.data.mul_(head_init_scale)  # 对self.head层的weight乘上一个因子,此处因为为1,表示不进行任何缩放
        self.head.bias.data.mul_(head_init_scale)    #  对self.head层的bias乘上一个因子,此处因为为1,表示不进行任何缩放

    def _init_weights(self, m):
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            nn.init.trunc_normal_(m.weight, std=0.2)
            nn.init.constant_(m.bias, 0)

    def forward_features(self, x: torch.Tensor) -> torch.Tensor:
        for i in range(4):
            x = self.downsample_layers[i](x)
            x = self.stages[i](x)

        return self.norm(x.mean([-2, -1]))  # global average pooling, (N, C, H, W) -> (N, C)   # 此处相当于做了一个globalAverage Pooling操作

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.forward_features(x)
        x = self.head(x)
        return x


def convnext_tiny(num_classes: int):
    # https://dl.fbaipublicfiles.com/convnext/convnext_tiny_1k_224_ema.pth
    model = ConvNeXt(depths=[3, 3, 9, 3],
                     dims=[96, 192, 384, 768],
                     num_classes=num_classes)
    return model


def convnext_small(num_classes: int):
    # https://dl.fbaipublicfiles.com/convnext/convnext_small_1k_224_ema.pth
    model = ConvNeXt(depths=[3, 3, 27, 3],
                     dims=[96, 192, 384, 768],
                     num_classes=num_classes)
    return model


def convnext_base(num_classes: int):
    # https://dl.fbaipublicfiles.com/convnext/convnext_base_1k_224_ema.pth
    # https://dl.fbaipublicfiles.com/convnext/convnext_base_22k_224.pth
    model = ConvNeXt(depths=[3, 3, 27, 3],
                     dims=[128, 256, 512, 1024],
                     num_classes=num_classes)
    return model


def convnext_large(num_classes: int):
    # https://dl.fbaipublicfiles.com/convnext/convnext_large_1k_224_ema.pth
    # https://dl.fbaipublicfiles.com/convnext/convnext_large_22k_224.pth
    model = ConvNeXt(depths=[3, 3, 27, 3],
                     dims=[192, 384, 768, 1536],
                     num_classes=num_classes)
    return model


def convnext_xlarge(num_classes: int):
    # https://dl.fbaipublicfiles.com/convnext/convnext_xlarge_22k_224.pth
    model = ConvNeXt(depths=[3, 3, 27, 3],
                     dims=[256, 512, 1024, 2048],
                     num_classes=num_classes)
    return model

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

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

相关文章

内网渗透(三十五)之横向移动篇-IPC配合系统服务横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

Linux文件权限查看与修改

Linux文件的权限linu文件的权限可以分为四类:可读、可写、可执行、没有权限。分别用字符r、w、x、- 表示。2. 用户与用户组Liunx是一个多用户多任务的操作系统,可以通过用户和用户组来更好的控制文件的权限。每个文件都有一个拥有者(某一个具…

批处理Batch学习

批处理Batch学习 前几天一个月薪35k的兄弟,给我推了一个人工智能学习网站,看了一段时间挺有意思的。包括语音识别、机器翻译等从基础到实战都有,很详细,分享给大家。大家及时保存,说不定啥时候就没了。 基础认识 批…

Linux下Python脚本的编写解析fio(minimal格式)(三)

在服务器测试(storage)过程中,会看到很多人写跑fio的脚本用minimal格式来解析,因为这种格式返回的结果对与脚本(shell,python)解析log非常方便.下面介绍一下这种方式下,用Python来解析log 1 一般客户会要求结果中出现一下参数的值: bandwidth…

推荐几款免费且优秀的短视频配音软件,你值得拥有

科技的迅猛发展带来了新生事物的不断涌现,短视频就是其中之一,有的小伙伴喜欢在茶余饭后记录生活的点点滴滴,也有人将之变成了日常的主要收入来源,但无论是哪种,一款好的AI配音软件都是必不可少的,很多短视…

LeetCode 88. 合并两个有序数组

原题链接 难度:easy\color{Green}{easy}easy 题目描述 给你两个按 非递减顺序 排列的整数数组 nums1nums1nums1 和 nums2nums2nums2,另有两个整数 mmm 和 nnn ,分别表示 nums1nums1nums1 和 nums2nums2nums2 中的元素数目。 请你 合并 num…

Flask像Jenkins一样构建自动化测试任务

flask这个框架很轻量,做一些小工具还是可以很快上手的。 1、自动化 某一天你入职了一家高大上的科技公司,开心的做着软件测试的工作,每天点点点,下班就走,晚上陪女朋友玩王者,生活很惬意。 但是美好时光…

常用类(四)Math类和Arrays类

一、Math类 Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数 我们查看math类的常用方法: 我们查看他的源码如下所示: 我们查看他的类图: 他的这些方法基本都是静态的: 我们的代码设置如下所…

重生之我是赏金猎人-SRC漏洞挖掘(十三)-攻防对抗/梦中绝杀X脖代理商

0x00 前言 前两天在国企实验室的朋友遇到了一个棘手的目标,听说之前没人能打点进去,只能靠xxxxx取证 我一听来了兴趣,在梦中臆造了一个靶场进行渗透,并且已获得相关授权 还请各位看官请勿对号入座,如有雷同&#xf…

百舸争流,奋楫者先 | 大势智慧2023年度销售动员大会圆满召开

春回大地,万物新生。满载生机与动力,2月10日,大势智慧2023年度销售动员大会圆满召开。 大势智慧CEO黄先锋、CTO张帆、副总裁周济安、运营中心副总经理段鸿、全国各分公司总经理、总监及全体销售成员线上、线下共聚一堂,以“百舸争…

Android Jetpack组件DataStore之Proto与Preferences存储详解与使用

一、介绍 Jetpack DataStore 是一种数据存储解决方案,允许您使用协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。 如果您当前在使用 SharedPreferences 存储数据,请考虑迁移到 DataStore&#…

vscode构建Vue3.0项目(vite,vue-cli)

构建Vue3.0项目构建Vue3.0项目1.使用Vite构建vue项目的方法以及步骤1. 安装vite2. 运行vite vue 项目3.说明2.使用vue-cli构建vue项目的方法以及步骤1.安装全局vue cli —— 脚手架2、VSCode3.报错4.运行构建Vue3.0项目 1.使用Vite构建vue项目的方法以及步骤 1. 安装vite n…

这才是计算机科学_计算机安全

文章目录一、前言1.1身份认证authentication1.2 权限1.3 开发安全二、黑客2.1 NAND镜像2.2 缓冲区溢出2.3 注入三、加密 cryptography3.1 列位移加密3.2 软件加密3.3 密钥交换一、前言 计算机网络中并不是没有人搞破坏的 但是网络无法区分中要执行的是好是坏 计算机安全&#…

设计模式第七讲-外观模式、适配器模式、模板方法模式详解

一. 外观模式 1. 背景 在现实生活中,常常存在办事较复杂的例子,如办房产证或注册一家公司,有时要同多个部门联系,这时要是有一个综合部门能解决一切手续问题就好了。 软件设计也是这样,当一个系统的功能越来越强&…

最大权闭合子图(最小割模型)

1,定义: 1,最大权闭合子图是最小割的一个模型。即每一个子图中的每一个点,其出边的点也全应该在这个子图中。而所有子图中,其点的权值和最大就是最大权闭合子图。 2,构建该图,我们把所有正权值…

Docker镜像创建及管理(Hub官方仓库使用及私有注册中心搭建)

写在前面 系统环境:centos 7 一、Docker如何创建镜像 镜像的来源有两种: 从镜像仓库下载镜像;自己创建新的镜像。创建分为两种:(1)基于已有镜像创建;(2)使用Dockerfi…

【数据治理-03】无规矩不成方圆,聊聊如何建立数据标准

无规矩,不成方圆!数据标准(Data Standards)是保障数据的内外部使用和交换的一致性和准确性的规范性约束,作为数据治理的基石,是绕不开的一项工作,如此重要的活如何干,咱们一起聊聊。…

【数据结构】排序算法

目录 1.理解排序 1.1 排序的概念 1.2 排序的运用场景 1.3 常见的排序算法 2.插入排序算法 2.1 直接插入排序 2.2 希尔排序 3.选择排序算法 3.1 直接选择排序 3.2 堆排序 4.交换排序算法 4.1 冒泡排序 4.2 快速排序 4.2.1 hoare 法 4.2.2 挖坑法 4.2.3 前…

前期软件项目评估偏差,如何有效处理?

1、重新评估制定延期计划 需要对项目进行重新评估,将新的评估方案提交项目干系人会议,开会协商一致后按照新的讨论结果制定计划,并实施执行。 软件项目评估偏差 怎么办:重新评估制定延期计划2、申请加资源 如果项目客户要求严格&a…

用股票交易量查询接口是怎么查询a股全天总成交量的?

用股票交易量查询接口是怎么查询a股全天总成交量的?今天下班就以通达信给大家讲解一下,通常是在K线图的底部状态栏,可以在日线进行查看a股成交量。在市场栏底部的子图中。 有当天成交的数量。成交量是表示一定的时间内已经成交的中的成交数量…