【鑑黃】nsfw鑑黃

訓練模型

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 鏡像提供了兩種調用方式: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
    }
}

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章