【深度学习】ResNet网络详解

article/2025/10/6 15:02:22

文章目录

    • ResNet
      • 参考
      • 结构概况
      • conv1与池化层
      • 残差结构
      • Batch Normalization
      • 总结

ResNet

参考

ResNet论文:
https://arxiv.org/abs/1512.03385
本文主要参考视频:https://www.bilibili.com/video/BV1T7411T7wa
https://www.bilibili.com/video/BV14E411H7Uw

结构概况

ResNet的网络结构图如图所示:

在这里插入图片描述

这是ResNet不同层数的网络 结构图。

可以看到,结构大差不差。不论是18层、34层、50层、还是101层、152层。

上来都是一个7x7的卷积层,然后是一个3x3的最大池化下采样。

然后就是按照图中的conv2_xconv3_xconv4_xconv5_x中的残差结构。

最后再跟一个平均池化下采样,和全连接层,sofmax输出。

conv1与池化层

我们先看一下前两层。

在这里插入图片描述

首先呢,ResNet使用ImagesNet数据集,采用的默认输入尺寸是224x224,RGB图像,三通道

按照表中,我们可以看到,图片输入之后,首先是一个7x7,64,stride 2

也就是一个卷积层,卷积核大小为7x7,输出通道为64(也就是卷积核个数),stride=2。

没说padding,我们需要自己算一下,表里写了这一层的输出是112x112

补充一点知识:

假设输入图片为 W x W 卷积核大小为F x F,步长stride=S,padding=P(填充的像素数)
则输出图像的大小 W2 =(W - F +2P)/S +1

可以注意到这个公式中有除法,一般我们做卷积时除不尽的时候都向下取整

可以参考pytorch官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d

在这里插入图片描述

但是我们做池化的时候,也可以采用向上取整

参看pytorch官方文档:https://pytorch.org/docs/stable/generated/torch.nn.MaxPool2d.html#torch.nn.MaxPool2d

有一个参数ceil_mode,默认是floor是向下取整,可以设置为True,向上取整

ceil_mode – when True, will use ceil instead of floor to compute the output shape

有的时候池化会选择向上取整(最大池化和平均池化有时取整方式不同)

那就是说 112 = (224 - 7 + 2P)/ 2 + 1

化简后就是 111 = (217 + 2P)/2 = 108.5+P

所以P=3 所以Padding是3

所以我们输入图片进来,第一层是in_channel=3,out_channel=64,kernel_size=7,stride=2,padding=3

没有偏置bias。经过这一层我们会得到大小为112x112的尺寸,通道数为64

然后经过一个3x3的最大池化下采样,stride=2

W o u t = ( W i n − F + 2 P ) / S + 1 W_{out}= (W_{in} - F + 2P)/S + 1 Wout=(WinF+2P)/S+1

池化层也采用向下取整。所以 56=(112 - 3 + 2P)/2 +1 计算出来P=1

所以第二层池化层是in_channel=64,out_channel=64,kernel_size=3,stride=2,padding=1

经过池化层,我们会得到一个56x56,64通道的输出,紧接着就是conv2_x中对应的一系列残差结构

残差结构

经过前面两层,我们得到一个56x56,64通道的输出

紧接着是conv2_x

这就是残差块,残差块大致有两种类型,一种是两层卷积的,一种的三层卷积的,就是途中红框画的。

在这里插入图片描述

比如如果是ResNet34,那么池化层之后,就是两个3x3,64的卷积层,这两个组成一个残差块。

如果是ResNet50,那么池化层之后就是1x1,64的卷积层 + 3x3,64的卷积层 + 1x1,256的卷积层,三个组成一个残差块。

后面写的x3就代表有三个这样的残差块连接一起

如下图所示,关于残差结构的原理,不多说了,这里主要讲实现。

在这里插入图片描述

有几个点需要注意:

以ResNet34为例,按照表格里面写的,池化之后,我们的大小是56x56x64,那么经过conv2_x之后我们的输出还是56x56x64

输入和输出特征矩阵的大小一样,那么就说明stride=1,padding=1

因为公式 W o u t = ( W i n − F + 2 P ) / S + 1 W_{out}= (W_{in} - F + 2P)/S + 1 Wout=(WinF+2P)/S+1

要保证一样,那就S=1,不然的话,大于1就没法一样,然后计算padding可知,也是1

所以经过这两层之后呢,得到的还是56x56x64的特征图,可以直接与残差块那个分支相加。

但是呢这里需要注意,我们看conv3_x,是3x3,128通道,也就是说经过conv2_x后得到的56x56,64通道

conv3_x里面升维了,并且大小也变了,变成28x28了

这时候要注意一个问题,分支与主分支的结果就无法相加了,大小不一致,维度不一致啊

怎么办呢,所以还有一种虚线连接的残差块,如图

在这里插入图片描述

在分支里面做了一个1x1的卷积层,1x1的卷积层主要是用来升维和降维的。同时通过设置stride可以改变尺寸

