解码 ResNet:残差块如何增强深度学习性能【数学推导】

2024-06-18 16:28

本文主要是介绍解码 ResNet:残差块如何增强深度学习性能【数学推导】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ResNet简介

残差网络结构

残差网络(ResNet)是由何凯明等人在2015年提出的,它极大地提高了深度神经网络的训练效果,尤其是非常深的网络。ResNet的核心思想是引入“残差块”(Residual Block),通过跳跃连接(Shortcut Connection)解决深层网络的梯度消失和梯度爆炸问题。

结构示意图

  • 输入层
  • 一系列的卷积层(Conv Layers)
  • 残差块(Residual Blocks)
  • 全连接层(Fully Connected Layer)
  • 输出层

在传统的卷积神经网络中,每一层都会对输入的特征进行某种变换,比如卷积操作,然后直接输出这些变换后的结果到下一层。可以把这种变换看作是对输入进行处理和提取新的特征。
y l = F l ( x l ) \mathbf{y}_l = \mathcal{F}_l(\mathbf{x}_l) yl=Fl(xl)

而ResNet通过增加一条跳跃连接,使得每个残差块输出的是“变换后的特征+原始输入特征”,即:

y = F ( x , { W i } ) + x \mathbf{y} = \mathcal{F}(\mathbf{x}, \{W_i\}) + \mathbf{x} y=F(x,{Wi})+x

其中, F ( x , { W i } ) \mathcal{F}(\mathbf{x}, \{W_i\}) F(x,{Wi}) 表示通过多层卷积、激活等操作后的特征, x \mathbf{x} x 表示原始输入特征。

什么是跳跃连接?

跳跃连接(Shortcut Connection),又称为“短路连接”或“直连”,是一种直接将输入信号传递到输出信号的技术。具体来说,就是在每个残差块中,除了正常的变换路径外,还增加了一条直接连接输入和输出的路径。

为什么要使用跳跃连接?

在深层网络中,随着层数的增加,梯度可能会逐渐消失或者爆炸,这会导致网络很难训练。而跳跃连接的引入可以缓解这个问题,因为它允许梯度直接传递到前面的层,确保梯度不会消失。

跳跃连接如何缓解梯度消失和梯度爆炸问题

为了理解跳跃连接如何缓解梯度消失和梯度爆炸问题,我们需要从反向传播(Backpropagation)的角度分析梯度传递过程。

在传统的深层网络中,假设某一层的输入是 x l \mathbf{x}_l xl ,输出是 y l \mathbf{y}_l yl 。每层的变换函数记为 F l \mathcal{F}_l Fl,那么:

y l = F l ( x l ) \mathbf{y}_l = \mathcal{F}_l(\mathbf{x}_l) yl=Fl(xl)

而在ResNet中,增加了跳跃连接后,输出变为:

y l = F l ( x l ) + x l \mathbf{y}_l = \mathcal{F}_l(\mathbf{x}_l) + \mathbf{x}_l yl=Fl(xl)+xl

在反向传播中,我们需要计算每层的梯度。对于传统的深层网络,第 l l l 层的梯度计算如下:

∂ L ∂ x l = ∂ L ∂ y l ⋅ ∂ y l ∂ x l = ∂ L ∂ y l ⋅ ∂ F l ( x l ) ∂ x l \frac{\partial \mathcal{L}}{\partial \mathbf{x}_l} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}_l} \cdot \frac{\partial \mathbf{y}_l}{\partial \mathbf{x}_l} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}_l} \cdot \frac{\partial \mathcal{F}_l(\mathbf{x}_l)}{\partial \mathbf{x}_l} xlL=ylLxlyl=ylLxlFl(xl)

而在ResNet中,由于增加了跳跃连接,梯度的计算变为:

∂ L ∂ x l = ∂ L ∂ y l ⋅ ( ∂ F l ( x l ) ∂ x l + I ) \frac{\partial \mathcal{L}}{\partial \mathbf{x}_l} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}_l} \cdot \left( \frac{\partial \mathcal{F}_l(\mathbf{x}_l)}{\partial \mathbf{x}_l} + \mathbf{I} \right) xlL=ylL(xlFl(xl)+I)

这里, I \mathbf{I} I 是单位矩阵,表示跳跃连接的梯度。

梯度分析

在ResNet中,由于跳跃连接的存在,梯度不仅传递了变换部分( ∂ F l ( x l ) ∂ x l \frac{\partial \mathcal{F}_l(\mathbf{x}_l)}{\partial \mathbf{x}_l} xlFl(xl) ),还传递了输入部分( I \mathbf{I} I ),这意味着即使在深层网络中,梯度也能有效地通过跳跃连接传递到前面的层,而不会完全依赖于 ∂ F l ( x l ) ∂ x l \frac{\partial \mathcal{F}_l(\mathbf{x}_l)}{\partial \mathbf{x}_l} xlFl(xl)

具体来说,如果 ∂ F l ( x l ) ∂ x l \frac{\partial \mathcal{F}_l(\mathbf{x}_l)}{\partial \mathbf{x}_l} xlFl(xl) 在深层网络中趋近于0(梯度消失)或趋近于无穷大(梯度爆炸),跳跃连接的单位矩阵 I \mathbf{I} I 确保了梯度至少能通过 I \mathbf{I} I 进行传递,缓解了梯度消失或爆炸的问题。

总结

  1. 跳跃连接的引入:在每个残差块中,除了对输入特征进行卷积、归一化和激活等操作外,还增加了一条直接传递输入特征到输出的路径。
  2. 公式中的体现:输出特征不仅包含变换后的特征,还加上了输入特征,即 y = F ( x ) + x \mathbf{y} = \mathcal{F}(\mathbf{x}) + \mathbf{x} y=F(x)+x
  3. 缓解梯度问题:跳跃连接确保了梯度在反向传播过程中,即使变换部分的梯度消失或爆炸,输入特征的梯度(\mathbf{I})也能直接传递,避免梯度完全消失或爆炸。

残差块的组成及功能

残差块是ResNet的基本单元,每个残差块中包含了两个主要部分:

  1. 变换路径:对输入进行卷积、批量归一化和激活操作。
  2. 跳跃连接(Shortcut Connection):直接将输入传递到输出,不进行任何变换,只是将输入特征原样添加到经过变换后的特征上。

详细组成

  1. 卷积层(Convolutional Layer):提取特征。
  2. 批量归一化层(Batch Normalization Layer):加速训练,稳定输入。
  3. ReLU激活函数(ReLU Activation Function):引入非线性,提高网络表达能力。
  4. 跳跃连接(Shortcut Connection):将输入直接加到输出上。

具体的操作流程如下:

  1. 输入特征 x \mathbf{x} x 通过卷积层和批量归一化层,得到变换后的特征 F ( x ) \mathcal{F}(\mathbf{x}) F(x)
  2. 变换后的特征 F ( x ) \mathcal{F}(\mathbf{x}) F(x) 与输入特征 x \mathbf{x} x 相加,得到输出特征 y \mathbf{y} y

y = F ( x , { W i } ) + x \mathbf{y} = \mathcal{F}(\mathbf{x}, \{W_i\}) + \mathbf{x} y=F(x,{Wi})+x

这里, x \mathbf{x} x 直接通过跳跃连接加到变换后的特征 F ( x ) \mathcal{F}(\mathbf{x}) F(x) 上。

  1. 输出特征 y \mathbf{y} y 再经过ReLU激活函数:

y = ReLU ( y ) \mathbf{y} = \text{ReLU}(\mathbf{y}) y=ReLU(y)

这种设计可以确保即使在深层网络中,梯度也能有效传播,避免梯度消失或爆炸。

ResNet的输出计算

在ResNet中,每一层的输出不仅仅取决于当前层的输入,还包括了前面层的输入,这种设计使得网络能够更有效地学习。

详细的数学推导
假设一个简单的ResNet包含L个残差块,每个残差块输出为 y l \mathbf{y}_l yl ,输入为 x l \mathbf{x}_l xl ,则有:

y l = F l ( x l ) + x l \mathbf{y}_l = \mathcal{F}_l(\mathbf{x}_l) + \mathbf{x}_l yl=Fl(xl)+xl

其中 F l ( x l ) \mathcal{F}_l(\mathbf{x}_l) Fl(xl) 表示第l个残差块中的变换函数(例如两层卷积和ReLU激活函数)。

整个网络的输入为 x 0 \mathbf{x}_0 x0 ,输出为 y L \mathbf{y}_L yL,即:

y L = F L ( y L − 1 ) + y L − 1 \mathbf{y}_L = \mathcal{F}_L(\mathbf{y}_{L-1}) + \mathbf{y}_{L-1} yL=FL(yL1)+yL1
y L − 1 = F L − 1 ( y L − 2 ) + y L − 2 \mathbf{y}_{L-1} = \mathcal{F}_{L-1}(\mathbf{y}_{L-2}) + \mathbf{y}_{L-2} yL1=FL1(yL2)+yL2
⋮ \vdots
y 1 = F 1 ( x 0 ) + x 0 \mathbf{y}_1 = \mathcal{F}_1(\mathbf{x}_0) + \mathbf{x}_0 y1=F1(x0)+x0

逐层递推,我们可以得到最终的输出:

y L = x 0 + ∑ l = 1 L F l ( x l ) \mathbf{y}_L = \mathbf{x}_0 + \sum_{l=1}^{L} \mathcal{F}_l(\mathbf{x}_l) yL=x0+l=1LFl(xl)

这种设计可以看作是对输入的逐层增强,每层不仅仅是对输入的简单变换,更是对前面所有层次特征的累积。

总结

  1. 残差网络结构:ResNet引入了残差块,每个残差块中有一条跳跃连接直接将输入加到输出上,这样即使网络很深,信息也能有效传递。
  2. 残差块的组成及功能:每个残差块由卷积、批量归一化、ReLU激活和跳跃连接组成,确保输入信息能够直接加到输出上。
  3. ResNet的输出计算:通过逐层递推,每一层的输出都是对输入和变换后特征的累积,使得网络能够更有效地学习深层特征。

具体实现:残差块的工作原理

  1. 输入特征(原始输入特征):假设输入特征是 x \mathbf{x} x
  2. 变换路径:输入特征 x \mathbf{x} x 经过一系列的卷积操作、批量归一化和激活函数后,得到变换后的特征 F ( x ) \mathcal{F}(\mathbf{x}) F(x)
  3. 跳跃连接:在变换路径之外,直接将输入特征 x \mathbf{x} x 加到变换后的特征 F ( x ) \mathcal{F}(\mathbf{x}) F(x)上,得到输出特征 y \mathbf{y} y

y = F ( x ) + x \mathbf{y} = \mathcal{F}(\mathbf{x}) + \mathbf{x} y=F(x)+x

这里, F ( x ) \mathcal{F}(\mathbf{x}) F(x) 是通过卷积和激活操作后的特征, x \mathbf{x} x 是原始输入特征。这样,每个残差块的输出就是“变换后的特征+原始输入特征”。

这篇关于解码 ResNet:残差块如何增强深度学习性能【数学推导】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072512

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