深度学习Week19——学习残差网络和ResNet50V2算法

news2024/11/27 7:25:32

文章目录
深度学习Week18——学习残差网络和ResNet50V2算法
一、前言
二、我的环境
三、论文解读
3.1 预激活设计
3.2 残差单元结构
四、模型复现
4.1 Residual Block
4.2 堆叠Residual Block
4.3. ResNet50V2架构复现

一、前言

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

本周由于临近期末,被各种各样事情耽误,学习效果很差,但是仍要坚持打卡,展示自己的学校成果,或许我会选择休息一周,整理一下事情,再重新学习本周内容,因此本周主要是代码复现,更深层次的学习放在未来两周,包括数据集的验证、Pytorch复现代码。

二、我的环境

  • 电脑系统:Windows 10
  • 语言环境:Python 3.8.0
  • 编译器:Pycharm2023.2.3
    深度学习环境:TensorFlow
    显卡及显存:RTX 3060 8G

三、论文解读

我花了一周的时间大致阅读了何恺明大佬的论文,由于时间问题,我只能给出我的理解,可能有错误,欢迎大家指正。

1、预激活设计

ResNet:采用传统的后激活设计,即批量归一化(Batch Normalization,简称BN)和ReLU激活函数位于卷积层之后。
ResNetV2:引入了预激活设计,将BN和ReLU移动到卷积层之前。这种设计被称为“Pre-Activation”,它改变了信息流和梯度流,有助于优化过程。
在这里插入图片描述
从上图中,我们可以很明显的看出原始残差单元、批量归一化后加法、加法前ReLU、仅ReLU预激活、完全预激活,何恺明大佬进行了4种新的尝试,可以看出最好的结果是(e)full pre-activation,其次到(a)original。
对于这个抽象的概念,我咨询了Kimi.ai,让他帮我解释,我试着理解(由于时间问题,本周很多内容都是请教AI的,但AI我觉得不一定准确,还需要小心求证)

  • 原始方法:每个队员跑完后,我们会给他们一个鼓励的拍手(ReLU激活函数),让他们振奋精神,然后他们把接力棒交给下一个队员,并且下一个队员在接棒前会做一些热身运动(批量归一化,BN)。
  • 改变后的第一种方法:这次我们让队员跑完后先做热身运动,然后再给他们拍手鼓励。这样队员们在接力时可能会有点混乱,表现不如原来好。
  • 改变后的第二种方法:我们让队员在接棒前就给他们拍手鼓励,这样他们在跑的时候可能更有动力,但可能因为热身不充分,效果一般。
  • 改变后的第三种方法:我们只给队员拍手鼓励,不做热身运动。这样队员们的表现和原来差不多,但可能因为没有热身,潜力没有完全发挥出来。
  • 改变后的第四种方法:我们让队员在做热身运动和拍手鼓励之后再接棒。这样他们既做好了准备,又得到了鼓励,跑得更快,表现最好。

因此我们发现,预激活可以简化信息流并提高优化的容易度

2、 残差单元结构

在咱们深度学习中,当我们增加网络的层数时,理论上网络的性能应该更好,因为有更多的数据可以用于学习复杂的特征。但实际情况是,过深的网络会变得难以训练,性能反而下降。残差单元因此诞生。

一个残差单元包Identity PathResidual Function
Identity Path就是将输入直接传递到单元的输出,不做任何处理,就像是一个"shortcut"或者“跳跃连接”。如下图,何恺明大佬提出了6种不同的shortcut在残差网络中的使用方式,以及它们是如何影响信息传递的
在这里插入图片描述
分别是原始,0,5倍缩放因子(减弱信息)c,d,e不理解和f应用dropout技术来随机丢弃一些信息,我觉得目的主要都是防止过拟合、增加模型效率,他们的结果如下:
在这里插入图片描述最原始的(a)original 结构是最好的,也就是 identity mapping 恒等映射是最好的

四 、模型复现

(这部分代码我由于最近事情太多就直接复制粘贴了,很不好,我会尽快改正!!)

  1. 官方调用
tf.keras.applications.resnet_v2.ResNet50V2(
    include_top=True,
    weights='imagenet',
    input_tensor=None,
    input_shape=None,
    pooling=None,
    classes=1000,
    classifier_activation='softmax'
)

# ResNet50V2、ResNet101V2与ResNet152V2的搭建方式完全一样,区别在于堆叠Residual Block的数量不同。

import tensorflow as tf
import tensorflow.keras.layers as layers
from tensorflow.keras.models import Model

4.1 Residual Block

"""
残差块
  Arguments:
      x: 输入张量
      filters: integer, filters of the bottleneck layer.
      kernel_size: 默认是3, kernel size of the bottleneck layer.
      stride: default 1, stride of the first layer.
      conv_shortcut: default False, use convolution shortcut if True,
        otherwise identity shortcut.
      name: string, block label.
  Returns:
    Output tensor for the residual block.
"""
def block2(x, filters, kernel_size=3, stride=1, conv_shortcut=False, name=None):
    preact = layers.BatchNormalization(name=name + '_preact_bn')(x)
    preact = layers.Activation('relu', name=name + '_preact_relu')(preact)

    if conv_shortcut:
        shortcut = layers.Conv2D(4 * filters, 1, strides=stride, name=name + '_0_conv')(preact)
    else:
        shortcut = layers.MaxPooling2D(1, strides=stride)(x) if stride > 1 else x

    x = layers.Conv2D(filters, 1, strides=1, use_bias=False, name=name + '_1_conv')(preact)
    x = layers.BatchNormalization(name=name + '_1_bn')(x)
    x = layers.Activation('relu', name=name + '_1_relu')(x)

    x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name=name + '_2_pad')(x)
    x = layers.Conv2D(filters,
                      kernel_size,
                      strides=stride,
                      use_bias=False,
                      name=name + '_2_conv')(x)
    x = layers.BatchNormalization(name=name + '_2_bn')(x)
    x = layers.Activation('relu', name=name + '_2_relu')(x)

    x = layers.Conv2D(4 * filters, 1, name=name + '_3_conv')(x)
    x = layers.Add(name=name + '_out')([shortcut, x])
    return x
# ResNet50
if conv_shortcut:
    shortcut = layers.Conv2D(4 * filters, 1, strides=stride, name=name + '_0_conv')(x)
    shortcut = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name=name + '_0_bn')(shortcut)
else:
    shortcut = x

# ResNet50V2 区别还是很显然的

if conv_shortcut:
    shortcut = layers.Conv2D(4 * filters, 1, strides=stride, name=name + '_0_conv')(preact)
else:
    # 注意后面还多了if语句
    shortcut = layers.MaxPooling2D(1, strides=stride)(x) if stride > 1 else x、

2. 堆叠Residual Block

def stack2(x, filters, blocks, stride1=2, name=None):
    x = block2(x, filters, conv_shortcut=True, name=name + '_block1')
    for i in range(2, blocks):
        x = block2(x, filters, name=name + '_block' + str(i))
    x = block2(x, filters, stride=stride1, name=name + '_block' + str(blocks))
    return x

3. ResNet50V2架构复现

def ResNet50V2(include_top=True,  # 是否包含位于网络顶部的全连接层
               preact=True,  # 是否使用预激活
               use_bias=True,  # 是否对卷积层使用偏置
               weights='imagenet',
               input_tensor=None,  # 可选的keras张量,用作模型的图像输入
               input_shape=None,
               pooling=None,
               classes=1000,  # 用于分类图像的可选类数
               classifier_activation='softmax'):  # 分类层激活函数
                   
    img_input = layers.Input(shape=input_shape)
    x = layers.ZeroPadding2D(padding=((3, 3), (3, 3)), name='conv1_pad')(img_input)
    x = layers.Conv2D(64, 7, strides=2, use_bias=use_bias, name='conv1_conv')(x)

    if not preact:
        x = layers.BatchNormalization(name='conv1_bn')(x)
        x = layers.Activation('relu', name='conv1_relu')(x)

    x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name='pool1_pad')(x)
    x = layers.MaxPooling2D(3, strides=2, name='pool1_pool')(x)

    x = stack2(x, 64, 3, name='conv2')
    x = stack2(x, 128, 4, name='conv3')
    x = stack2(x, 256, 6, name='conv4')
    x = stack2(x, 512, 3, stride1=1, name='conv5')

    if preact:
        x = layers.BatchNormalization(name='post_bn')(x)
        x = layers.Activation('relu', name='post_relu')(x)
    if include_top:
        x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
        x = layers.Dense(classes, activation=classifier_activation, name='predictions')(x)
    else:
        if pooling == 'avg':
            # GlobalAveragePooling2D就是将每张图片的每个通道值各自加起来再求平均,
            # 最后结果是没有了宽高维度,只剩下个数与平均值两个维度。
            # 可以理解为变成了多张单像素图片。
            x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
        elif pooling == 'max':
            x = layers.GlobalMaxPooling2D(name='max_pool')(x)

    model = Model(img_input, x)
    return model
