画像生成の構図を制御する
- 2023/02/07
- 20:09
バウンディングボックスを用いたStable Diffusionの構図制御を追加学習無しで行います。
導入
見れば大体分かると思いますが、この手法の詳細を説明します。
この記事の要約はこんな感じです。
- バウンディングボックスによってText-to-Imageモデルの構図を制御する新手法ABaGを提案します。
- ABaGはAttend-and-Exciteを応用した手法であり、on-the-flyで実行されるためモデルの追加学習を必要としません。
- ABaGの実装はここで公開しています。
画像生成に関する知識は素人同然ですが、頑張ります。
導入
Stable Diffusion等のText-to-Imageにおいて、画像の構図を制御することは困難です。
それは、U-Netの構造が物体位置を考慮しないからです。
そのような背景から、AIユーザーたちは狙った構図の絵を出すためにプロンプトを工夫したり、下絵を描いてImage-to-Imageしたりする必要があります。
しかし、そのような作業は属人性の再生産であるばかりか、耐え難いほど退屈であり技術的な面白みにも欠けます。
2023年1月に提案されたGLIGENは、U-Netに対して物体の位置を与えるスマートなアイデアでした。
この手法は下の画像の様に、バウンディングボックスを用いて生成画像の構図をコントロールすることができます。
GLIGENの技術的な概要は下の画像を見てください。
簡単に説明すると、位置情報を考慮するためのアテンション(Gated Self-Attention)を追加し、他のアテンションをフリーズさせて学習を行っています。
この機構によって、画像生成時に物体の位置情報を考慮することができるという理屈です。
既存手法の問題点
確かにこの手法はスマートで面白いのですが、Gated Self-Attentionを学習する必要がある点が少々厄介です。
何故かというと皆が皆モデルを学習する環境を持っているわけではありませんし、大量にあるモデルをひとつひとつ学習していくのはあまり現実的ではないからです。
理想的には、学習を必要とせず、実行時の工夫のみで構図を制御できた方がいい、というのが直感的に思うはずです。
提案手法
という訳でそんな感じの手法を提案します。
私の提案する手法はABaGという名前で、Attention-Based Guide for grounded text-to-image generationの略です。「あばじぃ」と読みます。
ABaGは16×16のアテンションマップに対してバウンディングボックスを適用し、潜在空間を調整することによって画像構図の制御を可能にする手法です。
また、ABaGはモデルの学習を一切必要とせず、実行時の工夫のみで動作します。
従って、Stable Diffusionが動く環境であれば動作します。
それでは、ABaGについて説明していきます。
まずは下の画像をご覧ください、これは、ABaGのアーキテクチャを定式化したものです。
まず、「a mouse and a red car」というプロンプトで画像を生成し、mouseとcarの位置をバウンディングボックスで制御したいと考えます。
ABaGは、画像生成におけるDDPMの各タイムステップにおいて、単語ごとに16×16のアテンションマップを取ってきます。
この際、バウンディングボックス内のアテンションマップ平均値を高く、バウンディングボックス外のアテンションマップ最大値を低くするような損失を算出し、潜在空間の値を更新するというのがABaGの主要なアイデアです。
(BBox内の計算に平均値を採用した理由は、BBox内の大域的な特徴を掴みやすくするためです。)
このように潜在空間を操作することにより、指定した物体がBBox内に出現しやすく、BBox外に出現しにくくなります。
つまり、画像の構図をBBoxによって制御できるようになります。簡単ですね。
この手法の基本的なアイデアはAttend-and-Exciteに影響を受けています。というかフォークです。
Attend-and-Exciteは複数の物体を同時に描画しやすくする手法ですが、画像の構図までは操作できませんでした。
しかし、損失を改造するだけでこんな事ができるようになるのは驚きです。
実験結果
論より証拠を出した方が分かりやすいと思うので、実際にBBoxを使って構図を固定したまま画像生成をしてみましょう。
まず、『a mouse and a red car』というプロンプトで、画面左側にmouseを、右下にcarを配置するようなBBoxを設定してみます。
見た感じ上手くいってます。
次は、『a girl is eating pizza on desk』というプロンプトで、構図を操作してみます。
これも割と上手くいっています。