鉴黄检测

那个深夜的电话

“光影”上线第二周的一个深夜,我的手机响了。

“你好,我是 XX 区网安大队的。有人举报你的平台上有涉黄图片,请立即处理。”

我打开后台一看,一个刚注册的用户上传了 17 张图片,其中 12 张是色情图片。它们已经在线上存在了 3 个小时——被 200 多个用户浏览过。

我花 10 分钟手动删除了所有违规图片,然后坐在椅子上发了 5 分钟的呆。

如果我当时在睡觉呢?如果这个用户上传了 100 张呢?

作为平台方,我要对用户发布的内容负责。但我总不能 24 小时盯着后台。

我需要自动化审核。

第一版:开源模型 NSFW.js

我首先找到了 NSFW.js——一个基于 TensorFlow.js 的开源鉴黄模型,可以在浏览器端或 Node.js 端运行。

测试结果:

NSFW.js 测试结果

图片                判定      Porn    Hentai  Sexy    实际
─────────────────────────────────────────────────────────────────
风景照              ✅ 安全   0.1%    0.0%    0.2%    安全 ✅
人像                ✅ 安全   2.3%    0.1%    15.4%   安全 ✅
海滩泳装            ❌ 违规   3.5%    0.2%    82.1%   安全 ❌ 误报!
色情图片            ❌ 违规   96.2%   0.3%    2.1%    违规 ✅
艺术裸体            ✅ 安全   42.1%   0.5%    38.2%   灰色 ⚠️ 漏报
日本漫画(正常)    ❌ 违规   1.2%    65.3%   3.2%    安全 ❌ 误报!

问题太明显了

  1. 海滩泳装被误判为违规(Sexy 82.1%)——摄影师经常上传泳装人像,这是正常内容
  2. 日本漫画被误判为色情(Hentai 65.3%)——Hentai 分类对动漫内容的区分度很差
  3. 艺术裸体漏报了(Porn 42.1%,没超过 60% 阈值)——这其实应该至少进入人工审核

准确率统计(200 张测试集):

NSFW.js 准确率

                 实际安全    实际违规
判定安全           85          12       ← 12 张漏报
判定违规           15          88       ← 15 张误报

准确率:   86.5%
误报率:   15.0%   ← 15% 的正常图片被错误拦截
漏报率:   12.0%   ← 12% 的违规图片没被发现

对于一个内容平台,12% 的漏报率意味着每天 1000 张上传中有 3~5 张违规图片会漏网。

调整阈值:两头为难

我试了调整阈值:

结果:

阈值 Porn>0.4, Sexy>0.6 (严格):
  准确率: 82.0%
  误报率: 25.0%   ← 太高!用户正常的泳装照被拦截
  漏报率: 3.0%

阈值 Porn>0.6, Sexy>0.8 (中等):
  准确率: 86.5%
  误报率: 15.0%
  漏报率: 12.0%

阈值 Porn>0.8, Sexy>0.9 (宽松):
  准确率: 83.5%
  误报率: 3.0%
  漏报率: 30.0%   ← 太高!大量违规图片漏网

严格模式误报太高,宽松模式漏报太高,中间的也不理想。

这就是开源模型的问题——训练数据有限、模型较小、对边缘场景(泳装、艺术照、动漫)的区分度不够。

第二版:云 API

研究了一圈,我发现国内的云服务商都提供了图片内容审核 API,背后的模型用海量标注数据训练,准确率远超开源方案。

我对比了三家主流服务商:

结果:

三家云 API 鉴黄准确率对比(200 张测试集)

服务商        准确率     误报率     漏报率     平均响应时间     单价
─────────────────────────────────────────────────────────────────────
阿里云        97.5%     1.5%      1.0%      200ms          1.5元/千次
腾讯云        96.0%     2.5%      1.5%      250ms          1.2元/千次
百度云        95.5%     2.0%      2.5%      300ms          1.0元/千次
NSFW.js      86.5%     15.0%     12.0%     150ms          免费

云 API 的准确率全面碾压开源模型。
误报率从 15% 降到 1.5%,漏报率从 12% 降到 1%。

成本分析

结论:每个月不到 100 块钱就能获得 97%+ 的准确率。这笔钱绝对值得花。

最终方案:阿里云 + 人工复核

我选了阿里云内容安全,原因是准确率最高(特别是对中文场景的优化),而且误报率最低——对于摄影社区来说,误报比漏报更伤用户体验。

集成到异步处理流程中:

审核放在处理之前——违规图片不需要浪费计算资源去压缩和生成缩略图。