AIが作った画像か判断するAIを作りました
Webサービスとして提供していましたが、飽きたのでクローズしました
Why
ピクシブのお気持ち表明記事の「AI生成作品のフィルタリング機能」というのが気になり、機械学習で作ることが出来るのではと思いやってみることに
Step 1 素材を集める
割愛
Step 2 コードを書く
AutoGluon というAutoML(全自動で良い感じに機械学習してくれる奴)ツールを使ったので、パラメーターの調整や難しいコードは何も書いてません。
過去に使って良い感じになった奴を流用します。
from autogluon.vision import ImagePredictor, ImageDataset
if __name__ == "__main__":
# \imagesの中にはAIが生成した画像フォルダとAIが作ってない画像フォルダを用意
dataset = ImageDataset.from_folder(r'C:\Users\admin\ml\novel\images')
# 学習用やテスト用のデータに分割
train, val, test = dataset.random_split(val_size=0.1, test_size=0.1,random_state=1)
# 何時間も学習させたくないので緩めの設定で
hyperparameters = {'batch_size': 16, 'early_stop_patience': 15}
time_limit = 60 * 60
predictor = ImagePredictor()
predictor.fit(train, time_limit=time_limit, presets='medium_quality_faster_train', hyperparameters=hyperparameters)
# テストデータでどれくらい良かったか出力する
test_acc = predictor.evaluate(test)
print('Top-1 test acc: %.3f' % test_acc['top1'])
# 結果を保存する
filename = 'my.ag'
predictor.save(filename)
Step 3 完成! したのでTFとか出してみる
# モデルロード
filename = "my.ag"
predictor_loaded = ImagePredictor.load(filename)
#データセット読み込み分割
dataset = ImageDataset.from_folder(r'C:\Users\admin\ml\novel\images')
train, val, test = dataset.random_split(val_size=0.1, test_size=0.1,random_state=1)
#予想させる
result = predictor_loaded.predict(test)
# tfとか計算する@合ってるか知らんけど
tp=0
tn=0
fp=0
fn=0
for key, val in test['label'].iteritems():
if val == 0:
if val == result[key]:
tp+=1
else:
fn+=1
else:
if val == result[key]:
tn+=1
else:
fp+=1
print("TP:",tp)
print("FN:",fn)
print("FP:",fp)
print("TN:",tn)
print("Accuracy:",(tp+tn)/(tp+tn+fp+fn))
print(classification_report(test['label'], result))
結果@ random_stateを再生っていした結果です
ラベル0がAIなのでTPがAIをAIと判定
TP: 139
FN: 10
FP: 1
TN: 87
Accuracy: 0.9535864978902954
precision recall f1-score support
0 0.99 0.93 0.96 149
1 0.90 0.99 0.94 88
accuracy 0.95 237
macro avg 0.94 0.96 0.95 237
weighted avg 0.96 0.95 0.95 237
Step 4 Webサービス化
機械学習しているコードは自体はPythonですが、僕はGo言語が好きなのでサーバーはGoで書きます。
Web Page→Golang Echo Server→Fast API→AutoGluon って感じで遠回りしてますが作ります
from autogluon.vision import ImagePredictor
from pathlib import Path
from fastapi import FastAPI
labels = sorted([dir.name for dir in Path(r'C:\Users\admin\ml\novel\images').iterdir() if dir.is_dir()])
print(labels)
filename = "my.ag"
predictor_loaded = ImagePredictor.load(filename)
app = FastAPI()
@app.get("/")
def read_root(file_name: str = ""):
if file_name == "":
return {"Error": "file name not found"}
return check(file_name)
def check(file: str):
result = predictor_loaded.predict_proba(file)
label = labels[result.idxmax(axis=1)[0]]
proba = result.max(axis=1)[0]
print(f'結果: {label} (確信度={proba})')
if label == 'AI':
return {"IsAI": True, "Percent": proba}
else:
return {"IsAI": False, "Percent": proba}
後はGo + Echoで作ったサーバーからFastAPIで作った機械学習して結果を返すだけのサーバーにリクエストを投げて結果を返すだけ
Step 5 世界に公開
クラウドだとGPUの値段で高額請求をされるので、メインPCをそのままポートを開けてクラウドフレア刺して公開です
https://ai.azunyan1111.com/
それで肝心な精度はどうなんですか?
テストデータではAccuracyは95%くらいでAIが作った画像か見抜けるようになりました。
AIが作った画像をAIが作った画像と見抜ける確率は非常に高いですが、手書きで書かれた場合のパターンを宇野ク集められてないので手書きで書いた絵をAIが描いた絵と見誤ることは多々ある感じです。(TFの値とか見ればそう@たぶん)
本職の人ならもっと出せるはず
機械学習知識0の自分でもまあまあの精度が出たので本職のプロがやればフィルタリングは簡単に出来ると思います。
知らんけど