人脸特征点检测(三)基于神经网络的方法:VGG,Mobilenet-v2尝试
本篇主要尝试着用CNN做特征点检测。主要尝试VGG, MobilenetV2的结构。
代码https://github.com/goodluckcwl/Face-alignment-mobilenet-v2
VGG尝试
VGG的结构包含两个卷积加一个ReLU。
网络结构设计
网络输入大小确定为,这个大小的输入设计几个卷积层就足够了。设计的网络结构如下:
Input | Operator | channels | stride | pad | kernel size |
---|---|---|---|---|---|
Conv2d | 64 | 1 | 1 | ||
Conv2d | 64 | 1 | 1 | ||
Pooling | - | 2 | - | ||
Conv2d | 128 | 1 | 1 | ||
Conv2d | 128 | 1 | 1 | ||
Pooling | - | 2 | - | ||
Conv2d | 192 | 1 | 1 | ||
Conv2d | 192 | 1 | 1 | ||
Pooling | - | 2 | - | ||
Conv2d | 256 | 1 | 0 | ||
Inner Product | 256 | - | - | - | |
Dropout | - | - | - | - | |
Inner Product | 136 | - | - | - |
Dropout比率设置
分别尝试了0~1之间的dropout比率,最佳值为0.3。
目标函数
用相对于瞳距归一化的欧式距离损失函数,可以收敛。主要的trick是图片要扩增,以及学习率要调整。
最终示例图片如下:
这个结果其实不是特别好,有比较多的改进的地方。
MobileNetv2尝试
MobileNetv2构造了一个线性嵌入层的逆残差模块:首先把低维表达映射到高维表达,用depthwise卷积来提取特征,最后再把特征通过一个线性的卷积层投影回低维表达。通过这种方式减少了参数。
网络结构设计
决定采用MobileNetv2,具体的结构设计经过实验,结合输入的图片的大小(采用64*64的输入),采用如下的结构:
Input | Operator | t | channels | n | stride |
---|---|---|---|---|---|
conv2d | - | 16 | 1 | 2 | |
bottleneck | 6 | 24 | 1 | 2 | |
conv2d | 6 | 24 | 1 | 1 | |
conv2d | 6 | 32 | 1 | 2 | |
conv2d | 6 | 32 | 1 | 1 | |
conv2d | 6 | 64 | 1 | 2 | |
conv2d | 6 | 64 | 1 | 1 | |
inner product | - | 200 | 1 | - | |
inner product | - | 200 | 1 | - | |
inner product | - | 50 | 1 | - | |
inner product | - | 136 | 1 | - |
其中,每个卷积模块由下面几部分组成:
- Conv层
- BatchNorm层
- Scale层
- LeakyReLU层
最后的全连接层映射到低维嵌入(50),再映射回landmark空间。
损失函数
损失函数采用标准的欧几里得损失函数,或者以瞳距归一化的欧几里得函数。
训练数据
- 300W
- Menpo
数据扩增
- 随机镜像。
- 随机旋转。从-30~30随机采样旋转的角度。
- 随机平移。
- 随机缩放。
- 添加高斯噪声。
本文的代码已在github上,就不多说了。