小言_互联网的博客

365天深度学习训练营-第J1周:ResNet-50算法实战与解析

404人阅读  评论(0)

目录

 一、前言

二、论文分析

三、残差网络(ResNet)介绍

1、残差网络解决了什么

2、ResNet-50介绍

 四、构造ResNet-50模型

1、Tensorflow代码

2、Pytorch代码


 一、前言


  
  1. ● 难度:夯实基础⭐⭐
  2. ● 语言:Python 3、Pytorch 3
  3. ● 时间: 25日- 210
  4. 🍺要求:
  5. 1.根据本文的Tensorflow代码,编写Pytorch代码
  6. 2.了解残差网络
  7. 3.是否可以将残差模块融合到C 3

二、论文分析

论文:Deep Residual Learning for Image Recognition

问题的提出:

随着网络层数的增加,更深的网络具有更大的训练误差,从而导致测试误差。

所以提出了一个问题:对叠层数越多是不是训练网络效果越好呢?

这种问题的阻碍是梯度消失或者爆炸,而这种我们的解决办法是:初始化归一和中间层归一化

随着网络深度的增加,精度变得饱和,然后迅速退化,但是这种退化不是由于过度拟合引起的,这也就成为了模型训练退化问题。像适当深度的模型添加更多层会导致更高的训练误差。解决这种误差是这篇论文的主要目的。

解决方案一:添加的层是身份映射,其他层是从学习中较浅的模型复制,但是现有的解释器很难做

解决方案二:引入深度残差学习框架来解决这种退化问题。

将所需的基础映射表示为H(x)

让堆叠的非线性层适合F(x):= H(x)- x的另一个映射。

原始映射为F(x)+ x。 

通过快捷连接来实现身份验证。

实验证明:

1)极深的残差网络易于优化,但是当深度增加时,对应的“普通”网络(简单地堆叠层)显示出更高的训练误差;

2)深层残差网络可以通过大大增加深度来轻松享受准确性的提高,所产生的结果比以前的网络要好得多。

Deep Residual Learning 

残差学习:

       将H(x)视为由一些堆叠层(不一定是整个网络)拟合的基础映射,其中x表示这些层中第一层的输入。如果假设多个非线性层可以渐近逼近复杂函数,那么就可以假设它们可以渐近逼近残差函数,即H(x)-x(假设输入和输出为尺寸相同)。因此,没有让堆叠的层近似为H(x),而是明确地让这些层近似为残差函数F(x):= H(x)-x。因此,原始函数变为F(x)+ x。尽管两种形式都应能够渐近地逼近所需的功能(如假设),但学习的难易程度可能有所不同。

简单来讲:

整个模块除了正常的卷积层输出外,还有一个分支把输入直接连在输出上,该分支输出和卷积的输出做算数相加得到了最终的输出,这种残差结构人为的制造了恒等映射,即F(x)分支中所有参数都是0,H(x)就是一个恒等映射,这样就能让整个结构朝着恒等映射的方向去收敛,确保最终的错误率不会因为深度的变大而越来越差。

假设我们现在已经有了一个N层的网络,现在在尾部加上K个残差模块(M层),

如果说这K个残差会造成网络过深,那么这K个残差模块会向恒等映射方向发展(参数为0),进而解决了网络过深问题

网络框架

实验结果

 可以明显看到在用ResNet之后,随着网络深度的增加,网络的训练效果更好。

三、残差网络(ResNet)介绍

1、残差网络解决了什么

残差网络是为了解决神经网络隐藏层过多时,而引起的网络退化问题。退化(degradation)问题是指:当网络隐藏层变多时,网络的准确度达到饱和然后急剧退化,而且这个退化不是由于过拟合引起的。

拓展:深度神经网络的"两朵乌云"

  • 梯度弥散/爆炸

简单来讲就是网络太深了,会导致模型训练难以收敛。这个问题可以被标准初始化和中间层正规化的方法有效控制。

  • 网络退化

随着网络深度增加,网络的表现先是逐渐增加至饱和,然后迅速下降,这个退化不是由过拟合引起的。

2、ResNet-50介绍

ResNet-50有两个基本的块,分别名为Conv BlockIdentity Block

Conv Block结构:

Identity Block结构:

ResNet-50总体结构:

 四、构造ResNet-50模型

