ResNet网络结构详解(Tensorflow2.6.0实现网络结构)
文章目录
- 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个类别概率:
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,而训练数据集的代码只有两个类别。
ResNet网络结构详解(Tensorflow2.6.0实现网络结构)相关推荐
- 深度残差网络(ResNet)详解与实现(tensorflow2.x)
深度残差网络(ResNet)详解与实现(tensorflow2.x) ResNet原理 ResNet实现 模型创建 数据加载 模型编译 模型训练 测试模型 训练过程 ResNet原理 深层网络在学习任 ...
- pytorch图像分类篇:6. ResNet网络结构详解与迁移学习简介
前言 最近在b站发现了一个非常好的 计算机视觉 + pytorch 的教程,相见恨晚,能让初学者少走很多弯路. 因此决定按着up给的教程路线:图像分类→目标检测→-一步步学习用pytorch实现深度学 ...
- ResNet网络详解与keras实现
ResNet网络详解与keras实现 ResNet网络详解与keras实现 Resnet网络的概览 Pascal_VOC数据集 第一层目录 第二层目录 第三层目录 梯度退化 Residual Lear ...
- ResNet网络详解并使用pytorch搭建模型、并基于迁移学习训练
1.ResNet网络详解 网络中的创新点: (1)超深的网络结构(突破1000层) (2)提出residual模块 (3)使用Batch Normalization加速训练(丢弃dropout) (1 ...
- GoogLeNet网络结构详解及代码复现
1. GoogLeNet论文详解 Abstract: 提出了GoogLeNet网络结构--22层,此设计允许在保证计算预算不变的前提下,增加网络的深度和宽度,这个网络结构是基于Hebbian原则和多尺 ...
- AlexNet网络结构详解与代码复现
参考内容来自up:3.1 AlexNet网络结构详解与花分类数据集下载_哔哩哔哩_bilibili up主的CSDN博客:太阳花的小绿豆的博客_CSDN博客-深度学习,软件安装,Tensorflow领 ...
- U-Net网络结构详解
U-Net网络结构详解 U-Net网络结构是对称的,由于网络结构像U型,所以被命名为U-Net.整体而言,U-Net是一个Encoder-Decoder(编码器-解码器)的结构,这一点是与FCN的结构 ...
- ResNet结构详解
ResNet结构详解 ResNet的层数34,50,101到底指什么? 首先看ResNet34的对比图 然后再看这个表 ResNet 到底是个什么结构 ResNet-34 虚线结构 ResNet-50 ...
- 深度学习之目标检测(五)-- RetinaNet网络结构详解
深度学习之目标检测(五)-- RetinaNet网络结构详解 深度学习之目标检测(五)RetinaNet网络结构详解 1. RetinaNet 1.1 backbone 部分 1.2 预测器部分 1. ...
- AlexNet网络结构详解(含各层维度大小计算过程)与PyTorch实现
AlexNet网络结构详解(含各层维度大小计算过程)与PyTorch实现 1.AlexNet之前的思考 2.AlexNet网络结构 3.AlexNet网络结构的主要贡献 4.PyTorch实现 ...
最新文章
- Analysis and Design Overview
- 【收藏】在QGIS中导入GOOGLE、BING等地图和卫星影像(插件方式和XYZ方式)
- 读WAF与IPS的区别总结之摘抄
- SHA-1退休:数千万用户通向加密网站之路被阻
- 重载session存储方式–session_set_save_handler()
- 【Flink】部分task每秒处理速度为0
- python爬小说目录_【python入门爬虫】爬取笔趣阁小说
- android标签循环,iOS和Android规范解析——标签导航和分段控件
- Django 模板标签[转]
- WinForm 进度条简单实现
- 机械工程c语言第一学期考试题,科学出版社机械工程图学习题集1~10章答案.ppt
- 全网最全测试工程师 学习网站汇总(测试必备 抓紧收藏)
- java生成一年中假日表(包括周末和法定假期),用于计算一年中的工作日
- Istio Egress Gateway出口流量管理
- JavaScript 中的事件类型1(读书笔记思维导图)
- 05-现代威胁环境下的10个SIEM用例
- 计算机仿真相关文献有哪些,计算机仿真技术研究论文
- 平板电脑服务器的安装系统安装系统安装系统,苹果平板电脑怎么重装系统 苹果平板电脑重装系统方法【详解】...
- 磨金石教育摄影技能干货分享|古风人像拍摄要注意哪些问题
- 0x30数学知识(0x38 概率与数学期望)例题3:扑克牌(题解)
热门文章
- Redis 连接命令
- 民宿营销方案,解决民宿运营三大痛点
- 替代亿图的软件-mac,windows都可用
- 方方格子access_有哪些好用能提高工作效率的 Excel 插件(或 Office 办公插件)值得推荐?...
- 基于pytorch-openpose框架的的人体姿态检测
- Photoshop CS2 视频教程-PS色板(转)
- 大一大学计算机期末考试题库,大学计算机基础 大一 考试必备题库
- UI美化APICLOUD千月影视APP源码
- java正则表达式yyyymmdd_正则表达式校验YYYYMMDD日期格式
- Java之实现简单中文笔画验证码