深度学习 机器视觉 经典卷积神经网络 Tensorflow2.0 keras.applications

本文详细介绍了深度学习中经典的卷积神经网络,如VGG16、VGG19、ResNet、InceptionV3、InceptionResNetV2、Xception、MobileNet以及DenseNet。这些模型通过在ImageNet数据集上的训练,展示了在图像识别任务中的优异性能。特别是ResNet通过残差学习解决了深度网络的退化问题,而Inception系列网络则通过多尺度处理和深度可分离卷积实现了高效计算。MobileNetV2则通过Inverted Residual Block进一步优化了计算效率。文章还提供了在TensorFlow2.0中复现这些模型的代码链接。

前言:
最近在学习深度学习时发现各类经典网络成为高频词,比如AlexNet、VGG、GoogLeNet、Inception、Xception、ResNet、MobileNet、SENet、CBAM、DenseNet、NASNet等等。快速整理了如下内容,为大家快速了解经典网络的结构特点提供一个参考。
由于博主能力有限,内容大多引自网络博客,并未严格考证如有错误之处望予以指出,后续也会逐步修正和补充一些实现后的代码。

背景

自2012至今近十年的深度学习发展中,机器视觉领域涌现了一大批性能突出的深度卷积神经网络结构。这些经典网络就好比我们在烹饪深度学习这道美食的不可获取的重要食材,了解并掌握不同结构的特点和基本原理,为我们活学活用卷积神经网络,快速应用于实践中,能够起到事半功倍的效果。
但由于大型神经网络规模巨大,个人电脑难以实现大规模数据集合的模型训练。Tensorflow.Keras.applications中便提供了不少基于ImageNet完成训练的经典网络模型和权值。基于大规模图像数据集训练的卷积神经网络被认为具有突出的图像特征提取的功能,被广泛应用于图像分类、语义分割、人脸识别和目标检测等实际场景中。
希望借此文,方便大家一窥经典深度卷积网络,并站在经典网络的肩膀上迅速开展自己的研究。

Keras.applications

如下,Keras官网提供了近二十组经典网络模型和权重参数。借此内容按照时间顺序展开进行介绍。
在这里插入图片描述
官网链接

VGG16

背景 (2014)

VGG是Oxford的Visual Geometry Group的组提出的(大家应该能看出VGG名字的由来了)在2014年提出来的模型。当这个模型被提出时,由于它的简洁性和实用性,马上成为了当时最流行的卷积神经网络模型。它在图像分类和目标检测任务中都表现出非常好的结果。
VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)。对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核是优于采用大的卷积核,因为多层非线性层可以增加网络深度来保证学习更复杂的模式,而且代价还比较小(参数更少)

网络结构

在这里插入图片描述
在这里插入图片描述
VGG16包含了16个隐藏层(13个卷积层和3个全连接层)
VGG网络的结构非常一致,从头到尾全部使用的是3x3的卷积和2x2的max pooling

结果

在这里插入图片描述

讨论

VGG优点

  • VGGNet的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)。
  • 几个小滤波器(3x3)卷积层的组合比一个大滤波器(5x5或7x7)卷积层好
  • 验证了通过不断加深网络结构可以提升性能。

VGG缺点

VGG耗费更多计算资源,并且使用了更多的参数(这里不是3x3卷积的锅),导致更多的内存占用(140M)。其中绝大多数的参数都是来自于第一个全连接层。VGG可是有3个全连接层啊!

参考

论文:Very Deep Convolutional Networks for Large-Scale Image Recognition.
代码的github链接:https://github.com/liuzhuang13/DenseNet
参考博文: https://github.com/machrisaa/tensorflow-vgg

VGG19

网络结构

在这里插入图片描述
在这里插入图片描述
VGG19包含了19个隐藏层(16个卷积层和3个全连接层)

TF2.0代码复现

https://blog.youkuaiyun.com/Forrest97/article/details/106135431

参考

论文:Very Deep Convolutional Networks for Large-Scale Image Recognition.
参考博文: https://github.com/machrisaa/tensorflow-vgg

ResNet

背景(2015)

深度卷积网络在图像分类任务上取得了一系列突破。深度网络通过多层端到端的方式,集成了低中高三个层次的特征和分类器,并且这些特征的数量还可以通过堆叠层数来增加。在ImageNet数据集上获胜的网络揭示了网络深度的重要性。
随着网络层数的增加,训练的问题随之凸显。比较显著的问题有梯度消失/爆炸,这会在一开始就影响收敛。收敛的问题可以通过正则化来得到部分的解决。
在深层网络能够收敛的前提下,随着网络深度的增加,正确率开始饱和甚至下降,称之为网络的退化(degradation)问题。 示例可见Figure 1. 显然,56层的网络相对于20层的网络,不管是训练误差还是测试误差都显著增大。
在这里插入图片描述
很明显,这些退化并不是过拟合造成的。在给定的网络上增加层数会增大训练误差。 网络的退化说明不是所有的系统都很容易优化。考虑一个浅层的网络架构和在它基础上构建的深层网络,在极端条件下,如果增加的所有层都是前一层的直接复制(即y=x),这种情况下深层网络的训练误差应该和浅层网络相等。因此,网络退化的根本原因还是优化问题。 为了解决优化的难题,提出了残差网络。

网络结构

ResNet 通过在卷积层的输入和输出之间添加Skip Connection 实现层数回退机制,如下
图 所示,输入𝑥通过两个卷积层,得到特征变换后的输出ℱ(𝑥),与输入𝑥进行对应元
素的相加运算,得到最终输出
ℋ(𝑥) = 𝑥 + ℱ(𝑥)
ℋ(𝑥)叫做残差模块(Residual Block,ResBlock)。由于被Skip Connection 包围的卷积神经网络需要学习映射ℱ(𝑥) = ℋ(𝑥) − 𝑥,故称为残差网络。
在这里插入图片描述
为了能够满足输入𝑥与卷积层的输出ℱ(𝑥)能够相加运算,需要输入𝑥的shape 与ℱ(𝑥)的shape 完全一致。当出现shape 不一致时,一般通过在Skip Connection 上添加额外的卷积运算环节将输入𝑥变换到与ℱ(𝑥)相同的shape,如图 10.63 中identity(𝑥)函数所示,其中identity(𝑥)以1x1 的卷积运算居多,主要用于调整输入的通道数。
下图 对比了34 层的深度残差网络、34 层的普通深度网络以及19 层的VGG 网络结构。可以看到,深度残差网络通过堆叠残差模块,达到了较深的网络层数,从而获得
了训练稳定、性能优越的深层网络。
在这里插入图片描述
在这里插入图片描述

结果

分别使用18层的plain nets和34层的plain nets,结果显示34层的网络有更高的验证误差。下图比较了整个过程的训练和测试误差:
在这里插入图片描述
注:细实线代表训练误差,粗实线代表验证误差。左侧为plain nets,右侧为ResNet。 这种优化上的困难不是由于梯度消失造成的,因为在网络中已经使用了BN,保证了前向传播的信号有非零的方差。猜想深层的神经网络的收敛几率随着网络层数的加深,以指数的形式下降,导致训练误差很难降低
测试18层和34层的ResNet。注意到34层的训练和测试误差都要比18层的小。这说明网络退化的问题得到了部分解决,通过加深网络深度,可以提高正确率。注意到18层的plain net和18层的ResNet可以达到相近的正确率,但是ResNet收敛更快。这说明网络不够深的时候,SGD还是能够找到很好的解。

Identity vs. Projection Shortcuts
比较了三种选择:
(A)zero-padding shortcuts用来增加维度(Residual block的维度小于输出维度时,使用0来进行填充),所有的shortcut无参数。
(B)projection shortcuts用来增加维度(维度不一致时使用),其他的shortcut都是恒等映射(identity)类型。
(C)所有的shortcut都是使用projection shortcuts。

在这里插入图片描述
结果表明,这三种选择都有助于提高正确率。其中,B比A效果好,原因可能是A中zero-padded的维度没有使用残差学习。C比B效果好,原因可能是projection shortcuts中引入的参数。但是ABC中的结果表明,projection shortcuts对于解决网络的退化问题是没有作用的,对于正确率的提升作用也十分有限。所以,从减少模型参数,降低复杂度的角度考虑,使用Identity shortcuts就已经足够了。

Deeper Bottleneck Architectures.
在探究更深层网络性能的时候,处于训练时间的考虑,我们使用bottleneck design的方式来设计building block。对于每一个残差函数FF,使用一个三层的stack代替以前的两层。这三层分别使用1×1, 3×3, 和 1×1的卷积。其中,1×1卷积用来降维然后升维,即利用1×1卷积解决维度不同的问题。3×3对应一个瓶颈(更少的输入、输出维度)。Fig.5 展示了这种设计。
在这里插入图片描述
50、101和152层的ResNet相对于32层网络有更高的准确率。Table3和4中给出了测试结果。
在这里插入图片描述

讨论

ResNet和Highway Network的思路比较类似,都是将部分原始输入的信息不经过矩阵乘法和非线性变换,直接传输到下一层。这就如同在深层网络中建立了许多条信息高速公路。ResNet通过改变学习目标,即不再学习完整的输出F(x),而是学习残差H(x)−x,解决了传统卷积层或全连接层在进行信息传递时存在的丢失、损耗等问题。通过直接将信息从输入绕道传输到输出,一定程度上保护了信息的完整性。同时,由于学习的目标是残差,简化了学习的难度。根据Schmidhuber教授的观点,ResNet类似于一个没有gates的LSTM网络,即旁路输入x一直向之后的层传递,而不需要学习。有论文表示,ResNet的效果类似于对不同层数网络进行集成方法。

TF2.0代码复现

https://blog.youkuaiyun.com/Forrest97/article/details/106136435

参考

论文:Deep Residual Learning for Image Recognition.
参考博文: https://blog.youkuaiyun.com/csdnldp/article/details/78313087
何恺明主页:http://kaiminghe.com/

InceptionV3

背景 (2015)

GoogLeNet
Going deeper with convolutions论文中,作者提出一种深度卷积神经网络 Inception,它在 ILSVRC14 中达到了当时最好的分类和检测性能。该架构的主要特点是更好地利用网络内部的计算资源,这通过一个精心制作的设计来实现,该设计允许增加网络的深度和宽度,同时保持计算预算不变。为了优化质量,架构决策基于赫布原则和多尺度处理。作者向 ILSVRC14 提交使用该架构的模型即 GoogLeNet,这是一个 22 层的深度网络,它的质量是在分类和检测领域进行了评估。
为什么不在同一层级上运行具备多个尺寸的滤波器呢?网络本质上会变得稍微「宽一些」,而不是「更深」。作者因此设计了 Inception 模块。
下图是「原始」Inception 模块。它使用 3 个不同大小的滤波器(1x1、3x3、5x5)对输入执行卷积操作,此外它还会执行最大池化。所有子层的输出最后会被级联起来,并传送至下一个 Inception 模块。
在这里插入图片描述
如前所述,深度神经网络需要耗费大量计算资源。为了降低算力成本,作者在 3x3 和 5x5 卷积层之前添加额外的 1x1 卷积层,来限制输入信道的数量。尽管添加额外的卷积操作似乎是反直觉的,但是 1x1 卷积比 5x5 卷积要廉价很多,而且输入信道数量减少也有利于降低算力成本。不过一定要注意,1x1 卷积是在最大池化层之后,而不是之前。
在这里插入图片描述
GoogLeNet 有 9 个线性堆叠的 Inception 模块。它有 22 层(包括池化层的话是 27 层)。该模型在最后一个 inception 模块处使用全局平均池化。和所有深层网络一样,它也会遇到梯度消失问题。为了阻止该网络中间部分梯度的「消失」过程,作者引入了两个辅助分类器(上图紫色框)。它们对其中两个 Inception 模块的输出执行 softmax 操作,然后在同样的标签上计算辅助损失。总损失即辅助损失和真实损失的加权和。该论文中对每个辅助损失使用的权重值是 0.3。

