ResNet网络结构详解(Tensorflow2.6.0实现网络结构)

article/2025/9/16 5:44:58

文章目录

    • 1.ResNetX网络结构表
      • (1)论文地址:
      • (2)ResNet18网络结构:
      • (3)ResNet34网络结构:
    • 2.卷积神经网络的发展
      • (1).卷积神经网络的发展:
      • (2).卷积神经网络的再一次崛起:
    • 3.ResNet18网络结构讲解
      • (1)输入图片:
      • (2)第一层输入图片的卷积和池化:
      • (3)第一组conv2_x:
      • (4)第一组conv3_x:
      • (5)第一组conv4_x:
      • (6)第一组conv5_x:
      • (7)最后进行全局平局池化操作,全连接层和softmax,输出1000个类别概率:
    • 4.相关问题和思考
      • (1)2.既然更深的网络可以提取到更多的特征,为什么人们不直接堆叠卷积层,使得网络的深度更深,从而提取到更多的特征呢?
      • (2)ResNet解决网络退化的机理
      • (3)解决shortcut connection时恒等映射问题
      • (4)为什么ResNet结构可以有效解决因网络层数增加而导致模型难以训练的问题?
      • (5)拓展
    • 5.ResNet18,34,50结构实现(Tensorflow2.6.0)
      • (1)ResNet18,34结构:
      • (2)ResNet50结构:
    • 6.测试设计的网络结构(进行图片数据集的训练)

1.ResNetX网络结构表

(1)论文地址:

https://arxiv.org/pdf/1512.03385.pdf
在这里插入图片描述
以下图片中的网络结构方式使用pytorch实现最好,因为在tensorflow中的padding='same’或者padding=‘valid’,不能自定义。但是在本篇文章中将使用tensorflow实现ResNet网络结构。
可以看这篇博文:https://mydreamambitious.blog.csdn.net/article/details/124077928
类似使用pytorch实现自定义padding的网络结构(AlexNet)

(2)ResNet18网络结构:

在这里插入图片描述
图片来自:https://blog.csdn.net/qq_37080185/article/details/120484553

(3)ResNet34网络结构:

在这里插入图片描述
在这里插入图片描述

2.卷积神经网络的发展

(1).卷积神经网络的发展:

LeNet5诞生于1994年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。自从1988年开始,在多年的研究和许多次成功的迭代后,这项由Yann LeCun完成的开拓性成果被命名为LeNet5。LeNet5当时主要用户手写体数字的识别


(2).卷积神经网络的再一次崛起:

在2012的ImageNet图片分类任务上,AlexNet获得了冠军,自从那以后人们开始使用卷积神经网提取特征,2013的时候ZFNet获得了冠军;2014年的时候GoogleNet获得了冠军,VGG获得了亚军;都是使用了卷积神经网络提取图像的特征

3.ResNet18网络结构讲解

(1)输入图片:

224x224x3


(2)第一层输入图片的卷积和池化:

在这里插入图片描述
在这里插入图片描述

卷积操作:
卷积采用步长为2,卷积核大小为7x7的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(224+2x3-7)/2+1=112
输出大小:112x112x64

池化操作:
池化单元采用3x3大小,步长为2:
output_size=(input_size+2x1-3)/2+1=56
输出大小为:56x56x64


(3)第一组conv2_x:

在这里插入图片描述
在这里插入图片描述

两个相同的卷积操作:
卷积采用步长为1,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(56+2x1-3)/1+1=56
输出大小:56x56x64


(4)第一组conv3_x:

在这里插入图片描述
在这里插入图片描述
第一步的卷积操作:
卷积采用步长为2,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(56+2x1-3)/2+1=28
输出大小:28x28x128

第二步的卷积操作:
卷积采用步长为1,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(28+2x1-3)/1+1=28
输出大小:28x28x128

第三步identity:
第二步卷积之后通道数已经升维到了128;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1x1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。


(5)第一组conv4_x:

在这里插入图片描述在这里插入图片描述
第一步的卷积操作:
卷积采用步长为2,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(28+2x1-3)/2+1=14
输出大小:14x14x256

第二步的卷积操作:
卷积采用步长为1,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(14+2x1-3)/1+1=14
输出大小:14x14x256

第三步identity:
第二步卷积之后通道数已经升维到了256;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1x1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。


(6)第一组conv5_x:

