訓練模型
nsfw_data_scraper訓練
- 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/nsfw_data_scraper docker_nsfw_data_scraper 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
模型
訓練好的模型 https://github.com/rockyzhengwu/nsfw
- git clone https://github.com/rockyzhengwu/nsfw
訓練好的模型在 data/
目錄下。
- cd nsfw
- python nsfw_predict.py /tmp/test/test.jpeg
輸出結果:
- {'class': 'sexy', 'probability': {'drawings': 0.008320281, 'hentai': 0.0011919827, 'neutral': 0.13077603, 'porn': 0.13146976, 'sexy': 0.72824186}}
class
: 圖片所屬列表 probability
: 各類別所屬的概率得分
鑑黃服務
模型數據訓練好以後就是搭建服務了,這裏我們直接使用TensorFlow
的 TensorFlow-serving
對外提供服務,爲了安裝方便,我們使用Docker
安裝部署。
NSFWDATA="/home/www/nsfw/data" 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 } }
python腳本
import sys import json import requests from PIL import Image import numpy as np _IMAGE_SIZE = 64 # TensorFlow-serving 調用地址,這裏要替換成自己的,後面會講到如何安裝 SERVER_URL = 'http://192.168.1.123:8501/v1/models/nsfw:predict' _LABEL_MAP = {0: 'drawings', 1: 'hentai', 2: 'neutral', 3: 'porn', 4: 'sexy'} def standardize(img): mean = np.mean(img) std = np.std(img) img = (img - mean) / std return img # 導入 def load_image(image_path): img = Image.open(image_path) img = img.resize((_IMAGE_SIZE, _IMAGE_SIZE)) img.load() data = np.asarray(img, dtype="float32") data = standardize(data) data = data.astype(np.float16, copy=False) return data # 分析 def nsfw_predict(image_data): pay_load = json.dumps({"inputs": [image_data.tolist()]}) response = requests.post(SERVER_URL, data=pay_load) data = response.json() outputs = data['outputs'] predict_result = {"classes": _LABEL_MAP.get(outputs['classes'][0])} predict_result['probabilities'] = {_LABEL_MAP.get(i): l for i, l in enumerate(outputs['probabilities'][0])} return predict_result if __name__ == '__main__': image_data = load_image(sys.argv[1]) predict = nsfw_predict(image_data) print(predict)
安裝python3和pip3
安裝腳本依賴
sudo pip3 install Image # 如果報錯 sudo yum install python3-devel sudo pip3 install requests sudo pip3 install numpy
執行
[root@localhost data]# python3 yellow /home/1.jpeg {'classes': 'neutral', 'probabilities': {'drawings': 0.00102156017, 'hentai': 0.000259996828, 'neutral': 0.998707414, 'porn': 1.07145597e-05, 'sexy': 3.48052083e-07}}
Java調用python
// yellowPath 腳本存放位置,後面會講到 @Value("${yellow.path}") private String yellowPath; /** * 自家庫鑑黃 * @param imagePath 作爲參數供Python腳本使用 * @return */ public String check(String imagePath) { String[] arguments = new String[] {"python3",yellowPath,imagePath}; String classes = ""; try { String line = null; Process process = Runtime.getRuntime().exec(arguments); BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK")); while ((line = in.readLine()) != null) { System.out.println(line); classes = line; } in.close(); int re = process.waitFor(); System.out.println(re); } catch (Exception e) { e.printStackTrace(); } return classes; }
參考鏈接:
https://blog.csdn.net/zhulin2012/article/details/106394274/
https://blog.52itstyle.vip/archives/4863/#%E9%89%B4%E9%BB%84%E6%9C%8D%E5%8A%A1