1、Tensorflow代码


  
  1. def identity_block( input_ten,kernel_size,filters):
  2. filters1,filters2,filters3 = filters
  3. x = Conv2D(filters1,( 1, 1))(input_ten)
  4. x = BatchNormalization()(x)
  5. x = Activation( 'relu')(x)
  6. x = Conv2D(filters2,kernel_size,padding= 'same')(x)
  7. x = BatchNormalization()(x)
  8. x = Activation( 'relu')(x)
  9. x = Conv2D(filters3,( 1, 1))(x)
  10. x = BatchNormalization()(x)
  11. x = layers.add([x,input_ten])
  12. x = Activation( 'relu')(x)
  13. return x
  14. def conv_block( input_ten,kernel_size,filters,strides=(2,2)):
  15. filters1,filters2,filters3 = filters
  16. x = Conv2D(filters1,( 1, 1),strides=strides)(input_ten)
  17. x = BatchNormalization()(x)
  18. x = Activation( 'relu')(x)
  19. x = Conv2D(filters2,kernel_size,padding= 'same')(x)
  20. x = BatchNormalization()(x)
  21. x = Activation( 'relu')(x)
  22. x = Conv2D(filters3,( 1, 1))(x)
  23. x = BatchNormalization()(x)
  24. shortcut = Conv2D(filters3,( 1, 1),strides=strides)(input_ten)
  25. shortcut = BatchNormalization()(shortcut)
  26. x = layers.add([x,shortcut])
  27. x = Activation( 'relu')(x)
  28. return x
  29. def ResNet50( nb_class,input_shape):
  30. input_ten = Input(shape=input_shape)
  31. x = ZeroPadding2D(( 3, 3))(input_ten)
  32. x = Conv2D( 64,( 7, 7),strides=( 2, 2))(x)
  33. x = BatchNormalization()(x)
  34. x = Activation( 'relu')(x)
  35. x = MaxPooling2D(( 3, 3),strides=( 2, 2))(x)
  36. x = conv_block(x, 3,[ 64, 64, 256],strides=( 1, 1))
  37. x = identity_block(x, 3,[ 64, 64, 256])
  38. x = identity_block(x, 3,[ 64, 64, 256])
  39. x = conv_block(x, 3,[ 128, 128, 512])
  40. x = identity_block(x, 3,[ 128, 128, 512])
  41. x = identity_block(x, 3,[ 128, 128, 512])
  42. x = identity_block(x, 3,[ 128, 128, 512])
  43. x = conv_block(x, 3,[ 256, 256, 1024])
  44. x = identity_block(x, 3,[ 256, 256, 1024])
  45. x = identity_block(x, 3,[ 256, 256, 1024])
  46. x = identity_block(x, 3,[ 256, 256, 1024])
  47. x = identity_block(x, 3,[ 256, 256, 1024])
  48. x = identity_block(x, 3,[ 256, 256, 1024])
  49. x = conv_block(x, 3,[ 512, 512, 2048])
  50. x = identity_block(x, 3,[ 512, 512, 2048])
  51. x = identity_block(x, 3,[ 512, 512, 2048])
  52. x = AveragePooling2D(( 7, 7))(x)
  53. x = tf.keras.layers.Flatten()(x)
  54. output_ten = Dense(nb_class,activation= 'softmax')(x)
  55. model = Model(input_ten,output_ten)
  56. model.load_weights( "resnet50_weights_tf_dim_ordering_tf_kernels.h5")
  57. return model
  58. model_ResNet50 = ResNet50( 24,(img_height,img_width, 3))
  59. model_ResNet50.summary()

