SDXLで生成した画像を素材にして、SD1.5のLoRAを作り直す ~ 画像生成AI実験メモ ④-1

本記事に掲載している人物画像は、すべて生成AIにより作成したものであり、特定の実在人物をモデルにしたものではありません。
SD1.5 LoRAの現実
SD1.5のLoRAを作成して、「これで完成!」という感じでSDXLへと話題を移してしまったので、実はちょっとモヤっとしてました。
思っていた以上に、良くも悪くも「顔に変化の無い」画像しか生成できなかったんです。
というのも、学習素材として使用した画像が、1枚の生成画像をimg2imgで微修正して作成した複数の「極めてよく似た画像」で、これを使用して一次LoRAを作成し、そのLoRAで生成された画像を学習素材として二次LoRAを作成し…、と、昇華させていったつもりでいたのですが、SD1.5は固着度合いが半端なく、「学習素材に似てる = ほぼ同じ」か「似ていない = まるで別人もしくは人物画像として成り立っていない」かのどちらかで、顔の傾き違いや首の回転度合い違い、表情違いは、結局、思うようには出せなかったんですね。
なので、「使えるLoRA」なんて銘打ちながら、同じ表情しか出せない「使い勝手の悪いLoRA」を作ったところで幕を引いてしまったんです。
これが心に引っかかっていて、「本当に使えるSD1.5のLoRAを作りたい」という思いが残っていたんです。
じゃぁ、どうするのか。
結局、SD1.5の特性上、生成画像に融通が利かないことを前提に素材を用意するしかなく、顔の傾きを抑止したかったら顔の傾いていない画像が必要で、顔の回転が必要なら少なくとも真正面以外の画像も必要、ということ。
でも、それらを作成済みのLoRAからもimg2imgからも、同一人物(の顔)として作成するのは非常に困難です。
例えるなら、タイムマシンを手に入れるには、まず未来に行く必要がある、みたいなパラドックスですよね。
ただ、それを解消できそうなのが、1枚の画像からSDXLのLoRAを作成する、というルートを経ることです。
わずか1枚の小さな画像から作成したSDXLのLoRAは、想像していた以上に融通の利く画像生成を実現してくれますので、これをSD1.5の学習素材に使用する、という発想ですね。
用意した学習用画像
用意したのは、
・顔のアップ(1024×1024):10枚
・胸から上(896×1152):10枚
・上半身(896×1152):6枚
・腰から上(768×1344):4枚
の計30枚です。

