当前位置: 代码迷 >> 综合 >> [tensorflow2笔记九] 使用keras复现经典卷积网络LeNet、AlexNet、VGGNet、InceptionNet、ResNet
  详细解决方案

[tensorflow2笔记九] 使用keras复现经典卷积网络LeNet、AlexNet、VGGNet、InceptionNet、ResNet

热度:92   发布时间:2023-12-14 22:10:45.0

文章目录

  • 1. LeNet
  • 2. AlexNet
  • 3. VGGNet
  • 4. InceptionNet
  • 5. ResNet

1. LeNet

LeNet卷积神经网络LeCun在1998年提出,卷积网络的开篇之作。通过共享卷积核减少了网络参数

LeNet一共有5层网络,两个卷积计算层,3个全连接层。如图C1,C3,C5,F6,Output

在这里插入图片描述
代码实现:

class LeNet(Model):def __init__(self):super(LeNet, self).__init__()self.c1 = Conv2D(filters=6, kernel_size=(5, 5), activation='sigmoid')self.p1 = MaxPool2D(pool_size=(2, 2), strides=2)self.c2 = Conv2D(filters=16, kernel_size=(5, 5), activation='sigmoid')self.p2 = MaxPool2D(pool_size=(2, 2), strides=2)self.flatten = Flatten()                            # 将来自卷积层的数据拉直self.f1 = Dense(120, activation='sigmoid')self.f2 = Dense(84, activation='sigmoid')self.f3 = Dense(10, activation='softmax')

2. AlexNet

AlexNet诞生于2012年,Hinton的代表作之一,当年ImageNet竞赛的冠军。

AlexNet使用relu激活函数,提升了训练速度;使用Dropout缓解了过拟合。

共有8层,前5层是卷积层,后3层是全连接层。

在这里插入图片描述
代码实现:

class AlexNet(Model):def __init__(self):super(AlexNet, self).__init__()self.c1 = Conv2D(filters=96, kernel_size=(3, 3))     self.b1 = BatchNormalization()                                   self.a1 = Activation('relu')                                       self.p1 = MaxPool2D(pool_size=(3, 3), strides=2)   self.c2 = Conv2D(filters=256, kernel_size=(3, 3))     self.b2 = BatchNormalization()                                   self.a2 = Activation('relu')                                       self.p2 = MaxPool2D(pool_size=(3, 3), strides=2) self.c3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same', activation='relu')                                                                   self.c4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same', activation='relu')                                      self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same',activation='relu')                                                                          self.p3 = MaxPool2D(pool_size=(3, 3), strides=2) self.flatten = Flatten()                       self.f1 = Dense(2048, activation='relu')self.d1 = Dropout(0.5)self.f2 = Dense(2048, activation='relu')self.d2 = Dropout(0.5)      self.f3 = Dense(10, activation='softmax')  

3. VGGNet

(1)理解

VGGNet是2014年ImageNet竞赛亚军。

VGGNet使用小尺寸卷积核,在减少参数的同时,提高了识别准确率。

VGGNet的网络结构规整,非常适合硬件加速。有16层和19层。

(2)结构

16层VGG网络:(CBAPD就是卷积)

CBA,CBAPD,CBA,CBAPD,
CBA,CBA,CBAPD,CBA,CBA,CBAPD,CBA,CBA,CBAPD,
Dense,Dense,Dense 依次相连

其中,卷积核的个数从64、128、256、512逐渐增加。因为越靠后,特征图尺寸越小,通过增加卷积核的个数,增加了特征图深度,保持了信息的承载能力。

4. InceptionNet

(1)理解

InceptionNet 是2014年ImageNet竞赛冠军。

InceptionNet引入了Inception结构块,在同一层网络内使用不同尺寸的卷积核,可以提取不同尺寸的特征提升了模型感知力;使用了批标准化BN,缓解了梯度消失。

核心是Inception结构块,GoogLeNet (Inception V1有22层) 等后续版本,都是基于结构块搭建的。

通过1 x 1卷积核,作用到输入特征图的每个像素点,设定少于输入特征图深度的1 x 1卷积核个数,减少了输出特征图深度,起到了降维的作用,从而减少了参数量和计算量。

