見出し画像

Stable Diffusionを使ったイラスト作成の記録(8) ~ ネガティブプロンプトをレイヤーで実現する ~

前回の記事

シリーズ一覧

Layered Diffusion Pipelineを使うためのリンク集

ネガティブレイヤーの導入

CFG(分類器なし誘導)とそれを利用したネガティブプロンプトの活用は、Stable Diffusionで画像生成を行う際に、画像のクォリティを上げる鍵と考えられています。その仕組みは私の以前の記事でも解説しています。

Layered Diffusion Pipelineのライブラリでも、ネガティブプロンプトは各レイヤーごとに設定することが可能となっていますが、これに加えて、レイヤー全体をネガティブプロンプトと似たような働きをさせることができます。これをネガティブレイヤーと呼ぶことにします。

ネガティブレイヤーは通常のレイヤーと同様に設定しますが、いくつか注意点があります。まず、プロンプトとネガティブプロンプトの意味が通常と反転するので、ネガティブプロンプトはpromptとして記述します。また、mask_byに負の数を設定します。mask_by=-6が、cfg_scale=7に相当します。さらに、cfg_scale=1としてネガティブプロンプトは使わない方がよいと思います。

ネガティブレイヤーの設定例はこのようになります。スクリプト全体は後述します。

Layer(
    prompt="lowres",
    cfg_scale=1,
    mask_by=-6,
)

「元素法典」のネガティブプロンプト

ネガティブプロンプトの一般的な考え方は私の以前の記事の通りですが、特に「元素法典」などで利用されているネガティブプロンプトは、非常に長く複雑なプロンプトとなっていることが多いようです。

「元素法典」のネガティブプロンプトでよく使われているフレーズは様々なところで再利用されているものが見られますが、例えば、次のブログ記事でまとめられているものなどがあります。

bad anatomy, bad hands, blurry, missing fingers, error, signature, cropped, username, low quality, text, watermark, normal quality, fewer digits, extra digit, worst quality, jpeg artifacts, lowres, bad feet, disfigured, missing arms, ugly, mutated hands, long neck, duplicate, morbid, bad proportions, fused fingers, multiple breasts, text font ui, cloned face, extra legs, extra limbs, more than 2 nipples, mutation, mutilated, poorly drawn hands, lowers, malformed hands, futa, missing legs, nsfw, too many fingers, tranny, owres, worstquality, missing limb, artist name, bad anatomy disfigured malformed mutated, deformed, fused anus, jpegartifacts, malformed, mutated, out of frame, unclear eyes

出典:ねへほもんの言う言う亭 『AIイラストの解体新書「元素法典」』

このフレーズを、それぞれの意味で分類してみます。また、NovelAIやWaifu Diffusion, Anything V3.0などの学習データとして使われているDanbooruのタグに含まれているかどうかもチェックしました。

好ましくない画質、スタイル

  • blurry

  • low quality (Danbooruのタグにはない)

  • normal quality (Danbooruのタグにはない)

  • worst quality (Danbooruのタグにはない)

  • lowres

  • duplicate

  • morbid

  • worstquality (Danbooruのタグにはない)

  • deformed

好ましくない構図、テーマ

  • cropped

  • futa (Danbooruのタグ: futa with femail, futa with mail, etc)

  • nsfw (Danbooruのタグにはない)

  • tranny (Danbooruのタグにはない)

  • out of frame

好ましくない人物の描写

  • bad anatomy

  • bad hands

  • missing fingers (Danbooruのタグにはない)

  • error

  • fewer digits

  • extra digit

  • bad feet

  • disfigured

  • missing arms (Danbooruのタグにはない)

  • ugly (Danbooruのタグ: ugly man, ugly woman)

  • mutated hands (Danbooruのタグにはない)

  • long neck

  • bad proportions

  • fused fingers (Danbooruのタグにはない)

  • multiple breasts

  • cloned face (Danbooruのタグにはない)

  • extra legs

  • extra limbs (Danbooruのタグにはない)

  • more than 2 nipples (Danbooruのタグにはない)

  • mutation

  • poorly drawn hands (Danbooruのタグにはない)

  • malformed hands (Danbooruのタグにはない)

  • missing legs (Danbooruのタグにはない)

  • too many fingers (Danbooruのタグにはない)

  • missing limb

  • fused anus (Danbooruのタグにはない)

  • malformed (Danbooruのタグにはない)

  • mutated (Danbooruのタグにはない)

  • unclear eyes (Danbooruのタグにはない)

ノイズ、文字など

  • signature

  • username (Danbooruのタグにはない)

  • text (Danbooruのタグにはない)

  • watermark

  • jpeg artifacts

  • text font ui (Danbooruのタグにはない)

  • artist name

