見出し画像

Stable Diffusionを使ったイラスト作成の記録(11) ~ 新機能「SPレイヤー」 ~

前回の記事

シリーズ一覧

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

新機能の追加

前回の記事で、ネガティブレイヤーの効果は次の2つに分解できると指摘しました。

  • 通常レイヤーのCFGスケールを後から増加させる

  • ネガティブプロンプトを後から追加する

このうち1つ目は可変CFGスケールにより実現可能と分かりました。しかし、2つ目については、適切な記述法がまだありませんでした。

SPレイヤー

今回新たに追加された昨日は、SPレイヤーという名前で、Single Prompt Layerの略です。

通常レイヤーがプロンプトとネガティブプロンプトの2つをCFGで合成するという働きをするのに対し、SPレイヤーはプロンプトかネガティブプロンプトのどちらかのみを持ち、単独ではCFGを実行せず、他のレイヤーと組み合わせてCFGを行います。

SPレイヤーと通常レイヤーの合成

このSPレイヤーを用いることで、既存のレイヤーに後から別のプロンプトを追加することが容易になります。

SPレイヤーはスクリプト中で次のように記述されます。

        SPLayer(
            prompt=negative_quality_tags,
            for_negative=True,
            strength=0.8,
            mask_by=0.2,
        ),

デフォルトでは、SPレイヤーはプロンプトに対して作用し、ネガティブプロンプトに作用させるにはfor_negative=Trueを付ける必要があります。また、単独でCFGを行わないので、cfg_scaleはありません。そのほかは通常レイヤーと同じです。

mask_byで既存レイヤーに対する混合割合を指定します。小数で指定することもできますし、マスク画像を使うことも可能です。

注)記事投稿時点では、この機能はGithubにアップロードされていません。可変CFGスケールなどと合わせて、機能を整理してから公開する予定です。
公開しました。https://github.com/nanashi161382/unstable_diffusion/commit/4519db5454a21e916b06e159c6994fa4fe803b05

SPレイヤーでネガティブレイヤーを再現

SPレイヤーと可変CFGスケールを使って、ネガティブレイヤーを再現します。このバージョンのネガティブレイヤーをネガティブSPレイヤーと呼びます。。スクリプトは次のようになります。

# スクリプト(11-1)
seed, img_strength, = 123456, strg(0.75, level=0.5)
scale, neg_after = 20, 0.8
neg_ratio = 0.2

def VariableCfgScale(initial_scale, final_scale, after):
    def callable_cfg_scale(remaining):
        if remaining > after:
            return initial_scale
        else:
            return final_scale
    return callable_cfg_scale

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",
            cfg_scale=VariableCfgScale(4.0, scale, after=neg_after),
        ),
        Layer(
            prompt="1girl, solo, high school, school uniform",
            negative_prompt="",
            mask_by="schoolgirl_mask.png",
            cfg_scale=VariableCfgScale(4.0, scale, after=neg_after),
        ),
        SPLayer(
            prompt=negative_quality_tags,
            for_negative=True,
            strength=neg_after,
            mask_by=neg_ratio,
        ),
    ],
    num_steps=30,
    size=(512, 512),
    rand_seed=seed,
)

seed, img_strength, neg_afterは、第8回でネガティブレイヤーを使った時にピックアップした生成画像の設定から取ったものです。scaleは、同じ設定に含まれるneg_scaleから 4.0 * (1.0 - neg_scale) の計算値を使います。

neg_ratioは、ネガティブSPレイヤーの混合割合です。-neg_scale / (scale - 1) の計算値が等価な値で、neg_scale=-2ならばneg_ratio=0.1818で、neg_scale=-4ならばneg_ratio=0.2105です。今回の実験では、0.2, 0.3, 0.5を使用します。

生成画像

上段は左から、可変レイヤーなし、可変レイヤーあり、ネガティブレイヤーありの画像が並んでいて、下段はネガティブSPレイヤーを使った画像が並びます。左から、neg_ratio=0.2, 0.3, 0.5と並んでいます。ネガティブレイヤーを使った画像に赤枠が付けてあります。

seed=1334630829
seed=1124067389
seed=129970857
seed=2895285493
seed=3545805225
seed=1578222291

可変レイヤーとネガティブSPレイヤーの組み合わせが想定通りの効果を与えていることが確認できました。

ポジティブSPレイヤーを試す

SPレイヤーはネガティブプロンプトだけではく、プロンプトの方に適用することも可能です。これをポジティブSPレイヤーと呼ぶことにします。

ポジティブSPレイヤーを試すにあたって、プロンプトを何にするか決める必要があります。ネガティブSPレイヤーでは画質に悪影響のあるタグを使ったので、今回のポジティブSPレイヤーの実験では逆の効果のタグということで、シンプルに"masterpiece"を使用します。

系統

ポジティブSPレイヤーの適用方法として、3系統の方法を試してみます。1つ目は、先のネガティブSPレイヤーと同じやり方です。下図のように全体の係数を変更せず、既存のプロンプトに新しいプロンプトを混合します。

系統1

2つ目は、既存のプロンプトに掛かる係数を変更せず、新しいプロンプトをその上に足し算します。この場合は、ネガティブプロンプトの係数を、プロンプト全体の係数の増加に合わせて増やします。

系統2

3つ目は、2つ目と同じですが、レイヤーの適用開始のタイミングをneg_afterで指定されるタイミングではなく、画像生成の最初から適用するようにします。

生成画像

最上段は左から、可変レイヤーなし、可変レイヤーあり、ネガティブSPレイヤー20%の画像が並んでいて、次の段から系統1、系統2、系統3と並んでいます。各系統は混合割合が左から10%, 30%, 50%の順に並んでいます。ネガティブSPレイヤー20%の画像に赤枠で印がつけられています。

seed=1334630829
seed=1124067389
seed=129970857
seed=2895285493
seed=3545805225
seed=1578222291

まとめ

ネガティブSPレイヤーは有用

可変CFGスケールとSPレイヤーの組み合わせで、ネガティブレイヤーの効果を適切に分解して、それぞれ独立に設定することができることが分かりました。

ポジティブSPレイヤーは今後も調査が必要

SPレイヤーの導入で、ネガティブSPレイヤーに加えて、ポジティブSPレイヤーを設定することができるようになりました。この新機能の活用方法については、今後の検討課題となります。

いいなと思ったら応援しよう!