前言

最近在做一款图床服务,关注公号的小伙伴一定记得小柒曾说过,会在周末放出的,不好意思放大家鸽子了。之所以一直没敢放出,是因为鉴黄接口一直没调试好,虽然我对公号的小伙伴百分之百信任,奈何互联网鱼龙混杂,万一上传了什么不雅的图片,然后不巧被某部门发现了,我包括我的服务器域名可就彻底玩完了!

架构

如图,先聊一下图床的架构:

  • Nginx代理那是必备神器了。

  • lua限流是一定的了,虽然前期没啥子流量,后期可能也没有。

  • 限量限制大小也是必须的了,不然带宽受不了。

  • 接入鉴黄,毕竟咱是合法备案网站。

  • 文件多重备份,OSS、分布式文件、本地文件各一份,防止走丢。

  • 为了查询方便,最后落库。

工具

  • SpringBoot,一个简化Spring开发的框架。

  • WebUploader,一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。

  • Python,加持各种开源第三方库处理图片。

  • nsfw_data_scraper,一个近1w星标的珍藏数据资源。

  • docker_nsfw_data_scraper,用于收集训练数据。

  • TensorFlow,开源机器学习库。

  • ResNet,图像分类的预训练模型。

  • TensorFlow-serving,部署tensorflow模型,并提供服务。

训练模型

训练之前,先介绍一个名词 NSFW,之前我也不知道啥意思,毕竟是村里来的,什么泷泽萝拉、松岛枫、小泽玛利亚、吉泽明步、波多野结衣、天海翼、樱井莉亚、饭岛爱、苍井空、麻生希、橘梨纱、武藤兰、泽井芽衣.....是一概不知道的。

NSFW:不适合在工作场合出现的内容(英语:Not Safe/Suitable For Work,缩写:NSFW)是一个网络用语,多指裸露、暴力、色情或冒犯等不适宜公众场合的内容。在给出含有上述内容的超链接旁标注 NSFW,用于警告观看者。

nsfw_data_scraper上传存放了成千上万张图片地址,并对图片进行了分类,以供训练:

  • 绘画(Drawing),无害的艺术,或艺术绘画;
  • 变态(Hentai),色情艺术,不适合大多数工作环境;
  • 中立(Neutral),一般,无害的内容;
  • 色情(Porn),不雅的内容和行为,通常涉及生殖器;
  • 性感(Sexy),不合时宜的挑衅内容。

同时,官方也提供了收集方法:

$ docker build . -t docker_nsfw_data_scraper
Sending build context to Docker daemon 426.3MB
Step 1/3 : FROM ubuntu:18.04
---> 775349758637
Step 2/3 : RUN apt update && apt upgrade -y && apt install wget rsync imagemagick default-jre -y
---> Using cache
---> b2129908e7e2
Step 3/3 : ENTRYPOINT ["/bin/bash"]
---> Using cache
---> d32c5ae5235b
Successfully built d32c5ae5235b
Successfully tagged docker_nsfw_data_scraper:latest
$ # Next command might run for several hours. It is recommended to leave it overnight
$ docker run -v $(pwd):/root docker_nsfw_data_scraper /root/scripts/runall.sh
Getting images for class: neutral
...
...
$ ls data
test train
$ ls data/train/
drawings hentai neutral porn sexy
$ ls data/test/
drawings hentai neutral porn sexy

如何训练模型,后面也很贴心的附上了训练方法,不过这里借用了 TensorFlowResNet 的模型,稍作修改。训练过程太过煎熬、痛苦,已经被湮灭在有限的带宽和无尽的小黄图中。

鉴黄服务

模型数据训练好以后就是搭建服务了,这里我们直接使用TensorFlowTensorFlow-serving 对外提供服务,为了安装方便,我们使用Docker安装部署。

NSFWDATA="/home/nsfw"
docker run -d --rm -p 8501:8501 \
--name nsfw \
-v "$NSFWDATA/models:/models/nsfw" \
-e MODEL_NAME=nsfw \
tensorflow/serving

serving 镜像提供了两种调用方式:gRPCHTTP请求。gRPC默认端口是8500HTTP请求的默认端口是8501,serving镜像中的程序会自动加载镜像内/models下的模型,通过MODEL_NAME指定/models下的哪个模型。

HTTP调用API地址:http://ip:port/v1/models/nsfw:predict

接口返回参数:

{
"classes": "porn",
"probabilities": {
"drawings": 0.0000170060648,
"hentai": 0.00108581863,
"neutral": 0.000101140722,
"porn": 0.816358209,
"sexy": 0.182437778
}
}

图床服务

完事具备,只欠图床,恰好,最近新域名也备案成功了,那就赶紧上线吧。麻溜的开始小范围内测,内测期间各位小伙伴可以多多踢出宝贵意见,2019年12月31日内测结束将清空所有数据,请悉知!

题外话

这篇案例酝酿了许久,还差点导致其难产,其实各种云上都有鉴黄服务,比如阿里云,50w次请求,810RMB,一年有效期,算下来也就不到2分钱。但是肉疼啊,如果省钱的同时又能学习知识,何乐而不为呢?

参考

https://github.com/tensorflow/serving

https://www.tensorflow.org/serving/api_rest

https://www.tensorflow.org/tfx/serving/docker

https://github.com/alexkimxyz/nsfw_data_scraper

https://github.com/tensorflow/models/tree/master/official

https://www.cnblogs.com/weiyinfu/p/9928363.html

https://github.com/tensorflow/models/tree/master/research/slim

https://github.com/tensorflow/models/tree/master/official/vision/image_classification#resnet

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java

机器学习 TensorFlow 实现智能鉴黄的更多相关文章

  1. nsfwjs鉴黄识别最小化案例

    3个月前,也就是2月份左右吧,Github上出现一个开源项目: Infinite Red, Inc.工作室宣布开源旗下基于tensorflow的tfjs的鉴黄小工具 据说是从15000张图片中 进行机 ...

  2. 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期

    腾讯云图片鉴黄集成到C#   官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...

  3. GitHub大佬:供计算机学习鉴黄功能的图片数据库

    ps:学无止境 想要构建一套鉴黄系统,必须有大量的真实图片供计算机进行学习,以便于区分开正常图片和黄色图片. 近期有位加拿大程序员在Github上传了图片列表,里面包含了大量图片地址可以供计算机进行学 ...

  4. 5分钟构建无服务图片鉴黄web应用(基于FunctionGraph)

    函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩.免运维.高可靠的方式运行.即使在一些复杂的web应用场景中,函数工作流也能发挥出令人 ...

  5. python鉴黄程序

    最近有客户向服务器上传了些垃圾图片,和正常图片混合在一起,大概有10W张的数量,在经历了大概3个小时翻了2000多张的时候,手指抽了下,感觉很不舒服,硬着头皮上,写个程序鉴别下吧,但是怎么搞呢,经过从 ...

  6. 5分钟Serverless实践 | 构建无服务器图片鉴黄Web应用

    Serverless是什么 Serverless中文译为“无服务器”,最早可以追溯到2012年Ken Fromm发表的<Why The Future Of Software And Apps I ...

  7. 5分钟搞定图片鉴黄web应用!

    函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩.免运维.高可靠的方式运行.通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻 ...

  8. 阿里云机器学习tensorflow实践

    1,前言 伴随人工智能和深度学习的应用越来越普及,越来越多的开发人员开始投入到智能算法的编程中.由于算法成熟且公开,软件编码这一块不存在难度:但模型训练和预测所需的时间与硬件设备的配置有极大关系,很多 ...

  9. iOS机器学习-TensorFlow

    人工智能.机器学习都已走进了我们的日常,尤其是愈演愈热的大数据更是跟我们的生活息息相关,做 人工智能.数据挖掘的人在其他人眼中感觉是很高大上的,总有一种遥不可及的感觉,在我司也经常会听到数据科学部的同 ...

随机推荐

  1. Centos7.4环境下搭建Python开发环境(虚拟机安装+python安装+pycharm安装)

    目录 一.安装 Centos7.4虚拟机 二.安装 python3.6.7 三.安装 pycharm 一般情况下,大家都是在 Windows平台下进行 Python开发,软件安装和环境搭建都非常&qu ...

  2. (day30)GIL + 线程相关知识点

    目录 昨日内容 进程互斥锁 队列 进程间通信 生产者与消费者模型 线程 什么是线程 为什么使用线程 创建线程的两种方式 线程对象的属性 线程互斥锁 今日内容 GIL全局解释器锁 多线程的作用 计算密集 ...

  3. 百度语音合成---前端vue项目

    ☞:官方文档 ☞:网页示例 具体步骤: 1.通过 socket.io 接收后端传过来的数据. 2.判断是否在播放声音.  如果没有则直接获取百度 token 播放声音 3.如果有,则存入数组.声音播放 ...

  4. Flask:数据库的操作

    1.对数据库的增加操作 在Django中,数据库查询需要借助objects方法,在Flask中也有类似的操作.在执行对数据库的增加操作之前,我们首先需要实例化一个session对象,这里的sessio ...

  5. OA权限设计

    Action表,有多少个Action,就有多少个记录; UserAction表,记录条数 = User数 * Action数,用于最终确定用于能否请求某个action Role角色表,自定义条数; R ...

  6. [2018-01-13] 什么是Django

    什么是Django? Django是一个基于Python的高级Web开发框架 它能够让开发人员进行高效且快速的开发 高度集成(不用自己造轮子),免费并且开源(内部已经实现了许多高级的功能) 浏览器浏览 ...

  7. NOIP模拟 14

    垃圾成绩,一点都不稳定. 如果把数组开小的分得到的话..总分还挺不错.. 那又能怪谁,都快NOIP了还犯这种傻逼错误 nc哥是要阿卡的节奏..真是太强了 某kyh也不知道偷了谁的rp,分高的一批 wd ...

  8. Spring MVC-------文件上传,单文件,多文件,文件下载

    Spring MVC 框架的文件上传是基于 commons-fileupload 组件的文件上传,只不过 Spring MVC 框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现,取消了 ...

  9. 小白学 Python(19):基础异常处理

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  10. HtmlSpanner 使用小结 -- 安卓解析html

    如何利用 HtmlSpanner解析 HTML格式 的字符串: 1. GitHub 下载HtmlSpanner项目 https://github.com/NightWhistler/HtmlSpann ...