その他(誤字など)

  • lowers (lowres)

  • owres (lowres)

  • bad anatomy disfigured malformed mutated

  • jpegartifacts (jpeg artifacts)

追加のDanbooruタグ

主に画質、スタイル関連で、フルカラーのイラスト生成で好ましくないDanbooruタグをさらにピックアップしてみます。

  • monochrome

  • greyscale

  • comic

  • 4koma

  • 2koma

  • chibi

  • sepia

  • lineart

  • sketch

  • simple background

  • rough

  • unfinished

今回使用するネガティブプロンプト

今回は、ネガティブプロンプトの利用を画質の向上に集中しようと考えているため、上記で集めた画質、スタイル関連のDanbooruタグを使います。ShiftEncodingは改行を許容するので、タグ1つずつ改行して並べます。

negative_quality_tags = """
blurry,
lowres,
duplicate,
morbid,
deformed,
monochrome,
greyscale,
comic,
4koma,
2koma,
chibi,
sepia,
lineart,
sketch,
simple background,
rough,
unfinished,
"""

スクリプト

# スクリプト(8-1)
seed, img_strength = 123456, strg(0.75, level=0.5)
neg_scale, neg_after = -4, 0.8
images = pipe(
    initialize=ByImage(
        image="schoolgirl.png",
        strength=img_strength,
    ),
    iterate=[
        Layer(
            prompt=("high school, school ground, school building, cherry tree, "
                    "blue sky"),
            negative_prompt="1girl",
        ),
        Layer(
            prompt="1girl, solo, high school, school uniform",
            negative_prompt="",
            mask_by="schoolgirl_mask.png",
        ),
        Layer(
            prompt=negative_quality_tags,
            cfg_scale=1.0,
            mask_by=neg_scale,
            strength=neg_after,
        ),
    ],
    num_steps=30,
    size=(512, 512),
    rand_seed=seed,
)

ネガティブプロンプトは既存のレイヤーではなく、新規のレイヤーに対して与えられます。ネガティブレイヤーはレイヤーリストの中で最終レイヤーとして設定されます。これにより、すべてのレイヤーが適用された後の画像に対して一括してネガティブプロンプトを適用することができます。

seedとimg_strengthは、これまでの記事を通して見つけた乱数シードとその最適なstrengthパラメータを設定します。これについては、後段で詳しく説明します。

neg_scaleとneg_afterは、ネガティブレイヤーに対するパラメータです。neg_scaleはネガティブプロンプトの強さで、cfg_scaleに対応するものです。neg_scale=-4がcfg_scale=5に対応します。

neg_afterは、画像生成の全ステップ中で、ネガティブレイヤーの適用を始める時点を示します。これはレイヤーに対するstrengthとして指定されます。

Generalized Strengthの概念図

レイヤーに対するGeneralized Strength

レイヤーに対するstrengthは、入力画像に対するstrengthとは逆で、初めはlevel=0.0で、最後はlevel=1.0となるように適用されます。

乱数シードとStrength

今回は、これまでの記事で使われた乱数シードの中から、ある程度下絵の意図に沿った画像が生成されているものをピックアップして使用します。まず、前回の記事から3つ採用し、さらにそれ以前の記事から追加で3つ採用して、前回の記事と同様に最適なstrengthを探索しました。

ピックアップされた乱数シードと、その最適strengthは次の通りです。

# 乱数シードとstrength
cases = [
    (1334630829, strg(0.6, until=0.7)),
    (1124067389, strg(0.9, until=0.8)),
    (129970857,  strg(0.3, until=0.7)),
    (2895285493, strg(0.8, until=0.75)),
    (3545805225, strg(0.7, until=0.75)),
    (1578222291, strg(0.9, until=0.8)),
]
ピックアップされた乱数シードから生成された画像

生成画像

最上段にネガティブレイヤーを適用前の画像と入力画像を表示し、次段以降にネガティブレイヤーを適用した画像を配置しています。

上段から各行ごとにneg_after=1.0, 0.8, 0.7, 0.6と並んでいて、左列から各列ごとにneg_scale=-2, -4, -6と並んでいます。右上が最もネガティブレイヤーの影響が強く、左下が最も影響が弱くなります。

seed=1334630829, strg(0.6, until=0.7)

seed=1334630829, strg(0.6, until=0.7)

ネガティブレイヤーの効果は劇的な効果がありました。特に上段のneg_afterが大きくなるほど強く画像が大きく変化しています。neg_scaleが大きくなると、効果はさらに強くなりますが、同時に画像の歪みが生まれて来ています。

パラメータの組み合わせによっては、校庭が失われたり腕が増えたりしていますが、人物の基本的な描写については最初のラフ画像の全体的に踏襲したものになっているように思います。

