深度学习训练营之J5周DenseNet+SE-Net实战

news2025/4/19 9:02:37

深度学习训练营之J5周DenseNet+SE-Net实战

  • 原文链接
  • 方法介绍
  • SE模块应用分析
  • SE模块的效果对比
  • SE模块代码实现
  • SE模块在DenseNet当中的应用
  • 参考内容

原文链接

📌第J5周:DenseNet+SE-Net实战📌

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊|接辅导、项目定制

语言:Python3、Pytorch
📌本周任务:📌

    1. 在DenseNet系列算法中插入SE-Net通道注意力机制,并完成猴痘病识别
    1. 改进思路是否可以迁移到其他地方呢
  • 3.测试集accuracy达到89%(拔高,可选)

🔊注: 从前几周开始训练营的难度逐渐提升,具体体现在不再直接提供源代码。任务中会给大家提供一些算法改进的思路、方向,希望大家这一块可以积极探索。(这个探索的过程很重要,也将学到更多)
个人感悟:本周由于临近期末考试,本周三进行数学专业课程的考试,然后还加上重感冒,所以这一次的深度学习训练营所准备的时间还是不是很充足,而且在DenseNet的实际应用上可以明显感觉到自身能力的不足,所以本次在代码的实现过程当中还是有点不熟练,所以本次主要以方法介绍为主,给大家带来的不便感到十分抱歉
论文链接:Squeeze-and-Excitation Networks

方法介绍

SE-Net作为ImageNet 2017 的冠军模型,其优点如下:

  • 复杂度低
  • 计算量小

其具体策略为:通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征,这又叫做“特征重标定”策略。具体的SE模块如下图所示
请添加图片描述
给定一个输入 x x x ,其特征通道数为 c 1 c_1 c1,经过一系列卷积等一般变换 F t r F_{tr} Ftr,后得到一个特征通道数为 c 2 c_2 c2的特征。与传统的卷积神经网络不同,我们需要通过下面三个操作来重新标定前面得到的特征。

1.首先是Squeeze操作,我们顺着空间维度来进行特征压缩,将一个通道数和输入的特征通道数相等,例如可以将将形状为(1, 32, 32, 10)的feature map压缩成(1, 1, 1, 10)。此操作通常采用global average pooling来实现。
2.得到了全局描述特征后,我们进行Excitation操作来抓取特征通道之间的关系,它是一个类似于循环神经网络中门的机制:
s = F e x ( z , W ) = σ ( g ( z , W ) ) = σ ( W 2 Re ⁡ L U ( W 1 z ) ) s=F_{e x}(z, W)=\sigma(g(z, W))=\sigma\left(W_{2} \operatorname{Re} L U\left(W_{1} z\right)\right) s=Fex(z,W)=σ(g(z,W))=σ(W2ReLU(W1z))

这里采用包含两个全连接层的bottleneck结构,即中间小两头大的结构:其中第一个全链接层起到即降维的作用,并通过ReLU激活,第二个全链接层用来将其恢复至原始的维度。进行Excitation操作的最终目的是为每个特征通道生成权重,即学习到的各个通道的激活值(sigmoid激活,值在0~1之间)。
最后一个是Scale的操作,我们将Excitation的输出的权重看作是经过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定,从而提高了每一个通道在模型上的特征更有辨别能力,这类似于attention机制。

SE模块应用分析

请添加图片描述
SE模块非常灵活,表现在其可以直接应用在现有的网络结果中,以Inception和ResNet为例,可以直接在这两个模块后面添加SE模块
请添加图片描述
方框旁边的维度信息代表该层的输出, r r r表示Excitation(激发)操作当中的降维系数

SE模块的效果对比

在ImageNet上的效果
请添加图片描述
从上表可以看出,SE-ResNets在各种深度上都远远超过了其对应的没有SE的结构版本的精度,这表示无论网络的深度以及大小,SE模块都能够给网络带来性能上的增益。值得一提的是,SE-ResNet-50可以达到和ResNet-101一样的精度;更甚,SE-ResNet-101远远地超过了更深的ResNet-152

SE模块代码实现

tensorflow

from tensorflow import keras
from keras import layers
from layers import Model, Input, Reshape, Activation, BatchNormalization, GlobalAveragePooling2D, Dense

class SqueezeExcitationLayer(Model):
    def __init__(self, filter_sq):
        # filter_sq是Excitation中第一个卷积过程中卷积核的个数
        super.__init__()
        self.avgpool = GlobalAveragePooling2D()
        self.dense = Dense(filter_sq)
        self.relu = Activation('relu')
        self.sigmoid = Activation('sigmoid')
    
    def call(self, inputs):
        x = self.avgpool(inputs)
        x = self.dense(x)
        x = self.relu(x)
        x = Dense(inputs.shape[-1])(x)
        x = self.sigmoid(x)
        x = Reshape((1,1,inputs.shape[-1]))(x)
        
        scale = inputs * x
        return scale

SE = SqueezeExcitationLayer(16)

SE模块在DenseNet当中的应用

tensorflow