如果经过四个分支输出到达卷积连接器,那么送到卷积连接器的特征数据尺寸相同,卷积连接器会把收到的这四路特征数据按深度方向拼接,形成Inception结构块的输出。

(2)结构图

在这里插入图片描述

(3)结构块

## 1.由于结构块的卷及操作都采用了CBA结构,将其定义为一个新的类ConvBNRelu
class ConvBNRelu(Model):def __init__(self, ch, kernelsz=3, strides=1, padding='same'):  # ch为输出深度super(ConvBNRelu, self).__init__()self.model = tf.keras.models.Sequential([Conv2D(ch, kernelsz, strides=strides, padding=padding), # 卷积BatchNormalization(),									# BNActivation('relu')										# 激活])def call(self, x):x = self.model(x)return x## 2.定义上图的Inception结构块
class InceptionBlk(Model):def __init__(self, ch, strides=1):super(InceptionBlk, self).__init__()self.ch = chself.strides = stridesself.c1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c2_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c2_2 = ConvBNRelu(ch, kernelsz=3, strides=1)self.c3_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c3_2 = ConvBNRelu(ch, kernelsz=5, strides=1)self.p4_1 = MaxPool2D(3, strides=1, padding='same')self.c4_2 = ConvBNRelu(ch, kernelsz=1, strides=strides)def call(self, x):x1 = self.c1(x)x2_1 = self.c2_1(x)x2_2 = self.c2_2(x2_1)x3_1 = self.c3_1(x)x3_2 = self.c3_2(x3_1)x4_1 = self.p4_1(x)x4_2 = self.c4_2(x4_1)# 使用tf.concat将各分支结果堆叠在一起,axis=3表示延深度方向堆叠x = tf.concat([x1, x2_2, x3_2, x4_2], axis=3) return x

(4)搭建InceptionNet

在这里插入图片描述
注:四个结构块相连,每两个结构块组成一个block。每个block中的第一个结构块卷积步长是2,第二个结构块步长是1,于是第一个结构块的输出特征图尺寸减半,因此把输出特征图深度加深,尽可能保持特征抽取中信息的承载量一致。

5. ResNet

(1)理解

ResNet诞生于2015年,何凯明,当年ImageNet竞赛冠军。

单纯堆叠神经网络层数,会使神经网络模型退化,以至于后边的特征丢失了前边特征的原本模样。使用一根跳连线,将前边的特征直接接到后边,使得输出结果包含了堆叠卷积的非线性输出,和跳过这层堆叠卷积直接连接过来的恒等映射,对应元素相加。

ResNet提出了层间残差跳连,引入了前方信息,缓解梯度消失,使得神经网络层数增加成为可能。

(2)ResNet块

ResNet块分两种:

·堆叠卷积没有改变特征图的维度(特征图的个数、高、宽和深度都相同),可直接相加,跳连线使用实线。

·堆叠卷积改变了特征图维度,跳连线使用虚线,需要借助1 x 1的卷积来调整恒等映射的维度,使得维度一致。

在这里插入图片描述
代码实现resnet块

class ResnetBlock(Model):def __init__(self, filters, strides=1, residual_path=False): super(ResnetBlock, self).__init__()self.filters = filters		# 卷积核的个数self.strides = strides		# 卷积核步长self.residual_path = residual_path	# residual_path维度是否相同self.c1 = Conv2D(filters, (3, 3), strides=strides,padding='same',use_bias=False)self.b1 = BatchNormalization()self.a1 = Activation('relu')self.c2 = Conv2D(filters, (3, 3), strides=1, padding='same', use_bias=False)self.b2 = BatchNormalization()if residual_path:self.down_c1 = Conv2D(filters, (1, 1), strides=strides, padding='same', use_bias=False)self.down_b1 = BatchNormalization()self.a2 = Activation('relu')def call(self, inputs):residual = inputsx = self.c1(inputs)x = self.b1(x)x = self.a1(x)x = self.c2(x)y = self.b2(x)if self.result_path:residual = self.down_c1(inputs)residual = self.down_b1(residual)out = self.a2(y + residual)		# 合并输出return out

注意:Inception块的“+”:是多分支输出结果按深度一层层叠加。
ResNet块的“+”:是对应元素相加,数值相加。

(3)搭建ResNet

1个卷积、8个resnet块、池化、1个全连接

在这里插入图片描述

  相关解决方案