MTCNN介绍

    • 历史
      • 此模型是2016年中科院深圳研究院乔宇老师在论文《Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks》中提出的
      • 本文原始的创意来自《A Convolutional Neural Network Cascade for Face Detection》,有人称它为 Cascade CNN。作者的修改体现在以下三点:
        • MTCNN的级联思想和主要网络结构都源自Cascade CNN,但是作者增加了网络深度、减少每层的滤波器数量、把5x5改为3x3卷积,在减少计算量的同时增加了网络的表征提取能力。
        • 除了上述网络结构修改,作者同时加入了人脸关键点的预测。作者认为通过多任务联合训练,对人脸检测是有好处的(我认为这相当于加入了更多的先验知识,告诉网络人有这几个部位)。作者在论文里也通过实验证实了自己的猜想。
        • online hard sample mining。怎么翻译呢,难道是"在线高难度样本挖掘"?意思就是每个batch只利用分类loss前70%的样本进行梯度回传。因为那些容易的样本对训练的贡献本来就不大,就忽略掉了。这可以加速网络收敛,提高最终性能。作者在论文里也有对比测试证明自己。
    • 总体
      • 需要解决的问题
        • 追踪和对齐问题
      • 效果
        • 模型实时性高
        • 在widerface和celeba等数据集中效果较好
        • 在少数人脸<5个人脸的情况下,其效能属于第一梯队的水准
        • 有很大的优化空间
      • 适用场景
        • 适用于框正方形的物体
        • 是少数能在传统硬件上落地的检测器
      • 存在的问题
        • 训练的时间长
          • 1.图片越大Pnet耗时也越大
          • 2.人脸越多Onet和Rnet耗时越大
          • 3.噪点比较多的夜晚图像会导致Pnet误框率增大
        • 需要大量的数据集
        • 收敛慢
        • 容易过拟合
        • 虚警过高
        • 图片超过1080时,图像金字塔最耗时,因为图片那么大时,人脸极有可能要比12*12大,所以越接近12*12时的缩放可能是没什么用处的,输入大图的时候能明显感觉处理的速度要慢很多,eg:1209*678的图片4 50个人头就需要2秒
    • 详细
      • 流程图
        • 如图

        • 流程图全面一点,加上金字塔

      • 数据
        • 网上已有的数据集wider face和celebA
          • wider face
            • 优点:汇集了人脸尺寸大小变化、拍照角度引起的人脸姿态变化、不同程度的人脸遮挡、表情变化、光照强弱差异以及化妆等多种影响因素,图片复杂度高
            • 缺点:wider face中的数据大多都是很多人脸,很小的都有,用这个数据集训练出来的网络不容易识别出大脸
          • celebA
            • 香港中文大学的开放数据,包含的都是名人身份的图片
            • 优点:脸大,识别的脸部特征清晰
            • 缺点:数据集里都是单人照片没有合影,对人脸识别的效果有影响。图片里的人都是欧美人,没有黑人、很少有亚洲人和没有老人和小孩,这就对这几种人的识别有很大的影响
          • 很多人将wider face和celebA结合在一起使用
        • 样本种类
          • positive:与真实值的iou高于阈值1
          • part:与真实值的iou在阈值1 2之间
          • negative:与真实值的iou低于阈值2
          • landmark:
          •  negatives/ positives/ part face/ landmark face=3:1:1:2
        • 使用
          • 分类使用positive和negative
          • 置信度使用positive和part
          •  
      • 网络具体步骤
        • Proposal Network(P-Net):
          • 输入图片
            • 因为pnet采用的是全卷积网络,所以输入的图片形状可以不相同
          • 进行图像金字塔
            • 作用:让不同尺寸的图片都能检测到人脸,比如小的脸就可以不进行图像金字塔,大的就需要进行图像金字塔。以增强网络对不同尺寸大小人脸的鲁棒性。
            • bounding boxes是12*12*3的,所以要将图片一点一点缩小,相对来说框就变大了,就可以框到大脸的了
              • 如图

          • 反算找到原图偏移量
            • 偏移量有两种算法,一种是偏移后的减原始的,一种是原始的减偏移的,但必须要对应最开始造数据时使用的
          • 作nms
            • 去掉重合率较高的
        • Refine Network(R-Net):
          • 输入从p网络中出来的框和图像
          • 在图像中扣出对应的正方形框
            • 由于R网络中需要全连接网络,所以要将图片同一形状。
          • 将处理好的24*24*3的正方形图输入到r网络
            • 如图

          • 偏移量计算
          • nms计算
        • Output Network(O-Net):
          • 输入从r网络中出来的框和图像
          • 在图像中扣出对应的正方形框
            • 由于o网络中需要全连接网络,所以要将图片同一形状。
          • 将处理好的48*48*3的正方形图输入到o网络
            • 如图

          • 偏移量计算
          • nms计算
            • iou
      • 池化
        • 首先要讲一下我们常听到的上采样和下采样
        • 下采样(subsampled)-缩小图像
          • 目的
            • 1、使图像符合显示区域的大小
            • 2、生成对应图像的缩略图
          • 与池化的关系-下采样就是池化
            • 采样层是使用pooling的相关技术实现的,为了降低特征的维度并保留有效信息,避免过拟合
            • 采样有最大值采样,平均值采样,求和区域采样和随机区域采样等。池化也有这几种池化
            • 池化会对位置产生偏移,对稠密信息操作的时候尽量不要用池化和填充
          • 原理
            • 对M*N的图像进行s倍的下采样,得到(M/S)*(N/S)的图像,s应该是M和N的公约数
        • 上采样(upsampling)-放大图像
          • 目的:放大原图像,从而可以显示在更高分辨率的显示设备上
          • 原理:图像放大几乎都是采用插值方法,即在原图像的基础上加上合适的插值算法。
            • 插值算法
              • 最近邻域差值(Nearest Neighbour Interpolation)
                • 特点:计算量小,但可能会造成插值生成的图像灰度上不连续,有明显的锯齿状,只能保持一个方向上的信息
              • 线性插值(Linear interpolation)
                • 特点:可以保持两个方向上的信息
              • 双线性插值(Bilinear interpolation)
                • 根据4个近邻像素点的灰度值做2个方向共3次线性插值。
                • 特点:计算量较大于邻近插值,但没有灰度不连续的问题,但是图像轮廓可能有点模糊
              • 双三次插值(Bicubic interpolation)--二维空间最常用的插值方法
                • 在(x,y)点通过最近的16个网格点的加权平均
                • 特点:进度高边缘更平滑,图像损失较低,但是计算量较大
            • 像素混洗(pixel shuffle)
      • 损失函数
        • 定义:衡量模型预测出来的值与真实值的差距。损失函数越小,模型的鲁棒性越好
        • 本模型主要使用的是BCEloss和MSEloss
          • 二分类交叉熵(Binary Cross Entropy)-BCEloss
            • 用的时候需要在该层前面加上 Sigmoid 函数
            • nn.BCEWithLogitsLoss是BCELoss 和 Sigmoid 层的结合
            • 本模型中用于评估置信度
          • MSEloss(mean squared error)
            • 回归问题中常用的损失函数式
            • 缺点:其偏导值在输出概率值接近0或者接近1的时候非常小,这可能会造成模型刚开始训练时,偏导值几乎消失。
            • 本模型中用于评估偏移量
        • Hard Sample mining—难分样本
          • 难分正样本-错分成负样本的正样本,训练中损失最高的正样本
          • 难分负样本-错分成正样本的负样本,训练中损失最高的负样本
          • 之前的困难样本都是手工挖掘,MTCNN中则是自动划分出来然后不断重复训练
      • 激活函数
        • leaky RELU(带泄露修正线性单元)
        • 解决了“RELU死亡”问题的

        • 表现不错,但效果不是很稳定
        • y=x
    • 优化
      • 针对训练时间长的问题1和问题2来选择优化网络结构
      • 卷积代替池化
    • 遇到的问题
      • Q1:为什么pnet,rnet和onet是同步训练的?网上的都说是异步的
        • 首先说一下,pnet,rnet和onet使用时是异步的,因为使用的时候必须有框往下传。
        • 然后说训练
        • 1.正常的训练模式是要异步的,这样才能保持数据流动性从而使模型的整体效果更好,但这样有一个缺点就是如果第一个模型训练的时候效果不是很好,输出的数据输入到下一层网络里就会影响下一层网络的效果。而且这样训练的周期较长。
        • 2.用同步训练的原因就是在算法实际落地的时候是需要时间的,所以选择同步训练,这样有点类似于贪心算法,每个都取单个最优。但这样训练要求人工处理数据的能力要强大。足以满足每个网络输入的要求。
      • Q2:偏移量问题
        • 相对谁偏移就减谁
      • Q3:np.min和min的区别
        • np.min中只需要有一个参数,比如说一个列表
        • min中需要两个参数,要是数组型(array)
        • np.minimum需要两个参数,取较大者,如果是数组的话会逐位取较大值
          • >> np.maximum([-2, -1, 0, 1, 2], 0)
          • >> array([0, 0, 0, 1, 2])
        •  
      • Q4: data.cpu() 和 cpu().data啥区别,还有就是后面加不加numpy()对data和cpu()的顺序有影响吗
        • 1.首先a是一个放在GPU上的Variable,a.data是把Variable里的tensor取出来,
        • 可以看出与a的差别是:缺少了第一行(Variable containing)
        • 2.a.cpu()和a.data.cpu()是分别把a和a.data放在cpu上,其他的没区别,另外:a.data.cpu()和a.cpu().data一样
        • 3.a.data[0] |  a.cpu().data[0]  | a.data.cpu()[0]是一样的,都是把第一个值取出来,类型均为float
        • 4.a.data.cpu().numpy()把tensor转换成numpy的格式
      • Q5:import Torchvision -DLL找不到
        • 重新安装anaconda,添加镜像文件
      • Q6:cuda设备端问题
        • 没写sigimoid
      • Q7:形状不匹配问题
        • 打印图片形状出来看看
      • Q8:ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
        • 错误的原因是你试图在整个数组上应用一个函数,当它被设计为在单个元素上工作时。
      • Q9:ValueError: unknown resampling filter-img.resize变形
        • img.resize(必须加的是元组)
      • Q10:np.stack的使用
        • a = np.array([[[1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3]]])
        • b = np.array([[4, 5, 6], [4, 5, 6], [4, 5, 6]])
        • print(a)
        • >>[[[1 2 3]
        • [1 2 3]]
        • [[1 2 3]
        • [1 2 3]]]
        • print(a.shape) >>(2, 2, 3)
        • print(np.stack(a, axis=0))
        • >>[[[1 2 3]
        • [1 2 3]]
        • [[1 2 3]
        • [1 2 3]]]
        • print(np.stack(a, axis=1))
        • >>[[[1 2 3]
        • [1 2 3]]
        • [[1 2 3]
        • [1 2 3]]]
        • print(np.stack(a, axis=2))
        • >>[[[1 1]
        • [2 2]
        • [3 3]]
        • [[1 1]
        • [2 2]
        • [3 3]]]
      • Q11:形状问题
        • 如图

      • Q12:框人脸的框均匀分布到整个图片上
        • 反算过程中偏移量计算错误,加减要看好
      • Q13:框在人脸附近但不准确
      • Q14:框不准且总框到手
        • 原因:1,训练过度。。。。
        • 解决:
          • 1.少训练点
          • 2.加centerloss
          • 3.五个关键点
          • 4.O网络后加一个网络用于筛选手
      • Q15:速度慢
        • 方法1-将串行网络改成并行网络
      • Q16:strip()用法
        • Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
      • Q17:下次解决问题的时候,网上的没错误的方法,没有解决我的问题的时候,先检查变量弄没弄混
    • ppt改进
      • celebA量多
      • 改进——数据量增多
      • pro网络全名
      • 全卷积的好处就是对任意尺寸图片进行操作
      • iou两处应用
      • 总结是本项目工具应用在其他地方
      • 效果图一张人少的,一张人多的
      • 网络为啥用12*12,24*24,48*48
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值