ちょっと、「顔のアップ」と「胸から上」、「胸から上」と「上半身」の境があいまいですが、これは、それぞれ作成した時のプロンプトに起因してます。
いずれも、このようなプロンプトで、もちろん、SDXLのモデルで作成しています。
prompt
<lora:ai_model_sdxl_b1-000180:0.85>
young woman, solo, close-up portrait,
three-quarter view,
gentle smile,
plain background,
photo, realistic, natural lighting
Negative
prompt
(worst quality:2), (low quality:2), (normal quality:2),
lowres, blurry, jpeg artifacts,
extra fingers, mutated hands, bad hands,
bad anatomy, bad proportions,
extra limbs, malformed limbs,
text, watermark, logo
プロンプトの、「close-up portrait」というところを、「bust shot」「upper body」「full body」として、それぞれ30枚ずつくらいですかね、生成して、選別してます。
顔の雰囲気を残しつつ、できるだけいろいろな角度を向いたものを、という基準での選考ですね。なんせ、SD1.5は、自由が利かない。これを頭に叩き込んでおく必要があります。
でも、改めてSDXLでの生成画像を見ると、わずか1枚の生成画像から、よくこれだけの展開が出来るLoRAが作成できたものだと思います。これならSD1.5で頑張らなくても…、というのはやめておきます(笑)
ところで、SD1.5に1024×1024?しかも縦長画像?と思われるかもしれませんが、もちろん、学習時にkohya_ssが画像を縮小します。
なら、なぜに?というところですが、1024×1024で作成した方が、縮小後も顔や紙の情報が比較的きれいに残るんだそうです。このサイズの方がSDXLの特徴を活かせる、というのもありますしね。
また、縦長(横長の場合も)のケースですが、 kohya_ss で resolution=512 (SD1.5での基準サイズ)、bucket有効を設定すると、512×512の正方形に収まるように縮小されるように思われがちですが、512×512相当の面積に収まるサイズ(かつ、bucket stepで割り切れる解像度)で縦横の解像度が決まるそうです。
なので、resolution=512、bucket step=64、bucket有効なら、
1024×1024 -> 512×512
896×1152 -> 448×576
768×1344 -> 384×640
あたりで学習されることになります。resolution=512なので、そこが上限という印象があったんですが、そうでもないようですね。
それぞれの画像に付けるキャプションですが、今回もシンプルに、
ai_model_v6, close-up
としようと思ったのですが、写真を見て頂くとお分かりの通り、生成時にシンプルな背景と指定したのですべてグレーの背景となっています。同じものは固着して学習する可能性が高いので、
ai_model_v6, close-up, gray background
というようにしました。
close-upの部分を、bust shot、upper body、full bodyに入れ替える感じですね。
kohya_ss のパラメータ設定
素材が揃ったところで、学習を始めます。
使用するモデルは、引き続きSD1.5のベースモデル、v1-5-pruned-emaonly.safetensors です。
学習素材が30枚なので、総ステップが2,000~2,500に収まる範囲が良いかと思い、画像の繰り返しは1、Epoch 80 あたりとします。総ステップ数が2,400ですね。
他に触ったパラメータは、このあたりでしょうか。
Network設定
network_dim = 32
network_alpha = 16
学習率
unet_lr = 0.000075
text_encoder_lr = 0.000025
learning_rate = 0.000075
顔の固着を防ぐため、少しだけ学習率を下げています。
これで実行。
5070Tiで8分程度、2060SUPERでは、gradient_checkpointing = true にしたことも影響するのか23分程度になりました。
パラメータが同一ではないので全く同じとは言えませんが、確認は主に5070Tiの方で行います(画像生成時間との兼ね合いです)。
改善の程は?
まずは、シンプルに顔の生成。
のときに使用したプロンプトを再利用。
X/Y/Z plot を使用して、epochの10~70と枝番なしの8パターンと、効き具合(weight)の0.2、0.4、0.6、0.8、1、1.2の6パターンを掛け合わせて生成してみました。

この顔の傾きはどこからきているのか(どのあたりに強く出ているのか)、分布がよく判らないですが、初期のSD1.5 LoRAよりは融通が利きそうな感じになっています。
学習が進む(epochの値が大きくなる)につれて、また、重みが大きくなるにつれて、学習素材の顔の特徴が出てきているのが判ります。
続いては、プロンプトの効きを確認するためのポーズ指定。腕上げから。
プロンプトやパラメータはこの時のものを使用していますので、再掲は省略します。
明らかにLoRAが効いていない weight 0.2と、上限に達した感のある1.2は落としました。

ポーズの効き(腕の上げ具合)は、やっぱり、weight が小さめの方が効くんですよね。この傾向は腕組みでも同じでしたので、掲載は省略。
これとは違う面白い傾向が出た「腰に手」を。

使用したSeed値の影響が大きいんでしょうね、「simple background」というプロンプトですが、全体的に植物園的な背景になっています。Seed値はやっぱり重要なんですね。LoRAの特性が勝つか、Seedの特性が勝つかはいろいろ試してみないと判らないところがあります。
まぁ、そんな感じで、結局のところ「これがベスト」というepoch数を決めるのは、やっぱり難しいな、と思います。
ただ、なんというか、金太郎飴的な「同じ表情の同じ顔」が生成される前作よりも、表情は多少豊かになったのではないか、と思います。
日常風景の画像生成
では、本当に使えるLoRAと言えるのか?ということで、プロンプトを変更して日常風景の画像を生成してみたいと思います。
で、どのLoRAを使用するのか、という選別に悩んでいるわけですが、結局、どんな画像を生成したいのか、ということにかかってくるんじゃないかと思います。
というわけで、オフィスの風景を出力するのにベストなものを選ぶために、こういうことをしてみました。