この中で一つ画像をピックアップするならば、次のものになるかと思います。人物が高校生らしく、校舎と地面が描かれている点から選びました。ただ、背景や鞄の部分に不自然な部分が残っています。

ネガティブレイヤーのscale: -4 after 1.0

seed=1124067389, strg(0.9, until=0.8)

seed=1124067389, strg(0.9, until=0.8)

先の乱数シードの時も同様ですが、ネガティブレイヤーの適用開始が0.8以前か0.7以後かで、構図が大きく変化しています。画像のstrengthが0.7以前は、構図がまだ固まっていないのではないかと思います。

下2段の画像は、どれもネガティブレイヤー適用前の画像を清書したような画像になっています。右側に行く(scaleが強くなる)と、建物の形状や髪の色の変化が強くなっています。指やリボンなどの細部はどのパラメータを取ってもすべてきれいにまとまったものはないようです。

この中で一つ画像をピックアップするならば、次のものになるかと思います。胸のリボンが不自然な形状になっていますが、それ以外の点は比較的よくまとまっているのではないかと思います。

ネガティブレイヤーのscale: -2 after 0.7

seed=129970857, strg(0.3, until=0.7)

seed=129970857, strg(0.3, until=0.7)

この乱数シードでは、ネガティブレイヤーの適用開始時点の違いで、人物のバリエーションがきれいに分かれています。興味深いことに、すべてのバリエーションが第6回の記事に現れていた人物の上半身に似ていますが、それとは異なり、背景画像や足の位置は一定してネガティブレイヤーの適用前の画像を踏襲しています。

この中で一つ画像をピックアップするならば、次のものになるかと思います。人物のバリエーションの差異が大きく選びづらいですが、背景の建物が高校の校舎に見えるかどうか、という観点で見ると選択肢は大きく狭まります。

ネガティブレイヤーのscale: -4 after 0.6

seed=2895285493, strg(0.8, until=0.75)

seed=2895285493, strg(0.8, until=0.75)

この乱数シードでは、パラメータによる人物の変化は比較的小さめですが、背景がやはり0.8と0.7の間で大きく変化しています。

この中で一つ画像をピックアップするならば、次のものになるかと思います。背景に校舎が描かれていること、人物の下絵との類似度、手など細部の形状の観点から選びました。

ネガティブレイヤーのscale: -4 after 0.8

seed=3545805225, strg(0.7, until=0.75)

seed=3545805225, strg(0.7, until=0.75)

この乱数シードの場合、ネガティブレイヤーの適用前の画像が人物の描画が崩れ気味であったため、ネガティブレイヤーを適用した後も修正しきれていない様子がうかがえます。しかし、ネガティブレイヤーを強く適用することで、相当程度改善することができるようです。

この中で一つ画像をピックアップするならば、次のものになるかと思います。髪の色が下絵から離れていますが、それ以外は比較的類似しているのではないかと思います。

ネガティブレイヤーのscale: -2 after 1.0

seed=1578222291, strg(0.9, until=0.8)

seed=1578222291, strg(0.9, until=0.8)

この乱数シードの場合も、これまでと傾向はほぼ同様で、ネガティブレイヤーの適用開始が0.8と0.7の間で構図に変化が見られます。全体として、比較的下絵を踏襲した画像が多く生成されている様子です。

この中で一つ画像をピックアップするならば、次のものになるかと思います。頭の位置と髪の色が下絵に近く、それ以外の細部の破綻が少ないものを選びました。

ネガティブレイヤーのscale: -4 after 0.8

ネガティブレイヤーの適用前後の比較

ネガティブレイヤーの適用前後の画像の変化を一覧表示してみます。適用後の画像は上記の分析でピックアップされたものを使い、パラメータは各画像のタイトル部に表示しています。

ネガティブレイヤーの適用前後の比較

まとめ

ネガティブプロンプトは画像のクォリティを劇的に改善する

ネガティブレイヤーの適用前後の比較画像を見て分かる通り、画像のクォリティの改善に議論の余地はないと言えます。

レイヤーはネガティブプロンプト適用の柔軟性を高める

ネガティブプロンプトをレイヤーとして適用することで、strengthを使って適用開始時点の調整をしたり、複数レイヤーにまたがって一括してネガティブプロンプトを適用したりすることが容易になります。

ネガティブレイヤーの使用指針

前回までクォリティ向上のためのネガティブプロンプトやネガティブレイヤーは使用しないで試行錯誤を繰り返してきましたが、通常はネガティブレイヤーは初めからセットしておく方がよいと考えられます。

ネガティブレイヤーのパラメータの初期値は、まだ議論の余地が残っているように思われますが、ピックアップ画像のパラメータの分布から、現時点では"-3 after 0.75"あたりを利用するのがよいように思われます。

この記事が気に入ったらサポートをしてみませんか?