在这里插入图片描述
在这里插入图片描述

第一步的卷积操作:
卷积采用步长为2,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(14+2x1-3)/2+1=7
输出大小:7x7x512

第二步的卷积操作:
卷积采用步长为1,卷积核大小为3x3的卷积操作:
ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(7+2x1-3)/1+1=7
输出大小:7x7x512

第三步identity:
第二步卷积之后通道数已经升维到了512;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1x1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。


(7)最后进行全局平局池化操作,全连接层和softmax,输出1000个类别概率:

1
在这里插入图片描述


4.相关问题和思考

(1)2.既然更深的网络可以提取到更多的特征,为什么人们不直接堆叠卷积层,使得网络的深度更深,从而提取到更多的特征呢?

讨论:这里就涉及到一个很重要的问题,就是当网络的深度加深时,会出现退化的现象。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从图中可以看出,56层的反而出现训练误差和测试误差都比20层的训练误差和测试误差都要大。网络变深之后还不如浅层的神经网络。
注意:这里不是出现了过拟合的现象,过拟合是在训练集上的准确率高,而在验证集上的准确率低。所以ResNet就是解决了网络退化现象。


(2)ResNet解决网络退化的机理

(1)恒定映射这一路的梯度为1,把深层梯度注入底层,防止梯度消失
(2)skip connection 可以实现不同分辨率特征的组合
(3)网络加深,相邻像素回传回来的梯度相关性越来越低,最后接近白噪声;但相邻像素之间具有局部相关性,相邻像素的梯度也应该局部相关。相邻像素不相关的白噪声梯度,只意味着随机扰动,并无拟合。ResNet梯度相关性衰减从增加为。保持了梯度相关性
(4)残差网络相当于不同长度的神经网络组成的组合函数
(5)残差模块相当于一个差分放大器

参考:
a.ResNet深度残差网络
https://b23.tv/k0skBHU
b.Resnet到底在解决一个什么问题呢https://www.zhihu.com/question/64494691
c.为什么resnet效果会那么好
https://www.zhihu.com/question/52375139


(3)解决shortcut connection时恒等映射问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用三种方式解决这个问题,上面的A,B,C分别代表三种方式的实验结果:
A——所有的shortcut无额外的参数,升维时采用padding补零的方式;
B——普通的shortcut使用identify mapping(恒等映射)升维时使用1x1卷积升维;
C——所有的shortcut都使用1x1卷积升维;
(a)A,B,C三种方式都比不带残差模块的模型都要好;其中A在升维的时候直接使用补零的方式,所以相当于丢失了shortcut分支的信息,没有进行残差学习;
(b)C的13个非下采样模块的shortcut都有参数,模型的表达能力更强;
(c)可以看到上面的三种方式中,C方式虽然是最好的,但是却引入的额外的参数量,所以这种方式并不是最适合的。说明identify mapping(恒等映射)已经足够解决shortcut问题。


(4)为什么ResNet结构可以有效解决因网络层数增加而导致模型难以训练的问题?

在这里插入图片描述
参考博文:
https://blog.csdn.net/weixin_44815085/article/details/104348749


(5)拓展

(1)更深层的网络提取的特征也更加的丰富,也越来越特化和更加的难理解;
(2)直接堆叠网络的深度会造成梯度消失和爆炸的问题。


5.ResNet18,34,50结构实现(Tensorflow2.6.0)

(1)ResNet18,34结构:

在这里插入图片描述

