作者 | 周强(CV君)
来源 | 我爱计算机视觉(公众号id:aicvml)
60s测试:你是否适合转型人工智能?
https://edu.csdn.net/topic/ai30?utm_source=cxrs_bw
什么样的算法才是好算法?
真正能实用的算法才是最好的算法!
这需要实现三个目标:精度高、速度快、模型小!
近期,arXiv新发布的文章《PFLD: A Practical Facial Landmark Detector》,则是实用人脸特征点检测算法的典范。
PFLD算法,目前主流数据集上达到最高精度、ARM安卓机140fps,模型大小仅2.1M!
这篇新出的论文,必将成为人脸特征点检测领域的重要文献,今天我们就一起来探究一下,PFLD算法到底有什么黑科技。
作者信息:
作者分别来自天津大学、武汉大学、腾讯AI实验室、美国天普大学。
感谢各位大牛!
人脸特征点检测的挑战
作者首先从算法实用性角度讨论了人脸特征点检测问题的面临的挑战。
-
Challenge #1 - Local Variation
人脸表情变化很大,真实环境光照复杂,而且现实中大量存在人脸局部被遮挡的情况等。
-
Challenge #2 - Global Variation
人脸是 3D 的,位姿变化多样,另外因拍摄设备和环境影响,成像质量也有好有坏。
-
Challenge #3 - Data Imbalance
现有训练样本各个类别存在不平衡的问题。
-
Challenge #4 - Model Efficiency
在计算受限的设备比如手机终端,必须要考虑计算速度和模型文件大小问题。
算法思想
作者使用的网络结构如下:
其中,
黄色曲线包围的是主网络,用于预测特征点的位置;
绿色曲线包围的部分为辅网络,在训练时预测人脸姿态(有文献表明给网络加这个辅助任务可以提高定位精度,具体参考原论文),这部分在测试时不需要。
作者主要用两种方法,解决上述问题。
对于上述影响精度的挑战,修改loss函数在训练时关注那些稀有样本,而提高计算速度和减小模型size则是使用轻量级模型。
-
Loss函数设计
Loss函数用于神经网络在每次训练时预测的形状和标注形状的误差。
考虑到样本的不平衡,作者希望能对那些稀有样本赋予更高的权重,这种加权的Loss函数被表达为:
M为样本个数,N为特征点个数,Yn为不同的权重,|| * ||为特征点的距离度量(L1或L2距离)。(以Y代替公式里的希腊字母)
进一步细化Yn:
其中
即为最终的样本权重。
K=3,这一项代表着人脸姿态的三个维度,即yaw, pitch, roll 角度,可见角度越高,权重越大。
C为不同的人脸类别数,作者将人脸分成多个类别,比如侧脸、正脸、抬头、低头、表情、遮挡等,w为与类别对应的给定权重,如果某类别样本少则给定权重大。
-
主网络
作者使用轻量级的MobileNet,其参数如下:
-
辅网络
参数如下:
实验结果
作者在主流人脸特征点数据集300W,AFLW上测试了精度,尽管看起来上述模型很简单,但超过了以往文献的最高精度!
下图是在300W上的CED,完美将其他算法的曲线压在下面。
下图为在300W数据集上不同评价标准IPN\IOP精度比较结果,依然是最棒的。
其中PFLD 1X是标准网络,PFLD 0.25X是MobileNet blocks width 参数设为0.25的压缩网络,PFLD 1X+是在WFLW数据集上预训练的网络。
值得一提的是表格中LAB算法,是CVPR2018上出现的优秀算法,之前一直是state-of-the-art。感兴趣的朋友可以参考52CV当时的报道:重磅!清华&商汤开源CVPR2018超高精度人脸对齐算法LAB 。
下图是该算法在AFLW数据集上与其他算法的精度比较:
同样是达到了新高度!
下面来看一下算法处理速度和模型大小,图中C代表i7-6700K CPU,G代表080 Ti GPU,G*代表Titan X GPU,A代表移动平台Qualcomm ARM 845处理器。
PFDL同样是异乎优秀!与精度差别很小的LAB算法相比,CPU上的速度提高了2000倍!
下面是一些特征点检测示例,尽管很多样本难度很大,但PFLD依然给出了可以接受的结果。
作者没有开源代码,但给出了Android应用 APK 和Android工程(算法封装在bin文件里)。
这个算法实在是太吸引人了,你是不是也想试一下呢?
论文作者给的网址:
https://sites.google.com/view/xjguo/fld
可惜国内不能下载,不过不用担心,(本文作者)已经把它搬到百度云了
链接:
https://pan.baidu.com/s/16HjDy9TyotCVwDdd55oWVQ
提取码:glwr
作者也下载了APK试用,表示好像没看到效果,不知是不是手机兼容性有问题。提醒一下,论文作者声明,该工程仅可用于研究比较,如需商业使用需要联系作者获得授权。
论文地址:
https://arxiv.org/pdf/1902.10859.pdf
PFLD算法看起来简单,但精度却很高,这无疑来自作者设计的Loss函数很好的处理了样本类别不平衡的问题,你觉得还有更好的处理方法吗?欢迎留言。
(本文为AI科技大本营转载文章,转载请联系作者)
人工智能的现状及今后发展趋势如何?
https://edu.csdn.net/topic/ai30?utm_source=csdn_bw
群招募
扫码添加小助手微信,回复:公司+研究方向(学校+研究方向),邀你加入技术交流群。技术群审核较严,敬请谅解。
推荐阅读:
❤点击“阅读原文”,查看历史精彩文章。
基础篇(能解决工作中80%的问题):
进阶篇:
其它:
一. MongoDB 复制(副本集)
MongoDB副本集(Replica Set)是有自动故障恢复功能的主从集群,有一个主节点和一个或多个从节点组成。副本集没有固定的主节点,当主节点发生故障时,整个集群会选举一个主节点为系统提供服务以保证系统的高可用。
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
复制还允许您从硬件故障和服务中断中恢复数据。
官网参考:MongoDB副本集
二. 为什么要复制?
保障数据的安全性
数据高可用性 (24* 7 )
灾难恢复
无需停机维护(如备份,重建索引,压缩)
读缩放(额外的副本读取)
副本集对应用程序是透明
三. MongoDB复制原理
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制结构图如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UAcjfDeV-1657022462558)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1224)]
以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
副本集特征:
- N 个节点的集群
- 任何节点可作为主节点
- 所有写入操作都在主节点上
- 自动故障转移
- 自动恢复
四. 设置一个副本集
使用同一个MongoDB来做MongoDB主从的实验, 操作步骤如下:
1、关闭正在运行的MongoDB服务器。
2、通过指定 --replSet
选项来启动mongoDB。基本语法格式如下:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
- 1
五. 案例
4.1 用适当的选项启动副本集的每个成员
sudo rm -rf /MongoDB/node1 /MongoDB/node2 /MongoDB/node3
sudo mkdir -p /MongoDB/node1 /MongoDB/node2 /MongoDB/node3
sudo mongod —bind_ip 192.168.17.129 —port 27020 —dbpath "/MongoDB/node1" —replSet rs0
sudo mongod —bind_ip 192.168.17.129 —port 27021 —dbpath "/MongoDB/node2" —replSet rs0
sudo mongod —bind_ip 192.168.17.129 —port 27022 —dbpath "/MongoDB/node3" —replSet rs0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
还可以通过配置文件中指定副本集名称。启动mongod使用配置文件,与配置选项指定的文件
4.2 mongo shell连接副本集
mongo -port 27020 --host 192.168.17.129
- 1
4.3 初始化initiate副本集
利用 rs.initiate()
会在副本集的一个成员上初始化一个默认的复制集配置。
4.4 验证初始副本集配置
使用 rs.conf()
显示副本集配置对象:
rs0:OTHER> rs.conf()
{
"_id" : "rs0",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.17.129:27020",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("579b3500299da8059cc5fb99")
}
}
rs0:PRIMARY>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
4.5 检查副本集的状态 rs.status()
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2021-07-29T11:13:58.433Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "192.168.17.129:27020",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1200,
"optime" : {
"ts" : Timestamp(1469789441, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-07-29T11:50:41Z"),
"electionTime" : Timestamp(1469789440, 2),
"electionDate" : ISODate("2021-07-29T11:50:40Z"),
"configVersion" : 1,
"self" : true
}
],
"ok" : 1
}
rs0:PRIMARY>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
4.6 将剩下的成员添加到副本集
必须连接到副本集primary主节点, 才能使用 rs.add()
添加剩余的成员。
rs.add()
在某些情况下,触发一个选举。如果连接到主节点primary成为从节点secondary,需要连接Mongo shell到主节点primary继续增加新的副本集成员
利用rs.status()
识别副本集主节点primary
4.7 删除副本
rs.remove("192.168.17.129:27021")
- 1
以上实例会启动一个名为rs0的MongoDB实例,其端口号为27017。
启动后打开命令提示框并连接上mongoDB服务。
在Mongo客户端使用命令rs.initiate()来启动一个新的副本集。
我们可以使用rs.conf()来查看副本集的配置, 查看副本集状态使用 rs.status()
命令



评论记录:
回复评论: