🎭

glazeって効果あるの?〜AI敵対性画像に対する絵柄集中学習の阻害性〜

2023/12/13に公開

はじめに

実験に至った経緯

世には出回っているAI対策、キャラ学習やi2iに対する実験はされていた。
ただ絵柄の集中学習に対する実験は私の探した限りではなく、今回実験するに至った。

今現在の「AI対策」

・glaze
シカゴ大学の教授が提唱した手法。画像にAIだけが強く認識してしまうノイズを画像に埋め込み、AI学習からの絵の保護を行うというものである。
検索すると、AIのキャラ学習については一定の効果があるものの、絵柄の学習についての検証はネットに上がっていない(自分調べ)。
・Mist
こちらはimage2imageには一定な効果を出している。だがやはり絵柄に対する集中学習への検証は私には見つけることができなかった。
・Nightshade
こちらは現時点(2023/12/12)一般公開されていないため、入手した後追加する。他の概念で書き換えてしまうタイプの対策のようだ。現在クローズド公開をしているところとのようだ。

学習に使うデータセット

今回は私の描いてきた絵およそ190枚をサンプルにする。一例を以下に挙げる。
データセットの中の一例

データセットの全ての画像は私が過去自分で描いた画像であり、私自身がつけたタグがペアでついている。アーティストタグはついていない。なぜなら今回データセットに入っている絵は私の物の中の一つの絵柄に絞った物であり、集中学習の結果として一つの絵柄に固定される(または阻害が成功する)ため、アーティストタグで区別する必要性はないからだ。

画像処理

先程のデータセットの画像全てにそれぞれglazeと mistをかけていく。
画像処理段階の設定は、glazeはIntensiveはDEFAULTRender QualityはMidium。
Mistはパラメーターとして--epsilon 16 --steps 10 --input_size 512 --block_num 1 --mode 2 --rate 1 --non_resizeの設定で行った。

両方かけたバージョンを用意することも思いついたが、時間がないので割愛する。というのも、glazeの場合1枚処理するのに約3分、Mistは1枚30分程度かかったからである。データセットの画像量を減らすことも検討したが、この量のデータセットならではの価値を考え、続行した。
「複数がけ」の効果もまた時間があれば追加していこうと思う。

オリジナル画像 glazeをかけた画像 Mistをかけた画像
オリジナル画像 glazeをかけた画像 Mistをかけた画像

同じ絵で比べてみると、見てみたところやはり目視できるノイズは入っている。特にmistはブロックごとに繰り返されているノイズが目立つ。全体画像をクリックして、スマホの場合は拡大などをしてぜひ見てほしい。
また、mistは私のパソコンスペックの関係上、幅512ピクセル大に縮小して実行するのが精一杯だった。画像サイズも学習に影響してしまうと予想されるが、ご了承いただきたい。

実行環境と設定

今回はcolabのこちらのノートを借りてモデルを作った。

今回の手法はLoraではなく FineTuneになる。モデルそのものを改変する手法だ。より高性能でナチュラルな学習となってくれることを期待しているが、Loraでも同様の手順、大凡同様の結果となるだろう。

ベースモデルはstable diffusion現時点(2023/12/12)最新のSDXL1.0を使い、ステップ数は5000。
その他の設定は以下だ。

config

[sdxl_arguments]
cache_text_encoder_outputs = true
no_half_vae = true
min_timestep = 0
max_timestep = 1000
shuffle_caption = false
[dataset_arguments]
debug_dataset = false
in_json = "/content/fine_tune/meta_lat.json"
train_data_dir = "/content/drive/MyDrive/dreambooth/MistOutput"
dataset_repeats = 1
keep_tokens = 0
resolution = "1024,1024"
caption_dropout_rate = 0
caption_tag_dropout_rate = 0
caption_dropout_every_n_epochs = 0
color_aug = false
token_warmup_min = 1
token_warmup_step = 0

[training_arguments]
save_precision = "fp16"
save_every_n_steps = 1000
train_batch_size = 4
max_token_length = 225
mem_eff_attn = false
xformers = true
max_train_steps = 5000
max_data_loader_n_workers = 8
persistent_data_loader_workers = true
gradient_checkpointing = true
gradient_accumulation_steps = 1
mixed_precision = "fp16"

[saving_arguments]
save_model_as = "safetensors"

[optimizer_arguments]
optimizer_type = "AdaFactor"
learning_rate = 4e-7
train_text_encoder = false
max_grad_norm = 0
optimizer_args = [ "scale_parameter=False", "relative_step=False", "warmup_init=False",]
lr_scheduler = "constant_with_warmup"
lr_warmup_steps = 100

検証

まず、上記のnoteにも記述されているプロンプトで試していこうと思う。
尚、seed値は固定するが、追加学習したためモデル自体は別のものである。あくまで絵柄に近いかどうか、もう少し突き詰めるとオリジナル画像で学習した絵柄に近いかどうかの判定を行う。そのため主観が入ることご了承いただきたい。

プロンプト及び設定詳細

1girl, aqua eyes, baseball cap, blonde hair, closed mouth, earrings, green background, hat, hoop earrings, jewelry, looking at viewer, shirt, short hair, simple background, solo, upper body, yellow shirt
Negative prompt: lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry
Steps: 20, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 3436906699, Size: 512x512

ベースモデルはsd_xl_base_1.0

ベースモデル オリジナル画像で学習

SDXLベースモデルで出てきた画像はぱっきりとした塗りなのに対し、オリジナル画像で学習したモデルは、問題なく「学習できてしまった」といえるだろう。瞳の描き方等も再現されている。

glaze画像で学習 Mist画像で学習

モデルが違うのに似たような画像が出てきた。多少の差はあれど、瞳の再現に関してはこちらのほうが優勢かもしれない。これでは。阻害が成功しているとは言えそうにないように見える。

次に、既にデータセットにある画像のタグをプロンプトにしようと思う。
この学習量の場合、過学習は起こしていないので復元とまではいかないが比較する価値はありそうだ。
わかりやすく、先ほど1例に出した紫の女の子のタグを使うことにする。

プロンプト及び設定詳細

1girl, solo, looking at viewer, medium hair, open mouth, blue eyes, purple hair, side ponytail, blue apron, own hands together, star hair ornament, long sleeves, black shirt, red skart, cowboy shot, outdoors, starry sky, standing, hands up, red skirt
Negative prompt: lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry
Steps: 35, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 3775323182, Size: 1024x1024

ベースモデルはsd_xl_base_1.0

ベースモデル オリジナル画像で学習
glaze画像で学習 Mist画像で学習

やはりオリジナル画像での学習は「うまくいっている」ように見える。対してglazeやMistをかけた画像で学習したものは体のバランスがややおかしくみえる。
だがそれを差し引いても「絵柄」の部分はかなり模倣できてしまっていると感じる。ベースモデルとの差を見れば一目瞭然だろう。

最後に、男性も1回比較してこの記事での比較は終了しようと思う。

プロンプト及び設定詳細

1boy,black hair, blue eyes, school uniform, cowboy shot,
Negative prompt: lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry
Steps: 35, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 2279256047, Size: 1024x1024

ベースモデルはsd_xl_base_1.0

ベースモデル オリジナル画像で学習
glaze画像で学習 Mist画像で学習

seed値を固定したおかげか、どれも似たようなデザインの絵が出てきた。やはり絵柄も似ている。

結果

後出しになるが、筆者はこのAI敵対性画像は一定の効果は見られるが、完全に防御するものではなく一定の模倣はできてしまう、ものだと考えていた。
だが結果的には(主観ではあるが)これでは「絵柄に対して防御できるものではない」と結論を付けざるを得ないだろう。

終わりに

Nightshadeが出てきたらまたぜひ試してみたいと思う。

追記

NightShade(とMist2)に対しての実験を以下の記事でおこなった。興味のある人はぜひ確認して欲しい。

https://zenn.dev/mobile_app_hub/articles/f5f3a98074dd30

Mobile App Hub

Discussion