在这个有指导意义的kaggle竞赛的介绍结尾,他们提到“Viola和Jones的开创性论文中使用的技术效果很好”。然而,那篇论文描述的是一个二元人脸识别的系统,而所解决的问题是关键点的分类,而不是整个图像的分类。我很难弄清楚如何具体调整Viola/Jones系统来进行关键点识别。
我假设应该为每个关键点训练一个单独的分类器,我的一些想法是:
-
遍历固定大小的子图像并对每个子图像进行分类,其中以关键点为中心像素的图像为正例。在这种情况下,我不确定如何处理靠近图像边缘的像素。
-
不是训练二元分类器,而是训练具有l*w个可能类别的分类器(每个像素一个类)。这个方法的主要问题是我怀疑它会非常慢,因为每个弱分类器突然需要进行l*w*原始操作。
-
我的第三个想法在我的脑海中还没有完全成形,但由于每个关键点都是面部更大部位的一部分(例如,眼睛的左、中、右部位),也许我可以尝试将子图像分类为仅是眼睛,然后使用最佳拟合子图像的左、中、右像素(在y坐标上居中)来表示每个面部部位。
这些想法有无价值,还有没有我没有想到的方法?
回答:
我最终深入研究了这个问题。我使用了“深度学习”,也就是多层神经网络。我使用了卷积网络。你可以通过查看这些演示来了解更多关于它们的信息:
http://cs.stanford.edu/people/karpathy/convnetjs/demo/mnist.html
http://deeplearning.net/tutorial/lenet.html#lenet
我对典型的卷积网络做了以下更改:
-
我没有进行任何降采样,因为任何精度的损失直接转化为模型得分的下降
-
我进行了n路二元分类,每个像素被分类为关键点或非关键点(我在最初的帖子中列出的第2项)。正如我所预料的,计算复杂性是这里的主要障碍。我试图使用GPU来克服这些问题,但神经网络中的参数数量太大,无法适应GPU内存,所以我最终使用了xl amazon实例进行训练。
这里有一个包含我所做的一些工作的github仓库:https://github.com/cowpig/deep_keypoints
无论如何,鉴于深度学习的流行度激增,肯定有许多人比我做得更好,并且发表了相关论文。这里有一篇看起来不错的报告: