機器學習 TensorFlow 實現智慧鑑黃
前言
最近在做一款圖床服務,關注公號的小夥伴一定記得小柒曾說過,會在週末放出的,不好意思放大家鴿子了。之所以一直沒敢放出,是因為鑑黃介面一直沒除錯好,雖然我對公號的小夥伴百分之百信任,奈何網際網路魚龍混雜,萬一上傳了什麼不雅的圖片,然後不巧被某部門發現了,我包括我的伺服器域名可就徹底玩完了!
架構
如圖,先聊一下圖床的架構:
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
如何訓練模型,後面也很貼心的附上了訓練方法,不過這裡借用了 TensorFlow
的 ResNet
的模型,稍作修改。訓練過程太過煎熬、痛苦,已經被湮滅在有限的頻寬和無盡的小黃圖中。
鑑黃服務
模型資料訓練好以後就是搭建服務了,這裡我們直接使用TensorFlow
的 TensorFlow-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
映象提供了兩種呼叫方式:gRPC
和HTTP
請求。gRPC
預設埠是8500
,HTTP
請求的預設埠是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/j