import keras
import  numpy as np
import  tensorflow as tf
from tensorflow.keras import layers
import tensorflow.keras.applications.resnet
from tensorflow.keras.applications.vgg16 import preprocess_input,decode_predictions# resnet50=tensorflow.keras.applications.resnet.ResNet50(weights='imagenet')
class ResNetBasicBlock(tf.keras.Model):def __init__(self,filter_size,stride=1):#对父类进行初始化super(ResNetBasicBlock,self).__init__()self.conv1=layers.Conv2D(filter_size,kernel_size=[3,3],strides=stride,padding='same')self.BN1=layers.BatchNormalization()self.relu1=layers.Activation('relu')self.conv2=layers.Conv2D(filter_size,kernel_size=[3,3],strides=[1,1],padding='same')self.BN2=layers.BatchNormalization()if stride!=1:self.SubSampling=keras.Sequential([layers.Conv2D(filter_size,kernel_size=[1,1],strides=stride)])else:self.SubSampling=lambda x:xdef call(self,inputs,training=None):x=self.conv1(inputs)x=self.BN1(x)x=self.relu1(x)x=self.conv2(x)x=self.BN2(x)identify=self.SubSampling(inputs)out_x=layers.add([identify,x])out_x=tf.nn.relu(out_x)return out_xclass ResNet(tf.keras.Model):def __init__(self,layer_nums,num_classes=1000):super(ResNet,self).__init__()self.Input=keras.Sequential([layers.Conv2D(64, kernel_size=[7,7], strides=[2,2],padding='same'),layers.BatchNormalization(),layers.Activation('relu'),layers.MaxPool2D(pool_size=[3,3],strides=[2,2],padding='same')])self.layer1=self.build_BasicBlock(64,layer_nums[0],stride=1)self.layer2=self.build_BasicBlock(128,layer_nums[1],stride=2)self.layer3=self.build_BasicBlock(256,layer_nums[2],stride=2)self.layer4=self.build_BasicBlock(512,layer_nums[3],stride=2)self.Globavgpooling=layers.GlobalAveragePooling2D()self.Dense=layers.Dense(num_classes)self.softmax=layers.Activation('softmax')def build_BasicBlock(self,filter_size,layer_num,stride):res_block=keras.Sequential([ResNetBasicBlock(filter_size,stride)])for i in range(1,layer_num):res_block.add(ResNetBasicBlock(filter_size,stride=1))return res_blockdef call(self,inputs,training=None):x=self.Input(inputs)x=self.layer1(x)x=self.layer2(x)x=self.layer3(x)x=self.layer4(x)x=self.Globavgpooling(x)x=self.Dense(x)out_x=self.softmax(x)return out_xmodel_renset18=ResNet([2,2,2,2])
model_renset18.build(input_shape=(None,224,224,3))
model_renset18.summary()
model_renset34=ResNet([3,4,6,3])
model_renset34.build(input_shape=(None,224,224,3))
model_renset34.summary()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)ResNet50结构:

在这里插入图片描述

import keras
import  numpy as np
import  tensorflow as tf
from tensorflow.keras import layers
import tensorflow.keras.applications.resnet
from tensorflow.keras.applications.vgg16 import preprocess_input,decode_predictions# resnet50=tensorflow.keras.applications.resnet.ResNet50(weights='imagenet')
class ResNetBasicBlock(tf.keras.Model):def __init__(self,filter_size,stride=1):#对父类进行初始化super(ResNetBasicBlock,self).__init__()self.conv1=layers.Conv2D(filter_size,kernel_size=[1,1],strides=stride,padding='same')self.BN1=layers.BatchNormalization()self.relu1=layers.Activation('relu')self.conv2=layers.Conv2D(filter_size,kernel_size=[3,3],strides=[1,1],padding='same')self.BN2=layers.BatchNormalization()self.relu2=layers.Activation('relu')self.conv2 = layers.Conv2D(filter_size*4, kernel_size=[1,1], strides=[1, 1], padding='same')self.BN2 = layers.BatchNormalization()if stride!=1:self.SubSampling=keras.Sequential([layers.Conv2D(filter_size*4,kernel_size=[1,1],strides=stride)])else:self.SubSampling=keras.Sequential([layers.Conv2D(filter_size*4,kernel_size=[1,1],strides=[1,1])])def call(self,inputs,training=None):x=self.conv1(inputs)x=self.BN1(x)x=self.relu1(x)x=self.conv2(x)x=self.BN2(x)x=self.relu2(x)identify=self.SubSampling(inputs)out_x=layers.add([identify,x])out_x=tf.nn.relu(out_x)return out_xclass ResNet(tf.keras.Model):def __init__(self,layer_nums,num_classes=1000):super(ResNet,self).__init__()self.Input=keras.Sequential([layers.Conv2D(64, kernel_size=[7,7], strides=[2,2],padding='same'),layers.BatchNormalization(),layers.Activation('relu'),layers.MaxPool2D(pool_size=[3,3],strides=[2,2],padding='same')])self.layer1=self.build_BasicBlock(64,layer_nums[0],stride=1)self.layer2=self.build_BasicBlock(128,layer_nums[1],stride=2)self.layer3=self.build_BasicBlock(256,layer_nums[2],stride=2)self.layer4=self.build_BasicBlock(512,layer_nums[3],stride=2)self.Globavgpooling=layers.GlobalAveragePooling2D()self.Dense=layers.Dense(num_classes)self.softmax=layers.Activation('softmax')def build_BasicBlock(self,filter_size,layer_num,stride):res_block=keras.Sequential([ResNetBasicBlock(filter_size,stride)])for i in range(1,layer_num):res_block.add(ResNetBasicBlock(filter_size,stride=1))return res_blockdef call(self,inputs,training=None):x=self.Input(inputs)x=self.layer1(x)x=self.layer2(x)x=self.layer3(x)x=self.layer4(x)x=self.Globavgpooling(x)x=self.Dense(x)out_x=self.softmax(x)return out_xmodel_renset50=ResNet([3,4,6,3])
model_renset50.build(input_shape=(None,224,224,3))
model_renset50.summary()

