目录
前言
1. ResNet 详解
1.1 Why residual?
1.2 What is residual?
1.3 ResNet中的残差结构
1.4 降维时的 short cut
2. 迁移学习简介
3. pytorch搭建ResNet
3.1 model.py
3.2 train.py
3.3 predict.py
3.4 batch_predict.py
3.5 load_weights.py
3.6 class_indices.json
up主教程给出了pytorch和tensorflow两个版本的实现,我暂时只记录pytorch版本的笔记。
参考内容来自:
up主的b站链接:验证码_哔哩哔哩 up主将代码和ppt都放在了github:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing up主的CSDN博客:深度学习在图像处理中的应用(tensorflow2.4以及pytorch1.10实现)_深度学习图像处理_太阳花的小绿豆的博客-CSDN博客
数据集:补充LeNet,resnet,mobilenet的出处_后来后来啊的博客-CSDN博客
原论文地址:Deep Residual Learning for Image Recognition(作者是CV大佬何凯明团队)
ResNet 网络是在 2015年 由微软实验室提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。
在ResNet网络的创新点:
在ResNet网络提出之前,传统的卷积神经网络都是通过将一系列卷积层与池化层进行堆叠得到的。
一般我们会觉得网络越深,特征信息越丰富,模型效果应该越好。但是实验证明,当网络堆叠到一定深度时,会出现两个问题:
1.梯度消失或梯度爆炸
2.退化问题(degradation problem):在解决了梯度消失、爆炸问题后,仍然存在深层网络的效果可能比浅层网络差的现象
总结就是,当网络堆叠到一定深度时,反而会出现深层网络比浅层网络效果差的情况。

- 对于梯度消失或梯度爆炸问题,ResNet论文提出通过数据的预处理以及在网络中使用 BN(Batch Normalization)层来解决。
- 对于退化问题,ResNet论文提出了 residual结构(残差结构)来减轻退化问题,下图是使用residual结构的卷积网络,可以看到随着网络的不断加深,效果并没有变差,而是变的更好了。(虚线是train error,实线是test error)
为了解决深层网络中的退化问题,可以人为地让神经网络某些层跳过下一层神经元的连接,隔层相连,弱化每层之间的强联系。这种神经网络被称为 残差网络 (ResNets)。
残差网络由许多隔层相连的神经元子模块组成,我们称之为 残差块 Residual block。单个残差块的结构如下图所示:



实验表明,这种模型结构对于训练非常深的神经网络,效果很好。另外,为了便于区分,我们把 非残差网络 称为 Plain Network。
实际应用中,残差结构的 short cut 不一定是隔一层连接,也可以中间隔多层,ResNet所提出的残差网络中就是隔多层。
跟VggNet类似,ResNet也有多个不同层的版本,而残差结构也有两种对应浅层和深层网络:
下图中左侧残差结构称为 BasicBlock,右侧残差结构称为 Bottleneck

对于深层的 Bottleneck,1×1的卷积核起到降维和升维(特征矩阵深度)的作用,同时可以大大减少网络参数。
可以计算一下,假设两个残差结构的输入特征和输出特征矩阵的深度都是256维,如下图:(注意左侧结构的改动)
那么两个残差结构所需的参数为:
明显搭建深层网络时,使用右侧的残差结构更合适。
观察下图的 ResNet18层网络,可以发现有些残差块的 short cut 是实线的,而有些则是虚线的。


原文的表注中已说明,conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层残差结构都是虚线残差结构。因为这一系列残差结构的第一层都有调整输入特征矩阵shape的使命(将特征矩阵的高和宽缩减为原来的一半,将深度channel调整成下一层残差结构所需要的channel)
需要注意的是,对于ResNet50/101/152,其实conv2_x所对应的一系列残差结构的第一层也是虚线残差结构,因为它需要调整输入特征矩阵的channel。根据表格可知通过3x3的max pool之后输出的特征矩阵shape应该是[56, 56, 64],但conv2_x所对应的一系列残差结构中的实线残差结构它们期望的输入特征矩阵shape是[56, 56, 256](因为这样才能保证输入输出特征矩阵shape相同,才能将捷径分支的输出与主分支的输出进行相加)。所以第一层残差结构需要将shape从[56, 56, 64] –> [56, 56, 256]。注意,这里只调整channel维度,高和宽不变(而conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层虚线残差结构不仅要调整channel还要将高和宽缩减为原来的一半)。
下面是 ResNet 18⁄34 和 ResNet 50/101/152 具体的实线/虚线残差结构图:
- ResNet 18⁄34

