我是靠谱客的博主 温婉裙子,最近开发中收集的这篇文章主要介绍【人脸检测】libfacedetection.train项目解读记录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目的:

  • 为什么libfacedetetiong可以脱离pytorch/caffe等环境的依赖
  • 关于模型的一些训练细节,如:数据,模型,如何脱离pytorch的依赖,只用c++就行,推理的速度等
  • 如何在现有的基础上进行拓展,让其支持更多的模型。

训练细节

1. 模型

先上关键代码,无关紧要的就删了:

self.model1 = Conv_2layers(3, 32, 16, 2)
        self.model2 = Conv_2layers(16, 32, 32, 1)
        self.model3 = Conv_3layers(32, 64, 32, 64, 1)
        self.model4 = Conv_3layers(64, 128, 64, 128, 1)
        self.model5 = Conv_3layers(128, 256, 128, 256, 1)
        self.model6 = Conv_3layers(256, 256, 256, 256, 1)

        self.loc, self.conf = self.multibox(self.num_classes)

    def multibox(self, num_classes):
        loc_layers = []
        conf_layers = []
        loc_layers += [nn.Conv2d(self.model3.out_channels, 3 * 14, kernel_size=3, padding=1, bias=True)]
        conf_layers += [nn.Conv2d(self.model3.out_channels, 3 * num_classes, kernel_size=3, padding=1, bias=True)]
        loc_layers += [nn.Conv2d(self.model4.out_channels, 2 * 14, kernel_size=3, padding=1, bias=True)]
        conf_layers += [nn.Conv2d(self.model4.out_channels, 2 * num_classes, kernel_size=3, padding=1, bias=True)]
        loc_layers += [nn.Conv2d(self.model5.out_channels, 2 * 14, kernel_size=3, padding=1, bias=True)]
        conf_layers += [nn.Conv2d(self.model5.out_channels, 2 * num_classes, kernel_size=3, padding=1, bias=True)]
        loc_layers += [nn.Conv2d(self.model6.out_channels, 3 * 14, kernel_size=3, padding=1, bias=True)]
        conf_layers += [nn.Conv2d(self.model6.out_channels, 3 * num_classes, kernel_size=3, padding=1, bias=True)]
        return nn.Sequential(*loc_layers), nn.Sequential(*conf_layers)

模型基本上是SSD的方案。

  • 基础模型是conv,batchnorm,relu的堆叠
  • 从3,4,5,6模块进行输出,并回归loss
  • 位置回归分支输出的最后维度为啥是:3 *14,2 *14,还不一样呢。3和2表示每个点的anchor数量。这个对应config.py文件中的'min_sizes': [[10, 16, 24], [32, 48], [64, 96], [128, 192, 256]], 说明:1. 这里前面的数字小,后面的数字大,表示用前面的特征图检测小目标,用后面的特征图检测大目标。 2. 这里每个list的个数表示每个点的anchor数量,比如第三层的[10,16,24],表示第三层输出特征,每个点的anchor宽度为10,16,24,所有是3 3. 这里的10是人脸的原始尺寸,并不是相对于下采样的特征图的尺寸,所以最小的anchor是10
  • 位置输出分支的14:人脸bbox(4个值)+ 人脸关键点(10个值)= 14

2. 数据

数据采用的是widerface数据集。数据增强部分基本应该和常用的人脸检测项目一样。
我认为一些可以注意的地方:

  • 项目本身采用320的尺寸进行训练,但是会以0.8的概率生成[0.3,1] scale的图片,在以图像短边为基准进行随机crop。
  • 随机的亮度,对比度,色度等
  • 将图片resize,填充到固定尺寸(320)

关键点对应的代码:

# 1. 更多的小尺寸图片
if random.uniform(0, 1) <= 0.2:                     # 0.2的概率采用同样尺寸
    scale = 1
else:
    scale = random.uniform(0.3, 1.)                 # 采用更多的小人脸,0.8的概率
short_side = min(width, height)                     # 短边

3. 损失函数

损失函数采用的是SSD的MultiBoxLoss,应该都是差不多的,没有对比。
损失函数计算三个:

  1. 人脸bbox的损失
    中心点的偏差/(0.1*anchor的宽度/高度)
    高度和宽度损失:log(偏差)/0.2
  2. 人脸关键点的损失
    人脸关键点是相对于anchor左上角的偏差/(0.1*anchor的高度/宽度),这和人脸bbox中心点的计算过程一样
  3. 分类交叉熵损失
    采用softmax为损失,但是会筛选样本,正负样本为1:3

前两个损失anchor与正样本对应时才计算

损失函数code

loss_l = F.smooth_l1_loss(loc_p[:, 0:4], loc_t[:, 0:4], reduction='sum')            # 人脸bbox的loss
loss_lm = F.smooth_l1_loss(loc_p[:, 4:14], loc_t[:, 4:14], reduction='sum')         # 人脸关键点的loss

loss_c = F.cross_entropy(conf_p, targets_weighted, reduction='sum')         # 交叉熵损失
	
	# 人脸bbox和关键的损失
    # dist b/t match center and prior's center
    g_cxcy = (matched[:, 0:2] + matched[:, 2:4])/2 - priors[:, 0:2]         # 中心点的偏差
    # encode variance
    g_cxcy /= (variances[0] * priors[:, 2:4])                               # 中心点的偏差/高度或宽度
    # match wh / prior wh
    g_wh = (matched[:, 2:4] - matched[:, 0:2]) / priors[:, 2:4]             # 高度和宽度的偏差
    g_wh = torch.log(g_wh) / variances[1]

    # landmarks
    g_xy1 = (matched[:, 4:6] - priors[:, 0:2]) / (variances[0] * priors[:, 2:4])    # 关键点的偏差,相较于人脸bbox左上角的偏差
    g_xy2 = (matched[:, 6:8] - priors[:, 0:2]) / (variances[0] * priors[:, 2:4])
    g_xy3 = (matched[:, 8:10] - priors[:, 0:2]) / (variances[0] * priors[:, 2:4])
    g_xy4 = (matched[:, 10:12] - priors[:, 0:2]) / (variances[0] * priors[:, 2:4])
    g_xy5 = (matched[:, 12:14] - priors[:, 0:2]) / (variances[0] * priors[:, 2:4])

总结

  1. 项目可读性很强。一个晚上就搞定了
  2. 代码很美,基本一看就知道大概

明天继续模型转换等阅读

reference

  1. https://github.com/ShiqiYu/libfacedetection.train

最后

以上就是温婉裙子为你收集整理的【人脸检测】libfacedetection.train项目解读记录的全部内容,希望文章能够帮你解决【人脸检测】libfacedetection.train项目解读记录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部