这里会用到预训练模型所以先了解一下预训练是什么以及它的作用是什么,详细内容可以参考教程
1.预训练是什么
深入理解:什么是预训练?预训练有什么作用?预训练和训练的本质区别???-CSDN博客
预训练是一种深度学习模型训练的策略,通常在大规模的数据集上进行。预训练的目标是通过在一个相关但较大的任务上训练模型,使得模型学习到通用的特征表示。这样的预训练模型在其他具体任务上的表现通常更好,因为它已经学习到了普适的特征。
预训练的好处在于,通过利用大规模数据进行训练,模型可以学习到更泛化的特征表示,从而在具体任务上表现更好。这对于数据较少的任务或者计算资源有限的情况下特别有用。预训练的模型也经常用于迁移学习,可以将预训练模型的部分或全部用于新的任务,以提高模型的性能。
预训练有什么作用?
加速训练过程,提高性能,解决数据不足问题,迁移学习,提高泛化能力。
这篇文章中的HRNet(High-Resolution Net)是针对2D人体姿态估计(Human Pose Estimation或Keypoint Detection)任务提出的,并且该网络主要是针对单一个体的姿态评估(即输入网络的图像中应该只有一个人体目标)。人体姿态估计在现今的应用场景也比较多,比如说人体行为动作识别,人机交互(比如人作出某种动作可以触发系统执行某些任务),动画制作(比如根据人体的关键点信息生成对应卡通人物的动作)等等。
(1)对于Human Pose Estimation任务,现在基于深度学习的方法主要有两种:
基于regressing(回归)的方式,即直接预测每个关键点的位置坐标。
基于heatmap的方式,即针对每个关键点预测一张热力图(预测出现在每个位置上的分数)。
当前检测效果最好的一些方法基本都是基于heatmap的,所以HRNet也是采用基于heatmap的方式。
1 HRNet网络结构
下图根据阅读项目源码绘制的关于HRNet-W32的模型结构简图,在论文中除了提出HRNet-W32外还有一个HRNet-W48的版本,两者区别仅仅在每个模块所采用的通道个数不同,网络的整体结构都是一样的。而该论文的核心思想就是不断地去融合不同尺度上的信息,也就是论文中所说的Exchange Blocks。
通过上图可以看出,HRNet首先通过两个卷积核大小为3x3步距为2的卷积层(后面都跟有BN以及ReLU)共下采样了4倍。然后通过Layer1模块,这里的Layer1其实和之前讲的ResNet中的Layer1类似,就是重复堆叠Bottleneck,注意这里的Layer1只会调整通道个数,并不会改变特征层大小。下面是实现Layer1时所使用的代码。
1.1(这里解释下conv的参数定义:
卷积神经网络中的参数解释_conv, [ 160, 1, 1 ] 解释-CSDN博客
conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding=‘SAME’)
这是一个常见的卷积操作,其中strides=【1,1,1,1】表示滑动步长为1,padding=‘SAME’表示填0操作
当我们要设置步长为2时,strides=【1,2,2,1】,strides在官方定义中是一个一维具有四个元素的张量,其规定前后必须为1,可以改的是中间两个数,中间两个数分别代表了水平滑动和垂直滑动步长值。
在卷积核移动逐渐扫描整体图时候,因为步长的设置问题,可能导致剩下未扫描的空间不足以提供给卷积核的,大小扫描 比如有图大小为55,卷积核为22,步长为2,卷积核扫描了两次后,剩下一个元素,不够卷积核扫描了,这个时候就在后面补零,补完后满足卷积核的扫描,这种方式就是same。如果说把刚才不足以扫描的元素位置抛弃掉,就是valid方式。)
经过3*3卷积,步长为2,下采样了4倍。可以拿个12乘以12的矩阵用3×3步长为2试一下,不够的补0,经过两次缩小了4倍。步长假设为1 的话就不会改变长宽。
1.2阶段一的代码如下:
这部分代码是layer1那一部分
# Stage1
downsample = nn.Sequential(
nn.Conv2d(64, 256, kernel_size=1, stride=1, bias=False),
nn.BatchNorm2d(256, momentum=BN_MOMENTUM)
)
self.layer1 = nn.Sequential(
Bottleneck(64, 64, downsample=downsample),
Bottleneck(256, 64),
Bottleneck(256, 64),
Bottleneck(256, 64)
)
1.3代码是什么:
用torch.nn.Sequential()搭建神经网络模型-CSDN博客torch.nn.Sequential
是一个Sequential
容器,模块将按照构造函数中传递的顺序添加到模块中。通俗的话说,就是根据自己的需求,把不同的函数组合成一个(小的)模块使用或者把组合的模块添加到自己的网络中。
1.4
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
代码示例
import torch
x = torch.randn(3,1,5,4)
print(x)
conv = torch.nn.Conv2d(1,4,(2,3))
res = conv(x)
print(res.shape) # torch.Size([3, 4, 4, 2])
输入:x[ batch_size, channels, height_1, width_1 ]
batch_size,一个batch中样本的个数 3
channels,通道数,也就是当前层的深度 1
height_1, 图片的高 5
width_1, 图片的宽 4
卷积操作:Conv2d[ channels, output, height_2, width_2 ]
channels,通道数,和上面保持一致,也就是当前层的深度 1
output ,输出的深度 4【需要4个filter】
height_2,卷积核的高 2
width_2,卷积核的宽 3
输出:res[ batch_size,output, height_3, width_3 ]
batch_size,,一个batch中样例的个数,同上 3
output, 输出的深度 4
height_3, 卷积结果的高度 4
width_3,卷积结果的宽度 2
3.代码使用
链接:
文件结构:
```
├── model: 搭建HRNet相关代码
├── train_utils: 训练验证相关模块(包括coco验证相关)
├── my_dataset_coco.py: 自定义dataset用于读取COCO2017数据集
├── person_keypoints.json: COCO数据集中人体关键点相关信息
├── train.py: 单GPU/CPU训练脚本
├── train_multi_GPU.py: 针对使用多GPU的用户使用
├── predict.py: 简易的预测脚本,使用训练好的权重进行预测
├── validation.py: 利用训练好的权重验证/测试数据的COCO指标,并生成record_mAP.txt文件
└── transforms.py: 数据增强相关
```