- ResNet 50/101/152s

Batch Normalization详解以及pytorch实验_pytorch batch normalization_太阳花的小绿豆的博客-CSDN博客参考博文:Batch Normalization详解以及pytorch实验_pytorch batch normalization_太阳花的小绿豆的博客-CSDN博客


迁移学习是一个比较大的领域,我们这里说的迁移学习是指神经网络训练中使用到的迁移学习。
在迁移学习中,我们希望利用源任务(Source Task)学到的知识帮助学习目标任务 (Target Task)。例如,一个训练好的图像分类网络能够被用于另一个图像相关的任务。再比如,一个网络在仿真环境学习的知识可以被迁移到真实环境的网络。迁移学习一个典型的例子就是载入训练好VGG网络,这个大规模分类网络能将图像分到1000个类别,然后把这个网络用于另一个任务,如医学图像分类。

- 使用迁移学习的优势:
- 能够快速的训练出一个理想的结果
- 当数据集较小时也能训练出理想的效果
注意:使用别人预训练好的模型参数时,要注意别人的预处理方式。
- 常见的迁移学习方式:
- 载入权重后训练所有参数
- 载入权重后只训练最后几层参数
- 载入权重后在原网络基础上再添加一层全连接层,仅训练最后一个全连接层

- 定义ResNet18/34的残差结构,即BasicBlock
- 定义ResNet50/101/152的残差结构,即Bottleneck
- 定义ResNet网络结构
- 定义resnet18/34/50/101/152
然后在实例化网络时导入预训练的模型参数。下面是完整代码:(看过vgg的宝子们应该知道把”study删去”,但是为了怕你们麻烦,我就删去了”study”,具体原因可以查看vgg)
预测脚本跟之前的几章差不多,就不详细讲了
这段代码的作用是使用训练好的模型对指定文件夹中的图像进行批量预测,并输出预测结果。具体步骤如下:
- 导入所需的库和模块。
- 定义设备类型,如果有可用的GPU则使用GPU,否则使用CPU。
- 定义数据预处理的转换操作,包括图像大小调整、中心裁剪、转换为张量、归一化等。
- 指定需要遍历预测的图像文件夹,并获取该文件夹下所有jpg图像的路径。
- 读取类别标签的映射关系,即将类别索引映射为类别名称。
- 创建模型,并将模型移动到指定设备上。
- 加载模型的权重参数。
- 设置模型为评估模式。
- 定义每个batch中图像的数量。
- 使用torch.no_grad()上下文管理器,禁用梯度计算。
- 遍历图像路径列表,每次取出一个batch的图像进行预测。
- 对每个图像进行预处理操作,并将其添加到一个列表中。
- 将图像列表打包成一个batch,并将其移动到指定设备上。
- 使用模型进行预测,得到预测结果。
- 对每个预测结果进行处理,包括计算概率最大的类别和对应的概率值。
- 打印每个图像的路径、预测类别和概率值。
以下代码的作用是加载预训练的ResNet-34模型的权重,并根据需要修改模型的最后一层全连接层的结构。
具体的步骤如下:
- 导入必要的库和模块。
- 检查是否有可用的GPU设备,如果有则使用GPU,否则使用CPU。
- 定义预训练权重文件的路径,并检查该文件是否存在。
- 创建一个ResNet-34模型的实例。
- 使用
torch.load函数加载预训练权重文件,并将权重映射到指定的设备。 - 修改模型的最后一层全连接层的结构,将输入特征的维度改为5。
- 可选的另一种方式是直接在创建ResNet-34模型时指定
num_classes=5,然后加载预训练权重文件,并删除其中与全连接层相关的权重。 - 打印出缺失的权重和意外的权重(如果有的话)。
总的来说,这段代码的作用是加载预训练的ResNet-34模型的权重,并根据需要修改模型的最后一层全连接层的结构。




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/162691.html