这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
鉴黄检测
那个深夜的电话
“光影”上线第二周的一个深夜,我的手机响了。
“你好,我是 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% 安全 ❌ 误报!问题太明显了:
- 海滩泳装被误判为违规(Sexy 82.1%)——摄影师经常上传泳装人像,这是正常内容
- 日本漫画被误判为色情(Hentai 65.3%)——Hentai 分类对动漫内容的区分度很差
- 艺术裸体漏报了(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%+ 的准确率。这笔钱绝对值得花。
最终方案:阿里云 + 人工复核
我选了阿里云内容安全,原因是准确率最高(特别是对中文场景的优化),而且误报率最低——对于摄影社区来说,误报比漏报更伤用户体验。
集成到异步处理流程中:
审核放在处理之前——违规图片不需要浪费计算资源去压缩和生成缩略图。