話題の Stable Diffusion を Google Colaboratory で動かしてみました。
それだけではつまらないので少しだけ改造して prompt を明示的に加減算できるようにしました。
参考の記事
加減算の参考にしました。優しく説明されている良い記事です。
Stable Diffusion
text-to-image の描画 AI です。自然言語で記述された prompt から画像を生成します。デジタルイラスト調、油絵調のものから写真のような画像まで何でも生成します。
どんな感じ?
A cute dog doing programming instead of his owner."
で生成してみました。
ものの数行のコードでこのような画像が生成できます。
prompt に加法性を与える
Stable Diffusion は、与えられた prompt をベクトルとして埋め込んで得られる意味ベクトルを使って画像生成をしています。このような文章の意味を反映したベクトルには意味的な加法性があると言われています。
例えば、
queen = king - man + woman
のような操作が成り立つような空間になっているらしいです。
改造する
pip でインストールした Stable Diffusion を改造して、この加法性を陽に扱えるようにします。
/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py を次のように変更しました。
import inspect
import warnings
from typing import List, Optional, Union
## 省略 ##
def __call__(
self,
prompt: Union[str, List[str]],
prompt_collection: List[str], # 追加
height: Optional[int] = 512,
width: Optional[int] = 512,
num_inference_steps: Optional[int] = 50,
guidance_scale: Optional[float] = 7.5,
eta: Optional[float] = 0.0,
generator: Optional[torch.Generator] = None,
output_type: Optional[str] = "pil",
**kwargs,
):
## 省略 ##
text_embeddings = self.text_encoder(text_input.input_ids.to(self.device))[0]
# ここから追加
for pw in prompt_collection:
p, w = pw.split("::")
p_input = self.tokenizer(
p,
padding="max_length",
max_length=self.tokenizer.model_max_length,
truncation=True,
return_tensors="pt",
)
p_embeddings = self.text_encoder(p_input.input_ids.to(self.device))[0]
text_embeddings += float(w) * p_embeddings
# ここまで追加
## 省略 ##
prompt_collection に "プロンプト::プロンプトの重み" からなるリストを与えてやることで、
写真 - リアルさ * 0.6 + ファンタジーっぽさ * 0.3 + 漫画っぽさ * 0.3
みたいな入力をモデルに与えることができるようになります。
加法性でいろいろ変換
画風変換
portrait of BILL GATES, photo
から "photo, realistic" を徐々に減算し、"drawn by HOKUSAI KATSUSHIKA, ukiyoe" を徐々に加算します。
浮世絵かどうかはよくわかりませんが、徐々に色味が失われて行って最終的に濃淡だけの水墨画っぽい画像になっています。
ただ、写真と絵の境界ははっきりしているように見えます。(急に絵になったな、と思う画像が出てくる)
これはモデルの特性かなと思っています。
性転換
portrait of STEVE JOBS, photo
から "male" を徐々に減算し、"female" を徐々に加算する。
なるほど。
おわりに
少しだけ Stable Diffusion を扱ってみました。
構図のコントロールが難しいです。