1、背景
用户通过制作平台,每天会有上万作品产生,在微信端每天有上百万作品在传播,节假日当天累计访问量会过亿,如果内容中存在涉政、涉黄等信息,很快就会被网监部门点名;公司业务的拓展必然会带来访问量的线性增长,但人力成本不能线性增长;为了助力人工审核,智能审核服务的构建成了必然。
2、一期目标
a、提供审核效果检测功能、审核日志统计功能。
b、将第三方审核接口与自有模型审核接口融合,形成统一对外接口服务,打通图片送审流程。
c、基于深度学习构建涉政人物图片分类模型。
d、提供违禁图片管理功能、搭建自有违禁图片样本库。
e、提供模型管理功能。
3、流程介绍
一期主要以基础框架搭建、服务流程打通为主;针对某一图片审核场景,技术通过管理后台为接口配置该场景下需要用到的模型单元,并为每个模型单元指定不同判断阈值(阈值分三段:通过、不通过、无法识别),多个模型单元组层模型pipline,确认提交后会为该pipline生成一个token,后期用户只需要在送审接口中带上该参数,便可进入正常服务。
每条送审的图片审核完毕后都会生成一条审核日志,基于这些日志,构建了效果监测与日志统计等功能,审核团队可以通过效果监测实时查看到每一张图片审核状态和审核详情(最近30天),审核人员也可将违规的图片导入到样本库;日志统计提供了模型每天的准确度与召回率统计,以及与人工审核的对比数据。
后台配置流程
后台配置主要分为两个部分,模型管理、配置模型pipline
1、模型管理:用户通过该功能新增模型或者修改久的模型(当模型pipline中还在引用模型时,该模型不允许被删除)。
2、模型pipline:针对某一使用场景,选择需要用到的模型,并为每个模型配置对应的阈值,多个模型组合成一个pipline list,提交保存后生成该pipline的调用token。需要注意的是,自建模型的图片输入应该是网络图片加载后的字节对象,避免网络图片被多个模型多次加载影响性能。模型训练流程
使用迁移学习,加速模型构建;如果是从头训练一个模型成本太高,可选用Vgg16、GoogleLeNet等开源模型在自己的数据集上进行微调;
至于数据集的构建可参看cifar-100图像分类模型,它有100个分类,每个分类下600张图片,其中500张训练集和100张测试集;在100个类别之上又被划分为20个大类,每个大类包含5个左右小类,图片分类结果会包含一个小类标签和一个大类标签。图片送审流程
1、用户从后台配置使用场景,构建模型pipline获取token
2、通过接口api将token与图片地址发送给服务器
3、服务器校验token有效性,根据token获取对应的模型pipline
4、根据pipline中各模型识别结果,汇总得出最终结果,返回调用并记录日志效果监测流程
支持机器审核、人工审核信息查看,支持图片入样本库操作。
用户图片请求日志实时写入数据库,通过前端日志管理功能可实时查看每张送审图片的状态,审核同事可通过该页面对图片进行二次确认审核,也可点击【入库】将图片加入审核库。(需要注意的是,如果机器判断为reject的数据,审核人员没有在当日进行二次确认审核,那么次日人工审核状态会变成auto_reject)、数据也会自动入样本库。
4、接口API
-
HTTP_GET:
该接口需要有缓存,缓存有效期内,同一张图片多次调用将不做二次审核。
http(s)://host/verify/img?token=abcd32位字符串&img_url=encoder('http://imghost')
- dubbo
public String verifyImg(String token, String imgUrl)
参数 | 是否必须 | 说明 |
---|---|---|
token | 是 | 用来进行接口请求验证和获取模型pipline,只有有效的token才会返回结果,token从管理后台配置模型时申请 |
img_url | 是 | 目标图片地址,需要进行encoder处理,因为图片都在七牛云,可以在图片地址后面加参数控制清晰度,以降低响应时间 |
- 返回值格式:
{
"timing": 1227,
"code": 200,
"msg": "success",
"request_id": "1556153748009-0eb0e50fc1de",
"image_url": "http://res.eqh5.com/C5BC2989-93D1-4267-AF5D-EE277F691723.jpg",
"suggest": "reject",
"suggest_msg": "图像涉黄",
"pipline": [{
"model": "porn",
"label": "色情",
"suggest": "reject",
"policy":">0.9",
"rate": 0.9022,
"label_details": [{
"rate": 0.9022,
"label": "敏感位"
}, {
"rate": 0.8781,
"label": "穿着暴露"
}]
}]
}
字段 | 描述 |
---|---|
timing | 当前请求处理时间,单位ms |
code | 请求响应状态,具体参见 response code |
msg | 对应 response code 说明 |
request_id | 服务器接收到请求后生成的唯一Id,由13位时间戳+图片地址md5值组成 |
image_url | 目标图片地址 |
suggest | reject 、normal 、 fuzzy |
suggest_msg | 审核结果描述 |
pipline.model | 审核模型:porn、terrorism、illegal、politic、ocr 、ad |
pipline.label | model审核结果描述 |
pipline.policy | model审核结果阈值判定描述,例如:>0.9 reject , <0.3 normal ,(0.3,0.9) fuzzy |
pipline.suggest | model判定结果描述 |
pipline.rate | model 最大label的置信度 (0-1) |
pipline.label_details.rate | model中单个label的置信度 (0-1) |
pipline.label_details.label | model中单个label描述 |
- response code
code | msg |
---|---|
200 | success |
421 | 认证相关:token无效,或未开通相关服务 |
400 | 认证相关:传入参数不对 |
500 | 服务器相关:服务器内部错误 |
510 | 服务器相关:请求太频繁 |
5、模型pipline
pipline是针对具体的使用场景设立的,内部组合多个自有模型和第三方模型协同处理;
输入:针对自有模型统一图片变量,避免一张图片多次加载。
输出:整合多模型判定结果,形成统一的输出格式。
并行还是串行?
并行:执行效率高,可结合多个审核模型结果选出最优判断结果赋值给suggest_msg,但会占用过度的计算资源。
串行:开发难度低、占用资源少,但执行相对耗时,拿不到所有模型判定结果(当遇到模型reject时可进行截断来加速判定)
结论:模型穿行执行。
6、数据库
- Cassandra审核日志数据库
CREATE TABLE verify_log (
product text , # 产品线名称
day text ,
scene_id text ,
req_id text,
img_url text ,
img_del text , #如果图片被删除 img_url中存放的是copy后的地址,否则存放原地址
scene_code text ,
req_time text , #图片请求时间
verify_time text , #机器审核时间
confirm_time text , #人工审核时间
suggest text , #机器审核结果
suggest_msg text , #机器审核结果描述
pipline text , #模型结果详细说明 json
result text , #最终判定结果,人工操作必填项:人工(reject 、normal);自动(auto_reject)
result_class text , #判定具体原因,来自下拉框选择,人工操作必填项
result_label text , #判定具体原因,来自下拉框选择,人工操作必填项
result_tag text , #判定具体原因,来自下拉框选择,可不填
operate_user text , #操作人
operate_time text #操作时间
PRIMARY KEY (product, day,scene_code,req_id)
) WITH CLUSTERING ORDER BY (day DESC,scene_code,req_id)
需要注意的是,日志应在请求code=200的情况下入库,入库时指定ttl,数据在Cassandra端保留1个月
-
Cassandra审核样本数据库
1、用户标记或自动标记为违规的数据会自动加入样本库
2、用户可以批量上传、补充样本库
3、用户可以删除、修改样本库数据
CREATE TABLE train_data (
day text ,
class text,
img_id text, #图片地址md5
label text,
label_tag text ,
img_url text , #为图片copy后的新地址
img_size text , #图片大小
img_shape text , #图片规格
operate_user text , #操作人
operate_time text , #操作时间
operate_mark text #操作记录
PRIMARY KEY (day,class,img_id)
)
此数据永久保存
7、日志统计
-
日志归档
日志每天从Cassandra库归档到HDFS,归档后的数据格式为parquet、并使用snappy压缩,目录规则如下:
/data/verify/img/yyyy/MM/dd
-
模型日志统计
基于归档后的日志,使用spark_shell脚本每天凌晨定时计算,并将计算后的结果存入mysql。