if __name__ == '__main__':
    model = ResNet50V2(input_shape=(224, 224, 3))
    model.summary()
Model: "model"
__________________________________________________________________________________________________
conv5_block1_1_relu (Activation (None, 7, 7, 512)    0           conv5_block1_1_bn[0][0]          
__________________________________________________________________________________________________
conv5_block1_2_pad (ZeroPadding (None, 9, 9, 512)    0           conv5_block1_1_relu[0][0]        
__________________________________________________________________________________________________
conv5_block1_2_conv (Conv2D)    (None, 7, 7, 512)    2359296     conv5_block1_2_pad[0][0]         
__________________________________________________________________________________________________
conv5_block1_2_bn (BatchNormali (None, 7, 7, 512)    2048        conv5_block1_2_conv[0][0]        
__________________________________________________________________________________________________
conv5_block1_2_relu (Activation (None, 7, 7, 512)    0           conv5_block1_2_bn[0][0]          
__________________________________________________________________________________________________
conv5_block1_0_conv (Conv2D)    (None, 7, 7, 2048)   2099200     conv5_block1_preact_relu[0][0]   
__________________________________________________________________________________________________
conv5_block1_3_conv (Conv2D)    (None, 7, 7, 2048)   1050624     conv5_block1_2_relu[0][0]        
__________________________________________________________________________________________________
conv5_block1_out (Add)          (None, 7, 7, 2048)   0           conv5_block1_0_conv[0][0]        
                                                                 conv5_block1_3_conv[0][0]        
__________________________________________________________________________________________________
conv5_block2_preact_bn (BatchNo (None, 7, 7, 2048)   8192        conv5_block1_out[0][0]           
__________________________________________________________________________________________________
conv5_block2_preact_relu (Activ (None, 7, 7, 2048)   0           conv5_block2_preact_bn[0][0]     
__________________________________________________________________________________________________
conv5_block2_1_conv (Conv2D)    (None, 7, 7, 512)    1048576     conv5_block2_preact_relu[0][0]   
__________________________________________________________________________________________________
conv5_block2_1_bn (BatchNormali (None, 7, 7, 512)    2048        conv5_block2_1_conv[0][0]        
__________________________________________________________________________________________________
conv5_block2_1_relu (Activation (None, 7, 7, 512)    0           conv5_block2_1_bn[0][0]          
__________________________________________________________________________________________________
conv5_block2_2_pad (ZeroPadding (None, 9, 9, 512)    0           conv5_block2_1_relu[0][0]        
__________________________________________________________________________________________________
conv5_block2_2_conv (Conv2D)    (None, 7, 7, 512)    2359296     conv5_block2_2_pad[0][0]         
__________________________________________________________________________________________________
conv5_block2_2_bn (BatchNormali (None, 7, 7, 512)    2048        conv5_block2_2_conv[0][0]        
__________________________________________________________________________________________________
conv5_block2_2_relu (Activation (None, 7, 7, 512)    0           conv5_block2_2_bn[0][0]          
__________________________________________________________________________________________________
conv5_block2_3_conv (Conv2D)    (None, 7, 7, 2048)   1050624     conv5_block2_2_relu[0][0]        
__________________________________________________________________________________________________
conv5_block2_out (Add)          (None, 7, 7, 2048)   0           conv5_block1_out[0][0]           
                                                                 conv5_block2_3_conv[0][0]        
__________________________________________________________________________________________________
conv5_block3_preact_bn (BatchNo (None, 7, 7, 2048)   8192        conv5_block2_out[0][0]           
__________________________________________________________________________________________________
conv5_block3_preact_relu (Activ (None, 7, 7, 2048)   0           conv5_block3_preact_bn[0][0]     
__________________________________________________________________________________________________
conv5_block3_1_conv (Conv2D)    (None, 7, 7, 512)    1048576     conv5_block3_preact_relu[0][0]   
__________________________________________________________________________________________________
conv5_block3_1_bn (BatchNormali (None, 7, 7, 512)    2048        conv5_block3_1_conv[0][0]        
__________________________________________________________________________________________________
conv5_block3_1_relu (Activation (None, 7, 7, 512)    0           conv5_block3_1_bn[0][0]          
__________________________________________________________________________________________________
conv5_block3_2_pad (ZeroPadding (None, 9, 9, 512)    0           conv5_block3_1_relu[0][0]        
__________________________________________________________________________________________________
conv5_block3_2_conv (Conv2D)    (None, 7, 7, 512)    2359296     conv5_block3_2_pad[0][0]         
__________________________________________________________________________________________________
conv5_block3_2_bn (BatchNormali (None, 7, 7, 512)    2048        conv5_block3_2_conv[0][0]        
__________________________________________________________________________________________________
conv5_block3_2_relu (Activation (None, 7, 7, 512)    0           conv5_block3_2_bn[0][0]          
__________________________________________________________________________________________________
conv5_block3_3_conv (Conv2D)    (None, 7, 7, 2048)   1050624     conv5_block3_2_relu[0][0]        
__________________________________________________________________________________________________
conv5_block3_out (Add)          (None, 7, 7, 2048)   0           conv5_block2_out[0][0]           
                                                                 conv5_block3_3_conv[0][0]        
__________________________________________________________________________________________________
post_bn (BatchNormalization)    (None, 7, 7, 2048)   8192        conv5_block3_out[0][0]           
__________________________________________________________________________________________________
post_relu (Activation)          (None, 7, 7, 2048)   0           post_bn[0][0]                    
__________________________________________________________________________________________________
avg_pool (GlobalAveragePooling2 (None, 2048)         0           post_relu[0][0]                  
__________________________________________________________________________________________________
predictions (Dense)             (None, 1000)         2049000     avg_pool[0][0]                   
==================================================================================================
Total params: 25,613,800
Trainable params: 25,568,360
Non-trainable params: 45,440

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

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

相关文章

v-html 空格/换行不生效

接口返回的内容如下&#xff1a;有空格有换行&#xff0c;但 使用v-html无效 需加css样式 white-space: pre-wrap; <div class"pretty-html" v-html"Value"></div>.pretty-html {white-space: pre-wrap; /* 保留空格和换行&#xff0c;并允许…

OZON怎么查看竞品数据,OZON怎么找竞品数据

在跨境电商的激烈竞争中&#xff0c;了解和分析竞品数据是每一位卖家优化销售策略、提升市场竞争力的关键步骤。OZON作为俄罗斯领先的电商平台&#xff0c;为卖家提供了丰富的数据分析工具&#xff0c;而萌啦ozon数据作为第三方数据分析平台&#xff0c;更是为卖家提供了更为全…

Linux 进程与计划任务管理

一、程序、进程、线程的概念 1. 程序&#xff1a;是指一组指示计算机或其他具有信息处理能力装置执行动作或做出判断的指令&#xff0c;通常用某种程序设计语言编写&#xff0c;运行于某种目标计算机体系结构上 2. 进程&#xff1a;是计算机中的软件程序关于某数据集合上的一次…

某yi逆向sign值

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未经…

pdf可以删除其中一页吗?6个软件教你快速进行pdf编辑

pdf可以删除其中一页吗&#xff1f;6个软件教你快速进行pdf编辑 编辑PDF文件并删除特定页面是处理文档时常见的需求&#xff0c;特别是在需要定制或精简文件内容时。以下是几款广受欢迎的PDF编辑软件&#xff0c;它们提供了强大的页面删除功能&#xff0c;帮助用户轻松管理和修…

重新定义 AI 部署效率与性能!ZOLOZ 如何借助 AC2 实现低成本高性能的提优?| AI 案例推荐

AI 容器镜像——面向云上全容器场景 王坚院士提到&#xff0c;算力是人工智能发展的三要素之一&#xff0c;而云计算是最好的提供算力的技术手段&#xff0c;英伟达的黄仁勋也表达过类似的观点。可以说&#xff0c;大模型时代下的 AI&#xff0c;天然就是在云场景里的。 容器…

SpringBoot-第一天学习

SpringBoot介绍-约定大于配置 SpringBoot是在Spring4.0基础上开发的&#xff0c;不是替代Spring的解决方案&#xff0c;而是和Spring框架结合并进一步简化Spring搭建和开发过程的。 如何简化&#xff1f;就是通过提供默认配置等方式让我们更容易&#xff0c;集成了大量常用的…

景区智能厕所系统,打造智能化,人性化公共空间

在智慧旅游的大潮中&#xff0c;景区智能厕所系统正逐渐成为提升公共空间智能化、人性化水平的关键载体。作为智慧城市建设的重要组成部分&#xff0c;智能厕所系统不仅解决了传统公厕存在的诸多问题&#xff0c;更通过科技的力量&#xff0c;为游客创造了更加舒适、便捷的如厕…

StreamSets: 数据采集工具详解

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 欢迎关注微信公众号&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&a…

c/c++ 程序运行的过程分析

c/c编译基础知识 GNU GNU&#xff08;GNU’s Not Unix!&#xff09;是一个由理查德斯托曼&#xff08;Richard Stallman&#xff09;在1983年发起的自由软件项目&#xff0c;旨在创建一个完全自由的操作系统&#xff0c;包括操作系统的内核、编译器、工具、库、文本编辑器、邮…

渲染农场渲染真的很贵吗?如何正确使用云渲染农场?

作为渲染行业主流的技术服务“渲染农场"&#xff0c;一直都是备受大家关注&#xff0c;渲染农场最核心的在于充足的计算机算力&#xff0c;结合3D软件支持多台机器渲染的特点&#xff0c;租用渲染农场的机器帮助你快速的解决你的渲染项目。 虽然说渲染农场需要支付一定的…

Astro新前端框架首次体验

Astro新前端框架首次体验 1、什么是Astro Astro是一个静态网站生成器的前端框架&#xff0c;它提供了一种新的开发方式和更好的性能体验&#xff0c;帮助开发者更快速地构建现代化的网站和应用程序。 简单来说就是&#xff1a;Astro这个是一个网站生成器&#xff0c;可以直接…

MinIO:开源对象存储解决方案的领先者

MinIO:开源对象存储解决方案的领先者 MinIO 是一款开源的对象存储系统&#xff0c;致力于提供高性能、可伸缩、安全的数据存储解决方案。 官方解释&#xff1a;MinIO 是一个基于Apache License v2。0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适…

因版本冲突导致logback的debug日志不打印

因框架调整&#xff0c;降级了logback的版本号&#xff0c;由1.3.12降级为1.2.11&#xff08;因框架限制&#xff0c;只能采用1.2版本&#xff09;&#xff0c;降级后发现debug日志无法打印出来&#xff0c;logback.xml配置文件不生效。后排查发现是与slf4j的版本兼容问题 依赖…

以某头部基金实践为例,验证深信服超融合对TA系统承载能力

TA&#xff08;Transfer Agent&#xff09;开放式基金登记过户系统是交易管理系统的重要组成部分&#xff0c;是登记注册机构向投资者提供账户管理、份额登记、交易清算、红利发放、持有人名册保管的综合服务系统。 作为开放式基金运作的核心系统之一&#xff0c;承担着投资者…

Qt 加载图片的几种方式 以及加载 loading

项目中经常使用加载图片&#xff1a; 常用有两种方式&#xff1a; 1.使用 QWidget 加载图片&#xff1a; 效果&#xff1a; 样例源码&#xff1a; int pict_H ui->widgetImage->height();int pict_W ui->widgetImage->width();ui->widgetImage->setFixe…

【车载开发系列】GIT安装详细教程

【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程一. GIT软件概念二. GIT安装步骤三. GIT安装确认三. GIT功能使用1&#xff09;Git Bash2&#xff09;Git CMD3&#xff09;Git FAQs4&#xff09;Git GUI 一. GIT软件概念 G…

comsol随机材料参数赋值

comsol随机材料参数赋值 在comsol中定义外部matlab函数 在comsol中定义外部matlab函数 首选项&#xff0c;安全性&#xff0c;允许 材料中&#xff0c;将杨氏模量更改为变量函数 计算 应力有波动&#xff0c;可见赋值成功 也可以看到赋值的材料参数&#xff1a;

针对 LLM 应用程序优化 RAG

前言 大型语言模型 (LLM)&#xff08;如 GPT-4&#xff09;在生成类似人类的文本方面表现出了令人印象深刻的能力。然而&#xff0c;在保留事实知识方面&#xff0c;它们仍然面临挑战。这就是检索增强生成 (RAG) 的作用所在——将 LLM 的生成能力与外部知识源相结合。RAG 已成…

TAPD项目管理软件无法与企业微信进行关联

TAPD一段时间未使用后&#xff0c;需要重新启动&#xff0c;此时会出现你的企业微信尚未与TAPD账号关联的提示 解决方案&#xff1a;找到TAPD应用&#xff0c;先删除应用&#xff0c;然后再解除禁用即可