所以就通过这个卷积层得到了28x28,128通道的特征图,可以与主分支直接相加了

并且我们通过计算可以算出来,残差块主分支padding=1,右边的分支padding=2

对于ResNet50和101,深层次的ResNet也是按照这样的方法处理的

在这里插入图片描述

但是注意啊,这种虚线结构只是为了解决尺寸不一样无法相加的情况

什么情况下需要用这个呢?

对于ResNet18和ResNet34而言,conv3_xconv4_xconv5_x的第一层才需要虚线结构。

可以看到表里面,ResNet34的conv3_x的第一层会输出28x28,128通道的,但是输入是56x56,64通道的,所以需要虚线结构,而conv2_x不需要,因为输入输出是一样的。

而对于ResNet50和ResNet101,ResNet152而言,conv2_xconv3_xconv4_xconv5_x的第一层都需要虚线结构

因为ResNet50从conv2_x开始,输入56x56,64通道,输出是56x56,256通道的,所以conv2_x也需要虚线结构,不过这个虚线结构只调整通道数即可。

在这里插入图片描述

所以,我们根据表格可以看到ResNet50中,conv3_x有四个残差块,这其中只有第一个会遇到尺寸不一样的问题,需要用虚线结构,别的都不需要。

同样的,conv4_xconv5_x的第一层也需要

另外再注意一个改进:

在这里插入图片描述

Batch Normalization

Batch Normalization的目的是使我们的一批(Batch)feature map满足均值为0,方差为1的分布规律。

这里关于BN层的原理就不写了,可以看这个视频和博客

https://www.bilibili.com/video/BV1T7411T7wa

https://blog.csdn.net/qq_37541097/article/details/104434557

我们需要知道的是

建议将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias

所以说,我们实际上的残差网络块应该是如图,这个样子的

在这里插入图片描述

总结

至此,整个ResNet的网络结构就清晰了。其中需要注意的点主要就是:

  • 计算卷积过程中的参数 W o u t = ( W i n − F + 2 P ) / S + 1 W_{out}= (W_{in} - F + 2P)/S + 1 Wout=(WinF+2P)/S+1
  • ResNet18层和34层conv3_xconv4_xconv5_x中的第一层需要用虚线结构
  • ResNet50层、101层和152层中的conv2_xconv3_xconv4_xconv5_x中的第一层都需要用虚线结构
  • BN层放在卷积层(Conv)和Relu之间,且卷积层不要使用偏置bias

http://chatgpt.dhexx.cn/article/ygtNIC50.shtml

相关文章

【使用Pytorch实现ResNet网络模型:ResNet50、ResNet101和ResNet152】

使用Pytorch实现Resnet网络模型:ResNet50、ResNet101和ResNet152 介绍什么是 ResNet?ResNet 的架构使用Pytorch构建 ResNet网络 介绍 在深度学习和计算机视觉领域取得了一系列突破。尤其是随着非常深的卷积神经网络的引入,这些模型有助于在图…

使用PyTorch搭建ResNet101、ResNet152网络

ResNet18的搭建请移步:使用PyTorch搭建ResNet18网络并使用CIFAR10数据集训练测试 ResNet34的搭建请移步:使用PyTorch搭建ResNet34网络 ResNet34的搭建请移步:使用PyTorch搭建ResNet50网络 参照我的ResNet50的搭建,由于50层以上几…

Java中的数组

数组 1.什么是数组 数组就是存储相同数据类型的一组数据,且长度固定 基本数据类型4类8种:byte/char/short/int/long/float/double/boolean 数组,是由同一种数据类型按照一定的顺序排序的集合,给这个数组起一个名字。是一种数据类型&#…

java输出数组(java输出数组)

