图片审核服务设计方案(一)

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。
    统计报表
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343