当前位置: 首页 > news >正文

讲一下resblock的跳跃连接,以及连接前后的shape保持(通过padding保持shape不变)

ResNet 残差块(ResBlock)的跳跃连接 & 形状保持

ResNet(Residual Network)通过 残差块(Residual Block, ResBlock) 解决了深度网络的梯度消失问题。其核心是跳跃连接(Skip Connection),可以让梯度直接从后面的层传播回前面的层,使深度网络更容易优化。


1. ResBlock 的跳跃连接

(1) 结构

ResBlock 的核心是恒等映射(Identity Mapping)

输入 x 直接加到输出 F(x) 上

y = F(x) + x

其中:

• F(x) 由 两层 3×3 卷积 + BN + ReLU 组成。

跳跃连接(Skip Connection) 直接把 x 传递到输出端。

• ReLU(y) 作为最终输出。


(2) 形状保持

卷积计算公式

对于 标准卷积(不考虑分组卷积或空洞卷积),输出特征图的尺寸(H_out 和 W_out)可以用以下公式计算:

H_{\text{out}} = \frac{H_{\text{in}} - \text{kernel\_size} + 2 \times \text{padding}}{\text{stride}} + 1

W_{\text{out}} = \frac{W_{\text{in}} - \text{kernel\_size} + 2 \times \text{padding}}{\text{stride}} + 1

H_{\text{in}}, W_{\text{in}}:输入特征图的高度和宽度

H_{\text{out}}, W_{\text{out}}:输出特征图的高度和宽度

• kernel_size:卷积核的大小(例如 3×3,此时 kernel_size=3)

• stride:步幅,决定滑动窗口移动的步长

• padding:填充的像素数,使得输入和输出尺寸一致

一般情况:

两次 3×3 卷积 具有 stride=1, padding=1,因此 输入 x 和 F(x) 的形状一致

H_{\text{out}} = \frac{H_{\text{in}} - 3 + 2 \times 1}{1} + 1 = H_{\text{in}}

• 因此,直接相加不会改变形状

如果通道数不匹配或 stride=2(降采样情况)

• 需要使用 1×1 卷积 进行 投影变换(Projection),保证 x 和 F(x) 形状一致:

\text{shortcut} = \text{Conv2d}(x, \text{out\_channels}, \text{kernel\_size}=1, \text{stride}, \text{padding}=0)


2. 代码实现

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

# 定义 ResNet 的 BasicBlock(适用于 ResNet-18/34)
class BasicBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(BasicBlock, self).__init__()
        # 3x3 卷积核,保持 shape
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)

        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)

        # 处理输入 x 和 F(x) 形状不匹配情况
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels)
            )

    def forward(self, x):
        identity = self.shortcut(x)  # 跳跃连接(可能做 1x1 卷积调整通道)
        
        out = F.relu(self.bn1(self.conv1(x)))  # 第一个 3x3 卷积
        out = self.bn2(self.conv2(out))  # 第二个 3x3 卷积
        
        out += identity  # 跳跃连接
        out = F.relu(out)  # 最终输出
        return out

# 例子:输入 (1, 64, 32, 32) 通过 BasicBlock
x = torch.randn(1, 64, 32, 32)
block = BasicBlock(64, 64, stride=1)
output = block(x)
print(output.shape)  # torch.Size([1, 64, 32, 32]) 形状保持

3. 形状变化分析

情况

卷积核

stride

padding

通道变化

H, W 变化

是否需要 1×1 变换

普通情况

3×3

1

1

相同

不变

不用 1×1 卷积

下采样

3×3

2

1

变大

H, W 降一半

需要 1×1 卷积

通道增加

3×3

1

1

变大

不变

需要 1×1 卷积


4. 总结

跳跃连接是 ResNet 的核心,使深度网络更易训练。

如果 stride=1,两次 3×3 卷积 + padding=1,形状不变,直接相加。

如果 stride=2 或通道数变化,则用 1×1 卷积调整 x 形状,确保可以相加。

这样既能保持特征信息,又能优化梯度流动,提高训练稳定性! 🚀

相关文章:

  • 建网站开发国外客户企业建站都有什么网站
  • 网站建设结课论文网络优化大师
  • 网站流程图设计工具西安优化外
  • wordpress博客导航windows11优化大师
  • 网络服务有点问题seo网站优化价格
  • wordpress网站怎么建设广东省广州市佛山市
  • Maven+Spring实现后端开发
  • 【滑动窗口】3254. 长度为 K 的子数组的能量值 I
  • 【UE5 C++课程系列笔记】32——读Json文件并解析
  • 【GoLang】etcd初始化客户端时不会返回错误怎么办
  • Vue3命名规范指南
  • 数字内容体验进阶优化策略
  • OP2177运算放大器:高性能模拟信号处理的关键元件
  • 使用el-tab 实现两个tab切换
  • MCP协议java开发的servers,已开源
  • Linux 基础入门指南:用户管理、基本命令(一)
  • Golang标准库——runtime
  • Linux命令-iotop
  • 【Java】网络编程
  • Python爬虫教程008:BeautifulSoup库的基本介绍
  • jQuery 遍历
  • 浙江大学朱霖潮研究员:《人工智能重塑科学与工程研究》以蛋白质结构预测为例|附PPT下载方法
  • Unity网络开发基础 (3) Socket入门 TCP同步连接 与 简单封装练习
  • java_高并发之SpringBoot中实现一个通用Excel导出功能
  • 适配 AGP8.5 版本,版本依赖管理(五)
  • 新版本Xmind结合DeepSeek快速生成美丽的思维导图