在这里插入图片描述


6.测试设计的网络结构(进行图片数据集的训练)

关于数据集和训练的代码参考这篇文章:
https://mydreamambitious.blog.csdn.net/article/details/123966676
只需要将代码中的网络结构换成上面的这个InceptionV1结构即可训练。但是有一点要注意就是我给出的这个网络结构最后输出类别为1000,而训练数据集的代码只有两个类别。


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

相关文章

ResNet网络结构详解,网络搭建,迁移学习

前言: 参考内容来自up:6.1 ResNet网络结构,BN以及迁移学习详解_哔哩哔哩_bilibili up的代码和ppt:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing 一、简介 ResNet 网络是在 2015年 由微软实验室提出&#xf…

ResNet网络结构详解与模型的搭建

ResNET(Deep Residual Learning for Image Recognition ) ResNet网络是在2015年由微软实验室提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。下图是ResNet34层模型的结构简图。…

Resnet网络结构图和对应参数表的简单理解

Resnet Resnet即就是残差网络,本文主要是对于resnet给出的网络结构图进行简单解释。 网络结构图 以上就是34层网络的网络结构图。 以上是18层、34层、50层、101层以及152层网络所对应的残差块。 我刚开始在网上看到这两张图片的时候,感觉一点都不懂&a…

pytorch Resnet 网络结构