多维数组在Java里如何创建多维数组? 这从第四个例子可以看出,它向我们演示了用花括号收集多个new表达式的能力: Integer[][] a4 { { new Integer (1), new Integer (2)}, { new Integer (3), new Integer (4)}, { new Integer (5), new…

java怎么输出数组(Java怎么给数组赋值)

Java中数组输出的三种方式。第一种方式,传统的for循环方式,第二种方式,for each循环,  第三种方式,利用Array类中的toString方法. 定义一个int类型数组,用于输出 int[] array={1,2,3,4,5}; 第一种方式,传统的for循环方式 for(int i=0;i {System.out.println(a[i]); } 第…

数组的输入与输出

前言: 我们知道对一个字符数组进行输入与输出时会用到: 输入:scanf,getchar,gets 输出:printf,putchar,puts 然而可能还有很多的朋友对这些还不是很了解,今天让我们共同学习数组的输入与输出吧。 %c格式是用于输入…

Java二维数组的输出

1. Java二维数组的输出<1> (1) 输出结果右对齐"%5d" public class HelloWorld {public static void main(String[] args){int myArray[ ][ ] { {1,2}, {7,2}, {3,4} };for(int i0; i<3; i){for (int j0; j<2; j)System.out.printf("%5d",my…

Java中数组的输入输出

数组的输入 首先声明一个int型数组 int[] a 或者 int a[] 给数组分配空间 anew int[10]; 和声明连起来就是int[] anew int[10]; 或者是 int a[]new int[10]; 给数组赋值 a[0]1;//0代表的是数组的第1个元素 ,元素下标为0 a[1]1;//1代表的是数组的第2个元素 ,元素下标为0 …

Java 数组的输入输出

Java中要对控制台进行输入操作的话要调用Scanner类&#xff0c;定义一个扫描的对象&#xff0c;例&#xff1a; //要导入java.util.Scanner; Scanner scanner new Scanner(System.in); 这样便打开了输入流&#xff0c;接下来定义数组&#xff1a; int[] n new int[4];//使…

Java中字符串数组的输入与输出

今天刷题遇到一个坑&#xff0c;老是接收不到字符串数组。即用str[i]sc.nextLine();这样的方式去接收数组的话&#xff0c;打印的时候总是会少一个。 import java.util.Scanner;public class test {public static void main(String[] args) {Scanner sc new Scanner(System.i…

java中打印输出数组内容的三种方式

今天输出数组遇到问题&#xff0c;学习一下打印输出数组内容的几种方式 错误示范&#xff1a;System.out.println(array);  //这样输出的是数组的首地址&#xff0c;而不能打印出数组数据。&#xff08;唉&#xff0c;我开始就是这么写的。。。&#xff09; 一维数组&#…

NTP协议之旅

NTP协议之旅 What---啥是NTPWhy---为什么需要NTPHow---NTP实现原理Do---NTP实战使用HCL 华三模拟器进行NTP配置抓包分析 What—啥是NTP NTP是在分布式网络中&#xff0c;进行时钟同步的协议&#xff0c;其具有较高的时间同步精度。所使用的传输层协议为UDP&#xff0c;使用端口…

ntrip协议

https://blog.csdn.net/wandersky0822/article/details/88558456这篇介绍的是RTK精确定位的原理&#xff0c;及影响精确定位的各种条件。 这一篇介绍的就比较细&#xff0c;仅仅介绍RTK 差分信息的 产生 申请与分发。 最近要做一个GPS RTK基站&#xff0c;也就是为RTK客户端提…

Ntrip协议简介

Ntrip通讯协议1.0 1 什么是Ntrip&#xff1f; CORS&#xff08;Continuously Operating Reference Stations&#xff09;就是网络基准站&#xff0c;通过网络收发GPS差分数据。用户访问CORS后&#xff0c;不用单独架设GPS基准站&#xff0c;即可实现GPS流动站的差分定位。 访问…

NTP技术介绍

NTP 简介 NTP&#xff08;Network Time Protocol&#xff0c;网络时间协议&#xff09;是由RFC 1305定义的时间同步协议&#xff0c;用来在分布式时间服务器和客户端之间进行时间同步。NTP基于UDP报文进行传输&#xff0c;使用的UDP端口号为123。 使用NTP的目的是对网络内所…

NTPv4协议解析

前言 本文的撰写基于RFC5905.NTP 是时间网络控制协议&#xff0c;V4版本相交V3版本&#xff0c;修复了V3存在的一些问题。尤其是NTPV4的拓展时间戳鼓励使用浮动双数据类型&#xff0c;这样使得NTP能够更好的支持1ns的场景&#xff0c;轮询间隔也从上一代的最多1024s拓展到了36…

NTP 网络时间协议

目录 基本原理 结构 工作模式 单播C/S模式 对等体模式 广播模式 组播模式 多播模式 NTP访问控制 访问权限 KOD 认证功能 配置 NTP用于在一系列分布式时间服务器与客户端之间同步时钟。基于IP和UDP。NTP报文通过UDP传输&#xff0c;端口号是123. NTP主要应用于网络中…

NTP协议简介

NTP协议简介 一. datec dates分析1. 同步流程2. 缺陷 二. NTP(**Network Time Protocol**)1. NTP概述 [1、2、3、7]2. NTP的时钟同步原理与授时精度分析 [3、1、10]NTP的时钟同步原理NTP的授时精度分析 3. NTP中其它的提高授时精度的措施[1、6]参考资料 三. 对NTP改进以获得更高…

ntp同步详解

一、ntp服务是什么 1.定义 NTP是网络时间协议(Network Time Protocol)&#xff0c;它是用来同步网络中各个计算机的时间的协议。 2.发展 首次记载在Internet Engineering Note之中&#xff0c;其精确度为数百毫秒。 稍后出现了首个时间协议的规范RFC-778&#xff0c;它被命…

NTP协议代码实现

本文将讲解NTP的代码实现和调试过程的一些记录。 首先&#xff0c;进行NTP报文结构体的构建。 //宏定义 #define NTP_TIMESTAMP_DELTA 2208988800ull //number of seconds between 1900 and 1970&#xff0c;1900-1970的时间差 #define SEC_TIME_ZONE (8*60*60) //B…