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

您所在的位置:网站首页 resnet网络结构详解 ResNet网络结构详解(Tensorflow2.6.0实现网络结构)

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

#ResNet网络结构详解(Tensorflow2.6.0实现网络结构)| 来源: 网络整理| 查看: 265

文章目录

* – 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

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)以下图片中的网络结构方式使用pytorch实现最好,因为在tensorflow中的padding=’same’或者padding=’valid’,不能自定义。但是在本篇文章中将使用tensorflow实现ResNet网络结构。可以看这篇博文: https://mydreamambitious.blog.csdn.net/article/details/124077928类似使用pytorch实现自定义padding的网络结构(AlexNet) ; (2)ResNet18网络结构:

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)图片来自:https://blog.csdn.net/qq_37080185/article/details/120484553 (3)ResNet34网络结构:

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构) ; 2.卷积神经网络的发展 (1).卷积神经网络的发展:

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

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

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

3.ResNet18网络结构讲解 (1)输入图片:

224x224x3

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

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

卷积操作:卷积采用步长为2,卷积核大小为7×7的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(224+2×3-7)/2+1=112 输出大小:112x112x64池化操作:池化单元采用3×3大小,步长为2:output_size=(input_size+2×1-3)/2+1=56 输出大小为:56x56x64

; (3)第一组conv2_x:

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

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

(4)第一组conv3_x:

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)第一步的卷积操作:卷积采用步长为2,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(56+2×1-3)/2+1=28 输出大小:28x28x128第二步的卷积操作:卷积采用步长为1,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(28+2×1-3)/1+1=28 输出大小:28x28x128第三步identity:第二步卷积之后通道数已经升维到了128;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1×1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。 ; (5)第一组conv4_x:

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)第一步的卷积操作:卷积采用步长为2,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(28+2×1-3)/2+1=14 输出大小:14x14x256第二步的卷积操作:卷积采用步长为1,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(14+2×1-3)/1+1=14 输出大小:14x14x256第三步identity:第二步卷积之后通道数已经升维到了256;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1×1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。 (6)第一组conv5_x:

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

第一步的卷积操作:卷积采用步长为2,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(14+2×1-3)/2+1=7 输出大小:7x7x512第二步的卷积操作:卷积采用步长为1,卷积核大小为3×3的卷积操作:ouput_size=(input_size+2xpadding-kernel_size)/stride+1=(7+2×1-3)/1+1=7 输出大小:7x7x512第三步identity:第二步卷积之后通道数已经升维到了512;因为这里需要进行恒等映射,所以这里需要将原来的输入x进行1×1的卷积,步长为2进行升维,将通维度升到和第二步卷积输出相同。

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

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构) 4.相关问题和思考 (1)2.既然更深的网络可以提取到更多的特征,为什么人们不直接堆叠卷积层,使得网络的深度更深,从而提取到更多的特征呢?

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

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

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

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

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

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

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

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)ResNet网络结构详解(Tensorflow2.6.0实现网络结构)使用三种方式解决这个问题,上面的A,B,C分别代表三种方式的实验结果:A——所有的shortcut无额外的参数,升维时采用padding补零的方式;B——普通的shortcut使用identify mapping(恒等映射)升维时使用1×1卷积升维;C——所有的shortcut都使用1×1卷积升维; (a)A,B,C三种方式都比不带残差模块的模型都要好;其中A在升维的时候直接使用补零的方式,所以相当于丢失了shortcut分支的信息,没有进行残差学习; (b)C的13个非下采样模块的shortcut都有参数,模型的表达能力更强; (c)可以看到上面的三种方式中,C方式虽然是最好的,但是却引入的额外的参数量,所以这种方式并不是最适合的。说明identify mapping(恒等映射)已经足够解决shortcut问题。 ; (4)为什么ResNet结构可以有效解决因网络层数增加而导致模型难以训练的问题?

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)参考博文:https://blog.csdn.net/weixin_44815085/article/details/104348749 (5)拓展

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

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

ResNet网络结构详解(Tensorflow2.6.0实现网络结构) 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:x 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) identify=self.SubSampling(inputs) out_x=layers.add([identify,x]) out_x=tf.nn.relu(out_x) return out_x class 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_block def 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_x model_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()

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

ResNet网络结构详解(Tensorflow2.6.0实现网络结构) 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_x class 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_block def 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_x model_renset50=ResNet([3,4,6,3]) model_renset50.build(input_shape=(None,224,224,3)) model_renset50.summary()

ResNet网络结构详解(Tensorflow2.6.0实现网络结构) 6.测试设计的网络结构(进行图片数据集的训练)

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

Original: https://blog.csdn.net/Keep_Trying_Go/article/details/124203294Author: Keep_Trying_GoTitle: ResNet网络结构详解(Tensorflow2.6.0实现网络结构)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/24052/

转载文章受原作者版权保护。转载请注明原作者出处!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3