2、Pytorch代码


  
  1. from torch import nn
  2. class ConvBlock(nn.Module):
  3. def __init__( self, in_channel, kernel_size, filters, stride):
  4. super(ConvBlock, self).__init__()
  5. filter1, filter2, filter3 = filters
  6. self.stage = nn.Sequential(
  7. nn.Conv2d(in_channel, filter1, 1, stride=stride, padding= 0, bias= False),
  8. nn.BatchNorm2d(filter1),
  9. nn.RuLU( True),
  10. nn.Conv2d(filter1, filter2, kernel_size, stride= 1, padding= True, bias= False),
  11. nn.BatchNorm2d(filter2),
  12. nn.RuLU( True),
  13. nn.Conv2d(filter2, filter3, 1, stride= 1, padding= 0, bias= False),
  14. nn.BatchNorm2d(filter3),
  15. )
  16. self.shortcut_1 = nn.Conv2d(in_channel, filter3, 1, stride=stride, padding= 0, bias= False)
  17. self.batch_1 = nn.BatchNorm2d(filter3)
  18. self.relu_1 = nn.ReLU( True)
  19. def forward( self, x):
  20. x_shortcut = self.shortcut_1(x)
  21. x_shortcut = self.batch_1(x_shortcut)
  22. x = self.stage(x)
  23. x = x + x_shortcut
  24. x = self.relu_1(x)
  25. return x
  26. class IndentityBlock(nn.Module):
  27. def __init__( self, in_channel, kernel_size, filters):
  28. super(IndentityBlock, self).__init__()
  29. filter1, filter2, filter3 = filters
  30. self.stage = nn.Sequential(
  31. nn.Conv2d(in_channel, filter1, 1, stride= 1, padding= 0, bias= False),
  32. nn.BatchNorm2d(filter1),
  33. nn.RuLU( True),
  34. nn.Conv2d(filter1, filter2, kernel_size, padding= True, bias= False),
  35. nn.BatchNorm2d(filter1),
  36. nn.RuLU( True),
  37. nn.Conv2d(filter2, filter3, 1, stride= 1, padding= 0, bias= False),
  38. nn.BatchNorm2d(filter3),
  39. )
  40. self.relu_1=nn.ReLU( True)
  41. def forward( self, x):
  42. x_shortcut = x
  43. x = self.stage(x)
  44. x = x + x_shortcut
  45. x = self.relu_1(x)
  46. return x
  47. class ResModel(nn.Module):
  48. def __init__( self, n_class):
  49. super(ResModel, self).__init__()
  50. self.stage1 = nn.Sequential(
  51. nn.Conv2d( 3, 64, 7, stride= 2, padding= 3, bias= False),
  52. nn.BatchNorm2d( 64),
  53. nn.ReLU( True),
  54. nn.MaxPool2d( 3, 2, padding= 1),
  55. )
  56. self.stage2 = nn.Sequential(
  57. ConvBlock( 64, f= 3, filters=[ 64, 64, 256], s= 2),
  58. IndentityBlock( 256, 3, [ 64, 64, 256]),
  59. IndentityBlock( 256, 3, [ 64, 64, 256]),
  60. )
  61. self.stage3 = nn.Sequential(
  62. ConvBlock( 256, f= 3, filters=[ 128, 128, 512], s= 3),
  63. IndentityBlock( 512, 3, [ 128, 128, 512]),
  64. IndentityBlock( 512, 3, [ 128, 128, 512]),
  65. IndentityBlock( 512, 3, [ 128, 128, 512]),
  66. )
  67. self.stage4 = nn.Sequential(
  68. ConvBlock( 512, f= 3, filters=[ 256, 256, 1024], s= 4),
  69. IndentityBlock( 1024, 3, [ 256, 256, 1024]),
  70. IndentityBlock( 1024, 3, [ 256, 256, 1024]),
  71. IndentityBlock( 1024, 3, [ 256, 256, 1024]),
  72. IndentityBlock( 1024, 3, [ 256, 256, 1024]),
  73. IndentityBlock( 1024, 3, [ 256, 256, 1024]),
  74. )
  75. self.stage5 = nn.Sequential(
  76. ConvBlock( 1024, f= 3, filters=[ 512, 512, 2048], s= 5),
  77. IndentityBlock( 2048, 3, [ 512, 512, 2048]),
  78. IndentityBlock( 2048, 3, [ 512, 512, 2048]),
  79. )
  80. self.pool = nn.AvgPool2d( 7, 7, padding= 1)
  81. self.fc = nn.Sequential(
  82. nn.Linear( 8192, n_class)
  83. )
  84. def forward( self, X):
  85. out = self.stage1(X)
  86. out = self.stage2(out)
  87. out = self.stage3(out)
  88. out = self.stage4(out)
  89. out = self.stage5(out)
  90. out = self.pool(out)
  91. out = out.view(out.size( 0), 8192)
  92. out = self.fc(out)
  93. return out

转载:https://blog.csdn.net/m0_58585940/article/details/128913158
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场