MTCNN 的 TensorFlow 实现

代码及原文贴在我的 github 上: https://github.com/FortiLeiZhang/model_zoo/tree/master/TensorFlow/mtcnnMTCNN 的 TensorFlow 实现Magic Vision 要加人脸识别功能,所以要在 TensorFlow Serving 上起一个人脸识别服务,自然想到的是 Google 的 Facenet。 由...
摘要由CSDN通过智能技术生成

代码及原文贴在我的 github 上:
https://github.com/FortiLeiZhang/model_zoo/tree/master/TensorFlow/mtcnn

MTCNN 的 TensorFlow 实现

Magic Vision 要加人脸识别功能,所以要在 TensorFlow Serving 上起一个人脸识别服务,自然想到的是 Google 的 Facenet。 由于 Google 官方提供下载的 Facenet 模型中有个 bug 导致其 serving 不起来,所以要在他们的源代码上进行修改重新训练。于是乎我想干脆把他们的代码自己重新写一遍算了。至于如何从头开始训练 Facenet,参见这篇 文章

Facenet 的实现过程包括两步,首先是用 MTCNN 将图片中的人脸框出来,第二步是识别框出来的人脸是谁。这里先完成第一步,即 MTCNN 的 TensorFlow 实现,并将得到的 model 在 TensorFlow Serving 上跑起来。

MTCNN 原始论文 中的 代码 是用 MATLAB 实现的。Facenet 只是将 MATLAB 代码翻译成了 TensorFlow , 并使用已经训练好的模型参数。这里不得不吐槽一下原始论文中的 MATLAB 代码,到处都是多余的 T 啊,有事没事的就来个转置,这肯定是平时写论文推公式养成的习惯,见到个矩阵后面就加个 T,本来好好的 (x, y) 坐标,非得要加个 T 变成 (y, x),完事再 T 回来。Google 也耿直,翻译代码的时候也是见到 T 就 np.transpose。我试着将多余的转置去掉,发现不行,结果不对,可能现成的参数就是这么训练出来的,如果去掉转置的话,参数可能对不上。长话短说,还是先看代码吧。

1. Dataset : CASIA-maxpy-clean

Facenet 用的是 CASIA-webface dataset 进行训练。这个 dataset 在原始地址已经下载不到了,而且这个 dataset 据说有很多无效的图片,所以我用的是清理过的数据库。该数据库在百度网盘有下载:下载地址,提取密码为 3zbb。

这个数据库有 10575 个类别,每个类别都有各自的文件夹,里面有同一个人的几张或者几十张不等的脸部图片。MTCNN 的工作就是从这些照片中把人物的脸框出来,然后交给下面的 Facenet 去处理。这里建立一个 ImageClass,存储各个类别的编号名称和该类别下所有图片的绝对路径。

2. 建立 MTCNN 模型

首先要在 main 函数中起一个 Graph,模型的图就建在这个 Graph 中,然后在此 Graph 中起一个 session 来运行函数执行命令建立三个 CNN:Proposal Network (P-Net), Refine Network (R-Net) 和 Output Network (O-Net)。

with tf.Graph().as_default():
    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
    sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
    with sess.as_default():
        pnet, rnet, onet = detect_face.create_mtcnn(sess, None)

Google Facenet 的原作者在建立网络时,自己重写了 CNN 网络所需要的各个组件,包括 Conv 层,MaxPool 层,Softmax 层等等。这里我偷点懒,用现成的 Keras 来实现各个组件。这里先只关注网络是如何搭建的,至于网络的输入输出以及是如何运作的,在下一节细说。

PNet

首先建立一个 variable_scope,在此 scope 中的所有 variable 和 op 的名称都会加前缀 pnet/ 。

输入是一个形如 (None, None, None, 3) 的 placeholder。

然后就是根据文章中的参数建立模型就好了。这里需要注意的地方有两处:

PReLU 层

MTCNN 使用 Parametric ReLU (PReLU) 来引入 nonlinearity,PReLU 的定义如下:

f(x)={ xαxifx>0
  • 19
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值