''' Basic unit of DenseBlock (using bottleneck layer) '''
def DenseLayer(x, bn_size, growth_rate, drop_rate, name=None):
    f = BatchNormalization(name=name+'_1_bn')(x)
    f = Activation('relu', name=name+'_1_relu')(f)
    f = Conv2D(bn_size*growth_rate, 1, strides=1, use_bias=False, name=name+'_1_conv')(f)
    
    f = BatchNormalization(name=name+'_2_bn')(f)
    f = Activation('relu', name=name+'_2_relu')(f)
    f = Conv2D(growth_rate, 3, strides=1, padding=1, use_bias=False, name=name+'_2_conv')(f)
    
    if drop_rate>0:
        f = Dropout(drop_rate)(f)
    
    x = layers.Concatenate(axis=-1)([x, f])
    return x


''' DenseBlock '''
def DenseBlock(x, num_layers, bn_size, growth_rate, drop_rate, name=None):
    for i in range(num_layers):
        x = DenseLayer(x, bn_size, growth_rate, drop_rate, name=name+'_denselayer'+str(i+1))
    return x


''' Transition layer between two adjacent DenseBlock '''
def Transition(x, out_channel):
    x = BatchNormalization(name=name+'_bn')(x)
    x = Activation('relu', name=name+'_relu')(x)
    x = Conv2D(out_channel, 1, strides=1, use_bias=False, name=name+'_conv')(x)
    x = AveragePooling2D(2, 2, name='pool')(x)
    return x


''' DenseNet-BC model '''
def DenseNet(input_tensor=None,  # 可选的keras张量,用作模型的图像输入
             input_shape=None,
             init_channel=64,
             growth_rate=32,
             block_config=(6,12,24,16),
             bn_size=4,
             compression_rate=0.5,
             drop_rate=0,
             classes=1000):  # 用于分类图像的可选类数
    img_input = Input(shape=input_shape)
    # first Conv2d
    x = ZeroPadding2D(padding=((3, 3), (3, 3)), name='conv1_pad')(img_input)
    x = Conv2D(64, 7, strides=2, use_bias=False, name='conv1_conv')(x)
    x = BatchNormalization(name='conv1_bn')(x)
    x = Activation('relu', name='conv1_relu')(x)
    x = MaxPooling2D(3, strides=2, padding=1, name='conv1_pool')(x)
    # DenseBlock
    num_features = init_channel
    for i, num_layers in enumerate(block_config):
        x = DenseBlock(x, num_layers, bn_size, growth_rate, drop_rate, name='denseblock'+str(i+1))
        num_features += num_layers*growth_rate
        if i!=len(block_config)-1:
            x = Transition(x, int(num_features*compression_rate))
            num_features = int(num_features*compression_rate)
    # 加SE注意力机制
    x = SqueezeExcitationLayer(16)(x)
    # final bn+ReLU
    x = BatchNormalization(name='final_bn')(x)
    x = Activation('relu', name='final_relu')(x)
    x = GlobalAveragePooling2D(name='final_pool')(x)
    x = Dense(classes, activation='softmax', name='predictions')(x)
    
    model = Model(img_input, x, name='DenseNet')
    return model


''' DenseNet121 '''
def densenet121(n_classes=1000, **kwargs):
    model = DenseNet(init_channel=64, growth_rate=32, block_config=(6,12,24,16),
                     classes=n_classes, **kwargs)
    return model


''' DenseNet169 '''
def DenseNet169(n_classes=1000, **kwargs):
    model = DenseNet(init_channel=64, growth_rate=32, block_config=(6,12,32,32),
                     classes=n_classes, **kwargs)
    return model


''' DenseNet201 '''
def DenseNet201(n_classes=1000, **kwargs):
    model = DenseNet(init_channel=64, growth_rate=32, block_config=(6,12,48,32),
                     classes=n_classes, **kwargs)
    return model

参考内容

经典CNN算法解析实战-第J5周:DenseNet+SE-Net实战

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

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

相关文章

UART帧格式介绍

UART及通信方式简介 UART Universal Asynchronous Receiver Transmitter 即通用异步收发器,是一种通用的串行、异步通信总线 ,该总线有两条数据线,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信…

Web3 游戏团队如何在项目发布前奠定成功基础——以真实用户支持为核心的运营策略

作者:lesleyfootprint.network 运营 Web3 游戏项目是一项令人兴奋且具有挑战性的任务。无论是对于 NFT 游戏还是链上多人游戏,建立强大且高度参与的用户群体都是游戏成功的关键因素之一。 在本文中,我们将探讨游戏中真实参与和机器人刷量之…

class文件中,常量池之后的相关数据解析!【class二进制文件分析】

前言:前段时间读《深入java虚拟机》介绍到class文件的时候,由于理论知识较多,人总感觉疲惫不堪,就泛泛阅读了一下。在工作中使用起来知识点知道,但是总是需要查阅各种资料。今天有时间,继续整理常量池后面的…

msvcp140.dll丢失的4个解决方法,msvcp140.dll丢失的常见原因

msvcp140.dll是Windows操作系统中的一个动态链接库文件,由Microsoft Visual C程序库所提供。它包含了许多C函数和类的定义,可以为应用程序提供一些基本服务,比如内存管理、文件输入/输出和网络连接等功能。我们在打开游戏或者软件的时候&…

Goby 漏洞更新 |海康威视部分iVMS系统存在文件上传漏洞

漏洞名称:海康威视部分iVMS系统存在文件上传漏洞 English Name:Some Hikvision iVMS file upload vulnerabilitie CVSS core: 9.8 影响资产数:15294 漏洞描述: 海康威视-iVMS综合安防管理平台是一套“集成化”、“数字化”、…

Redis系列----redis网络模型2

一、redis单双线程判断 一、redis单线程定义 主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这…

VH6501干扰仪的使用

目录 1.VH6501接口介绍 2.使用场景 2.1当VH6501作为硬件接口卡作通信/监测使用时,使用CH1的任意接口与总线连接即可 2.2若将 VH6501 用于干扰总线,针对单节点干扰时则通常情况下接任意一个接口即可 2.3针对多节点干扰时,需要通过CH1的两个…

YCbcr to rgb 笔记

YCbCr 色彩空间的一种 YCbCr或Y’CbCr有的时候会被写作:YCBCR或是Y’CBCR,是色彩空间的一种,通常会用于影片中的影像连续处理,或是数字摄影系统中。Y’为颜色的亮度(luma)成分、而CB和CR则为蓝色和红色的浓度偏移量成份。Y’和Y…

3.4 最大字段和

博主简介:一个爱打游戏的计算机专业学生博主主页: 夏驰和徐策所属专栏:算法设计与分析 1.什么是最大子段和? 我的理解: 最大子段和是一个经典的问题,也称为最大子数组和问题。给定一个整数数组,要求找到…

口撕raft面试100问

1,Raft 协议什么作用 2,详细介绍 Raft 流程 我觉得以下这个流程是比较详细的了, 以下是带上了持久化和日志压缩的细节: 持久化:节点会定期将自己的信息,比如当前任期号、投票信息、日志条目和快照&#…

项目改造操作(图书管理系统为例)

目录 后端 概述 获取所有的读者的借阅卡号 获取所有的未被借阅的图书编号 进行借阅 前端 后端 概述 本模块主要完成对图书的借阅处理。需要实现三个接口,第一个是获取所有的读者的借阅卡号,第二个是获取所有的未被借阅的图书编号,第三…

Spring Boot 启动注解分析

文章目录 1. SpringBootApplication2. EnableAutoConfiguration3. AutoConfigurationImportSelector3.1 isEnabled3.2 getCandidateConfigurations 3.3 removeDuplicates3.4 getExclusions3.5 checkExcludedClasses3.6 removeAll3.7 filter 虽然我们在日常开发中,S…

【Golang】golang中http请求的context传递到异步任务的坑

文章目录 前言一、HTTP请求的Context传递到异步任务的坑 前言 在golang中,context.Context可以用来用来设置截止日期、同步信号,传递请求相关值的结构体。 与 goroutine 有比较密切的关系。 在web程序中,每个Request都需要开启一个goroutin…

使用docker部署nginx并支持https

配置nginx支持https,其实也简单,搞个证书,然后修改下配置文件就好了。我以前一篇文章(使用docker部署多个nginx站点并配置负载均衡)为例,做个记录。 如前所述,我使用docker,部署了3…

一文带你看懂软件测试(功能、接口、性能、自动化)详解

全文2000字,预计阅读时间10分钟,建议先点赞收藏慢慢看 一、软件测试功能测试 测试用例编写是软件测试的基本技能;也有很多人认为测试用例是软件测试的核心;软件测试中最重要的是设计和生成有效的测试用例;测试用例是测…

面了个京东拿30k出来的,牛逼到家了。。。

今天上班开早会就是新人见面仪式,听说来了个很厉害的大佬,年纪还不大,是上家公司离职过来的,薪资已经达到中高等水平,很多人都好奇不已,能拿到这个薪资应该人不简单,果然,自我介绍的…

RK平台如何配置USB功能

简介 RK平台基本能够通过dts配置就能实现USB功能。为了方便理解,我这里分三部分来介绍,包括:usb-phy,usb控制器,usb供电。 usb-phy usb-phy负责最底层的信号转换,主要是硬件的差分信号转换成数字信号传给…

十条ChatGPT常用的Prompt

Prompt 本文数据来源:Will 3.6-6.16 硅谷,原作者:rowancheung 一,简化复杂的信息 Prompt: 将(主题)分解成更小、更容易理解的部分。使用类比和现实生活中的例子来简化概念并使其更相关 Brea…

Python之并发多线程操作

一、threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 二、开启线程的两种方式 方式一 #方式一 from threading import Thread import time def sayhi(name):time.sleep(2)print(%s say hello %na…

最大公约数(GCD) 与 最小公倍数(LCM)的 定义、关系、求法

最大公约数 与 最小公倍数 约数 和 倍数最大公约数最小公倍数 最大公约数与最小公倍数的关系求最大公约数、最小公倍数例一例二 约数 和 倍数 如果数 a a a能被数 b b b整除, a a a就叫做 b b b的倍数, b b b就叫做 a a a的约数。 约数和倍数都表示一个…