最近在学习廖老师的pytorch教程,学到Resnet 这部分着实的烧脑,这个模型都捣鼓了好长时间才弄懂,附上我学习过程中最为不解的网络的具体结构连接(网上一直没有找到对应网络结构,对与一个自学的学渣般的我,很…

ResNet网络结构解析--Pytorch

ResNet101–DSSD/SSD (1)ResNet在Pytorch官方代码中有5种不同深度的结构,分别为18、34、50、101、152(各网络深度指的是“需要通过训练更新参数“的层数,如卷积层,全连接层等),和论…

ResNet网络结构详解及代码复现

1. ResNet论文详解 1.1. Introduction 一般网络越深&#xff0c;特征就越丰富&#xff0c;模型效果也就越好。在深度重要的驱动下&#xff0c;出现了2个问题&#xff1a; 梯度消失和梯度爆炸&#xff1a; 梯度消失&#xff1a;误差梯度<1&#xff0c;当网络层数增多时&…

resnet50网络结构_pytorch实践(改造属于自己的resnet网络结构并训练二分类网络)

我的CSDN博客:https://blog.csdn.net/litt1e 我的公众号:工科宅生活 在学习pytorch过程中,突然想拥有属于自己的网络结构,于是便自己选择了一个比较简单的resnet18进行改造,并用其对蚂蚁和蜜蜂进行分类,比较一下没有经过预训练的resnet18好还是自己改造的resnet_diy好。 …

【DL系列】ResNet网络结构详解、完整代码实现

Name&#xff1a; Deep Residual Learning for Image Recognition Author&#xff1a; 何恺明团队 Publiced&#xff1a; 2015.12_CVPR 文章目录 前言1. 残差网络待解决的问题2. ResNet模型亮点 ResNet模型结构1. 残差学习2. Residual模块3. ResNet模型 ResNet-layers模型完整代…

pytorch实现resnet网络结构

ResNet结构和pytorch实现 resnet的网络结构都是经过5个不同数量的残差块最后一个全连接分类完成的。 在resnet50以后&#xff0c;由于层数的增加残差块发生了变化&#xff0c;从原来3x3卷积变为三层卷积&#xff0c;卷积核分别为1x1、3x3、1x1&#xff0c;减少了网络参数。主…

ResNet网络结构搭建

ResNet 下图为包含有18层(17个卷积层和1个全连接层)、34层(33个卷积层和1个全连接层)、50层(49个卷积层和1个全连接层)、101层(100个卷积层和1个全连接层)、152层(151个卷积层和1个全连接层)的resnet结构 下图是论文中给出的两种残差结构。左边的残差结构是针对层数较少网络&a…

ResNet网络结构

注&#xff1a;深度好像就是channel w*h*c 根据b站up霹雳吧啦的讲解做的笔记 视频地址6.1 ResNet网络结构&#xff0c;BN以及迁移学习详解_哔哩哔哩_bilibiliR 6.2 使用pytorch搭建ResNet并基于迁移学习训练_哔哩哔哩_bilibili ResNet网络解决梯度消失、爆炸&#xff0c;以及…

经典网络ResNet介绍

经典网络ResNet(Residual Networks)由Kaiming He等人于2015年提出&#xff0c;论文名为《Deep Residual Learning for Image Recognition》&#xff0c;论文见&#xff1a;https://arxiv.org/pdf/1512.03385.pdf ResNet要解决的是深度神经网络的”退化(degradation)”问题&…

六、ResNet网络详细解析(超详细哦)

1、 RestNet网络 1.1、 RestNet网络结构 ResNet在2015年被提出&#xff0c;在ImageNet比赛classification任务上获得第一名&#xff0c;因为它“简单与实用”并存&#xff0c;之后很多方法都建立在ResNet50或者ResNet101的基础上完成的&#xff0c;检测&#xff0c;分割&…

ResNet结构

文章目录 系列文章目录一、Residual net(残差网络)二、BatchNormalization(BN)三、ResNet结构 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开…

深度学习之图像分类(七)--ResNet网络结构

深度学习之图像分类&#xff08;七&#xff09;ResNet 网络结构 目录 深度学习之图像分类&#xff08;七&#xff09;ResNet 网络结构1. 前言2. Residual3. 网络配置4. 代码 本节学习ResNet网络结构&#xff0c;以及迁移学习入门&#xff0c;学习视频源于 Bilibili&#xff0c;…

[NCTF2019]SQLi 1regexp注入

[NCTF2019]SQLi&regexp注入 知识点&#xff1a; 无引号闭合&#xff0c;可以利用转义符 \ %00作为截断字符可以代替注释符#和-- - regexp注入可以配合 ^ 来爆破字符 解题&#xff1a; 打开题目得到&#xff1a; 可以看做插入语句&#xff1a; select * from users where…

buuctf-[NCTF2019]Keyboard

题目是这样子的&#xff1a; 下载完压缩包并解压后打开txt文件&#xff0c;发现是这样一串密文&#xff1a; 其实答案就在问题题目中&#xff0c;keyboard是键盘的意思&#xff0c;那结果显而易见了&#xff0c;o y i w u e u y u w u i i e不难发现&#xff0c;这些字母在键盘…

NCTF Crypto WriteUp

http://ctf.nuptzj.cn/challenges Crypto篇&#xff1a; 第一题、第二题、第七题和CG-CTF一样&#xff0c;不写了… 第三题&#xff1a; 说了全家桶&#xff0c;那就python跑吧… Flag&#xff1a;nctf{base64_base32_and_base16} 150分到手 第四题&#xff1a; 鬼知道进行…

[NCTF2019]Fake XML cookbook

BUUCTF 刷题 [NCTF2019]Fake XML cookbook BUUCTF 刷题前言一、[NCTF2019]Fake XML cookbook总结 前言 通过刷题拓宽自己的知识面 一、[NCTF2019]Fake XML cookbook &#xff08;1&#xff09;打开后如图所示 &#xff08;2&#xff09;尝试了一下万能密码&#xff0c;没啥用…

[NCTF2019]True XML cookbook

打开环境&#xff0c;看到熟悉的页面&#xff0c;和前面的[NCTF2019]Fake XML cookbook页面一样&#xff0c;应该也是XXE漏洞&#xff0c;这里再介绍一下XXE漏洞&#xff1a; XXE(XML External Entity Injection)全称为XML外部实体注入。 XML是什么&#xff1f; XML指可扩展…