1. MTCNN回顾(分类到检测)
分类器简述(PNet的推理)
- 回顾多任务经典网络MTCNN,以第一个尺度Pnet为例子,可以想象成是一个12x12的卷积核
- MTCNN是一个全卷机的网络,每一个滑窗推理会输出的是1x2x1x1(有样本没样本的Label Map) 和 1x4x1x1 (回归出来的BBox信息)
- 以confidence的图为例子输入为100x100,根据公式输出为45x45的Label Map。
- Label Map 代表着每一个像素储存12x12卷积核提取100x100的特征,也是我们熟知的感受野
- Label Map 是指当前12x12滑窗的标签(是否有样本的概率),通过阈值对概率的调整,可以分为三类,正类1, 负类0,不正不负-1,每一个正类旁边都会有好几个不正不负
分类器到检测器
- 我的理解是检测器可以简单的理解成带标签的分类器,标注每一个像素的confidence(0.7, 0.8, 0.9…),在训练中做回归任务
- 进一步说,如果我有事先标注好的Label Map 可以直接使用训练生成的Label Map直接做Loss,
- 分类可以用二元交叉熵等,不正不负的不参与训练
- 回归可以用MSE等
- 让训练出来的Label Map去拟合标注好的Label Map
- 以前是随机采一些框,落在哪里算阈值
- 现在检测器全部阈值[0 - 1]我都列出来,然后把这些阈值当成标签,把分类问题做成回归问题
- 这种回归出来就是有样本高响应,没有样本低响应,这就是二元高斯分布
- 下面我们来讨论和复现二元高斯核
高斯滤波器定义
高斯滤波是一种图像滤波器,它使用高斯函数来平滑图像中的噪声。它通常在图像处理中使用,以减少图像中的噪声或模糊不清的图像。
高斯滤波器的核是一个二维高斯分布,它的形状与输入图像的大小无关,但是在大多数情况下,核的大小是奇数。高斯滤波器的核大小越大,滤波器就越平滑,但是它也会使图像的边缘变得模糊。
使用高斯滤波器的一种常见方法是将核与图像中的每个像素相乘,然后将所有乘积相加,最后将结果除以核中所有元素的和。这可以使用线性卷积实现。
使用高斯滤波器的一个优点是它对于高斯噪声非常有效,并且它还可以在保留图像边缘的同时平滑图像。然而,高斯滤波器也有一些缺点,例如它可能会模糊图像中的细节,并且在处理非高斯噪声时效果可能不佳。
手写复现高斯核
下面为二维高斯的定义, x, y 是距离的偏移量, 这里写成dx, dy更好
这里我们舍弃左边, 当x, y = 0, f(x) = 1, 保证最大为1。
import numpy as np
sigma = 1
size = 5 # 高斯核的大小
center = 2 # 中心点是(2, 2)
heatmap = np.zeros((size, size))
print(heatmap)
for x in range(size):
for y in range(size):
dx = x - center
dy = y - center
gvalue = np.exp(- (dx ** 2 + dy ** 2)/ (2 * (sigma * sigma)))
heatmap[y, x] = gvalue
heatmap
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
array([[0.01831564, 0.082085 , 0.13533528, 0.082085 , 0.01831564],
[0.082085 , 0.36787944, 0.60653066, 0.36787944, 0.082085 ],
[0.13533528, 0.60653066, 1. , 0.60653066, 0.13533528],
[0.082085 , 0.36787944, 0.60653066, 0.36787944, 0.082085 ],
[0.01831564, 0.082085 , 0.13533528, 0.082085 , 0.01831564]])
把图片画出来是这样
可以通过改变size和center,sigma来调整。
用高斯核对全是[0, 1]的MTCNN网络输出的图像可以生成一个feature map直接用MSE, L2做Loss就是一个检测器了
高斯核改进
- 用np.meshgrid
gridy, gridx = np.meshgrid(np.arange(11), np.arange(11))
dy = gridy - center; dx = gridx - center;
heatmap = np.exp(- (dx ** 2 + dy ** 2)/ (2 * (sigma * sigma)))
plt.imshow(heatmap)
- 用np.ogrid改进
sigma = 2 # 高斯分布超参数
gsize = 5 # 高斯核大小,高斯分布超参数
half_size = gsize // 2
dy, dx = np.ogrid[-half_size:half_size+1, -half_size:half_size+1]
gkernel = np.exp(- (dx ** 2 + dy ** 2)/ (2 * (sigma * sigma)))
plt.imshow(gkernel)
两种改法都能出现下面的东西