全体に悪くは無いですね。ただ、weightが1.0になると真っすぐしか現れない傾向が強く、0.8あたりがベストなのかな、と。そのなかでも表情を良く出していて、顔に回転方向の傾きがみられる epoch60~80(無印)あたりがベストなのかな、と思います。
というわけで、epoch60、weight0.8でいくつか、Seed値を変えながら生成してみたいと思います。
アイキャッチ画像にも使用できるよう、横長の 640×320 で作成します。プロンプトは、前回と同じものです(LoRA指定部以外)。


こんな感じですかね。なんか、SDXLのときと比べると、若干違和感を覚えるんですが、SD1.5なので致し方なし、という感でしょうか。それでも、前回の最終で出した

これよりは、「造りもの感(生成AIの画像感)」が、かなり緩和されていると思います。
山登りのも出してみました。
プロンプトはSDXL編で、最後に出力したものをそのまま使用しています(LoRA指定部以外)。


SDXLで出た山登りの重装備感が全く感じられないのは、プロンプトの解釈がSD1.5よりもSDXLの方が的確だということを示してるんでしょうかね。
ここまでで、前回のSD1.5で作成した「使えるLoRA」よりは格段に使いやすくなっていることはお判り頂けたかと思います。
…が、事実を言います。
この画像を生成するためにオフィス版、山登り版ともに、50枚近い画像を生成し、選りすぐりを掲載しています。
5070Tiで作成すると1枚当たり1.5秒ですので、それほど苦にはならないんですが、2060SUPERで作成すると、1枚当たり4.6秒ほど。SDXL版に比べると遥かに短いとはいえ、「これ」という画像を得るには大量生産する必要があるのが事実です。
SD1.5の宿命
では、「ボツ」にした画像は、何がダメだったのか、というところですが、もちろん、LoRAの学習素材に明らかに似ていないものは参考例とするには相応しくないので外しています。例えば、このようなもの。

とはいえ、これはまだ「良い方」です。
圧倒的に多いのが、このように、人の顔としてアンバランスな構成になっているもの、なんです。

特に、山登りの方は、プロンプトで上半身と指定はしているものの全身に近い描画が比較的増え、顔が小さいものになればなるほど、このような顔の崩壊が発生しています。

崩れの程度は様々ですが、傾向として顔が小さいものほど崩壊の度合いも増します。

これが、50枚の中で最も顔が小さかったものですね。
LoRAの顔に似てる似ていない、という次元とは異なる話です。
ただ、これは、SD1.5の宿命でもあるんです。
例えば、512×512ピクセルの画像を生成する場合でも、ノイズ除去による画像生成は、およそ64×64の潜在空間(latent space)上で行われます。例えば、完成画像(512×512)上の顔が縦横32ピクセルしかなければ、潜在空間では単純計算でわずか4×4程度の領域になるわけです(最後の画像の顔がちょうど縦横32ピクセルほどです)。
この限られた領域の中に、両目、鼻、口、顔の輪郭、眉、髪との境界などを、それらしく配置する必要があるんですね。
潜在空間では、プロンプトの内容を手掛かりに、U-Netによるノイズ除去がステップ数だけ繰り返されます。最後にVAEデコーダーが、完成した潜在表現を通常の画像に戻します。
とはいえ、Stable Diffusionの中に「人の顔はこの位置に目があり、ここに鼻がある」という設計図があるわけではなく、学習した大量の画像をもとに、「人の顔らしいもの」を推測して描いているだけです。
4×4程度しかない領域の中で顔の各パーツを正しく並べる、というのは考えただけでも難しく(無理があるんじゃない?と)、小さな顔が破綻してしまうのも頷けます。
この様子をChatGPTに図示してもらいました。
とはいえ、理由を知って、ただ残念がっているだけでは先へと進まないので、次のステップで、この「顔崩れ」を改善できないか、と、トライしてみました。
この続きが、こちらになります。
Stable Diffusionの環境構築からLoRA作成、SDXLでの検証など、画像生成に関する記事一覧は、以下のまとめページに整理しています。
