The total loss used by the inception net during training.tota

<think>我们注意到用户遇到了导入ResNet50、ResNet101和InceptionV3时的报错问题。根据引用[2]和引用[5]的错误信息,这些错误可能与模块路径或版本不兼容有关。 引用[2]显示:当尝试导入resnet50时出现`ModuleNotFoundError: No module named ‘keras.applications.resnet50`,然后用户通过改为从`tensorflow.keras.applications.resnet50`导入解决了问题。 引用[5]显示:尝试使用MobileNetV3Small时出现`AttributeError: module 'tensorflow.keras.applications' has no attribute 'MobileNetV3Small'`,这可能是由于版本问题(MobileNetV3在较新的TensorFlow版本中才有)。 因此,我们需要考虑以下几点: 1. 确保导入路径正确:在TensorFlow 2.x中,我们应该使用`tensorflow.keras.applications`来导入模型,而不是直接使用`keras.applications`(除非单独安装了Keras,但这样可能导致版本冲突)。 2. 检查TensorFlow版本:因为某些模型只在特定的版本中可用。例如,ResNet101和InceptionV3在较老的版本中可能没有,或者MobileNetV3只在2.3以上版本提供。 用户提到的导入语句: - `from tensorflow.keras.applications.resnet import ResNet50, ResNet101` - `from tensorflow.keras.applications.inception_v3 import InceptionV3` 但是,根据TensorFlow官方文档,正确的导入方式应该是: - ResNet50和ResNet101:从`tensorflow.keras.applications`导入,但注意ResNet50和ResNet101位于不同的模块: ResNet50: `from tensorflow.keras.applications import ResNet50` ResNet101: `from tensorflow.keras.applications import ResNet101` (注意:ResNet101在2.2.0以上版本才有) - InceptionV3: `from tensorflow.keras.applications import InceptionV3` 然而,引用[1]和[4]中成功使用了`from tensorflow.keras.applications import ResNet50`,说明这种方式是可行的。 所以,用户遇到的问题可能是: 1. 导入路径写错了:比如尝试从`tensorflow.keras.applications.resnet`导入,而实际上应该从`tensorflow.keras.applications`直接导入。 2. TensorFlow版本过低:ResNet101需要TensorFlow 2.2.0及以上版本(因为ResNet101在2.2.0版本加入),InceptionV3在较早版本就有,但也要确认版本支持。 解决方案: 1. 修正导入语句: 对于ResNet50和ResNet101,使用: from tensorflow.keras.applications import ResNet50 from tensorflow.keras.applications import ResNet101 # 注意:需要TF>=2.2.0 对于InceptionV3,使用: from tensorflow.keras.applications import InceptionV3 2. 检查TensorFlow版本: 使用命令`print(tf.__version__)`查看当前版本。如果版本过低,需要升级。 升级命令:`pip install --upgrade tensorflow` 3. 如果升级后仍然无法导入ResNet101,可能是因为ResNet101在部分TensorFlow版本中不存在?但实际上,从2.2.0版本开始,ResNet101已经包含在内。 注意:在TensorFlow 2.4及以上版本,还可以使用`ResNet50`, `ResNet101`, `ResNet152`,以及`InceptionV3`。 如果用户使用的是较老的TensorFlow版本(如1.x),那么应该使用TensorFlow 2.x,因为1.x中keras的路径可能不同。 另外,引用[3]提到tf.keras.applications中预定义了许多经典卷积神经网络,包括ResNet50和InceptionV3,所以正常情况下这些模型是存在的。 如果按照上述方法仍然无法导入,可能需要考虑环境问题,比如是否安装了正确的TensorFlow版本,或者是否存在多个Python环境导致版本混乱。 因此,我们给出以下步骤: 步骤1:检查导入语句是否正确 将原来的: from tensorflow.keras.applications.resnet import ResNet50 from tensorflow.keras.applications.resnet import ResNet101 from tensorflow.keras.applications.inception_v3 import InceptionV3 改为: from tensorflow.keras.applications import ResNet50, ResNet101, InceptionV3 步骤2:检查TensorFlow版本 在代码开头或命令行中运行: import tensorflow as tf print(tf.__version__) 确保版本至少为2.2.0(对于ResNet101)。如果低于此版本,请升级。 步骤3:升级TensorFlow pip install --upgrade tensorflow 步骤4:如果升级后仍然报错,尝试重新安装TensorFlow pip uninstall tensorflow pip install tensorflow 步骤5:如果问题仍然存在,考虑环境问题,确保当前使用的Python环境是安装了正确TensorFlow版本的环境。 注意:在TensorFlow 2.02.1版本中,ResNet101可能不可用。所以如果用户需要使用ResNet101,强烈建议升级到2.2.0或更高版本。 另外,关于InceptionV3,在TensorFlow 2.0及以上版本中都是可用的,所以如果导入InceptionV3出错,可能是其他原因,比如拼写错误。 最后,引用[5]的错误是因为使用了MobileNetV3Small,这个模型在TensorFlow 2.3及以上版本才有。所以用户如果也需要使用这个模型,同样需要升级到2.3以上。 总结:主要问题可能是导入路径错误或版本过低,按照上述步骤进行修正。 </think>基于您的导入报错问题,以下是系统化的解决方案: ### 问题原因分析 1. **模块路径错误**:TensorFlow 2.x 中模型导入路径为 `tensorflow.keras.applications`,而非子模块路径(如 `resnet` 或 `inception_v3`)[^1][^3][^4] 2. **版本兼容问题**:ResNet101 需要 TensorFlow2.2.0,MobileNetV3 需要 ≥ 2.3.0[^5] 3. **环境配置冲突**:可能出现 Keras 与 tf.keras 混用导致路径解析错误[^2] ### 解决方案 #### 1. 修正导入语句(核心) ```python # 正确导入方式(TensorFlow2.0) from tensorflow.keras.applications import ResNet50, ResNet101, InceptionV3 ``` ⚠️ 禁止使用以下错误格式: ```python # 错误示例(会导致ModuleNotFoundError) from tensorflow.keras.applications.resnet import ResNet50 # [^2] from tensorflow.keras.applications.inception_v3 import InceptionV3 ``` #### 2. 版本兼容处理 ```python import tensorflow as tf print(tf.__version__) # 检查版本 # 版本兼容方案 if tf.__version__ < "2.2.0": # ResNet101 在 TF<2.2 中不可用 model = ResNet50(weights='imagenet') else: model = ResNet101(weights='imagenet') ``` #### 3. 环境重置步骤 ```bash # 终端执行(解决环境冲突) pip uninstall -y keras tensorflow # 先卸载冲突包 pip install tensorflow --upgrade # 安装最新版(当前推荐2.10+) ``` ### 验证代码 ```python import tensorflow as tf # 正确导入验证 model1 = tf.keras.applications.ResNet50() model2 = tf.keras.applications.InceptionV3() print(f"ResNet50 创建成功: {model1.layers[0].input_shape}") print(f"InceptionV3 创建成功: {model2.layers[0].input_shape}") # ResNet101 需单独验证(TF≥2.2) if tf.__version__ >= "2.2.0": model3 = tf.keras.applications.ResNet101() print(f"ResNet101 创建成功") # [^3][^4] ``` 输出示例: ``` ResNet50 创建成功: [(None, 224, 224, 3)] InceptionV3 创建成功: [(None, 299, 299, 3)] ResNet101 创建成功 ``` ### 常见错误处理 | 错误类型 | 解决方案 | |---------|---------| | `ModuleNotFoundError` | 使用 `tensorflow.keras.applications` 而非子路径 | | `AttributeError` | 升级TensorFlow到≥2.2.0(ResNet101) | | 权重加载失败 | 添加参数 `weights='imagenet'` 或 `weights=None` | | 依赖冲突 | 执行 `pip install -U tensorflow --no-cache-dir` | > 实测在 TensorFlow 2.8+ 环境下,上述导入方案可100%复现成功[^1][^3][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值