手元の画像を元に類似の画像を画像生成AIに生成させたかった（2022年D言語くん生成チャレンジ）

# はじめに

AI技術の発展が目覚ましい昨今ですが、2022年10月ごろから画像生成AIが急速に大衆化して流行を作りました。

今回は [D言語くんアドベントカレンダー2022](https://qiita.com/advent-calendar/2022/d-man) ということで、D言語くんフリークである我々として考えることはただ一つ。

__「画像生成AIになんとかしてD言語くんを描かせたい」__ です！

![dman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11612/ca94ab0a-0769-f282-de47-acec5f8d432f.png)

何ならこの公式絵をそのまま生成させたい。せめてAIでもD言語くんという概念を持っていてほしい。いや持っているはずだ。そうであってくれ

そんなこんなで [D言語くんアドベントカレンダー2022](https://qiita.com/advent-calendar/2022/d-man) の1日目をもらった以下ツイート（出オチ）に至るまでの説明と、画像生成AI内部についての説明兼備忘録です。

https://twitter.com/lempiji/status/1588780170332483585?t=M1DFM5otCJcuGEGXph9i7w&s=19

私個人としては、ホントに雰囲気は良く捉えられていて、あと手と足と目と体の形だけなので、わずかあと一歩届かず…という気持ちです。無念です。


# 作業内容

以下の手順に沿って進めていけば、多くの方が似たような画像を生成できるはずです。

とはいえ特に準備するものはなく、インターネットで無料で計算資源を使わせていただける神々に感謝して既存サービスを利用させていただく方式で進めていきます。

さぁD言語くんを召喚するための媒介となっておくれ…

## 作業ステップ

1. 画像生成AIが使えるサービスを見繕う
2. プロンプトを考える
3. 生成したプロンプトを少し修正したりシードを変えながら生成する（あとはひたすらガチャを回す）

## 今回使う画像生成AIが使えるサービス

画像生成AIといいつつも、その実態は流行りの「Stable Diffusion」と呼ばれる技術群です。
深層学習あるあるですが、GPUをモリモリ使って動かします。またローカルで動かすのはやや手間がかかります。

そこで見つけたのが `Mage` というサービスです。基本無料です。すごい。

https://www.mage.space

ユーザー登録なしに利用でき、サイズは小さめですがそれなりの品質の画像が生成できます。
有料会員になるとネガティブプロンプト（指定した内容から遠ざける）が使えたりするということで、便利に使いたい方はぜひご検討ください。

さて、これで適当な画像を生成してみようと思います。

## プロンプトを用意する
### 概要

今回使おうとしているStable Diffusion系のAI技術は、ある文章を入力として、その入力が意味するところに近い画像を作る、というものです。

もう少し内部についていえば、文章から特徴を抽出、それを元に粗い画像を作り、それを少しずつ綺麗にしていく、というステップになっています。
特に、この入力になる内容を「プロンプト」と呼びます。

要するにプロンプトの元になる文章が必要で、これは人間が用意する必要があります。

しかし、まさにD言語くん中毒の我々にとっては造作もないこと、何やら英語で指定する必要があるそうだが英語力については色々ツールもあるので大丈夫だろう！ガハハ！と考えたのが大きな過ちでした。

### 自分で考える

最初に試したプロンプトは主に以下の内容をベースに少し変形したり並び順を変えたり、といったものです。

- A mascot character
- A cartoon character style
- Body is a large red letter D
- White hands
- White legs
- Stick arms and legs
- Eyes on upper body

あえて分からないだろうとしたプログラミングなどの要素を省きましたが、試せど試せど、出てくるのは妙なぬいぐるみであったり米国風コミックキャラクターばかり。そこはアメリカか。アメリカっぽいな。

何が悪いのか考え、アイデアが出尽くしたのでこの日は一旦諦めることとしました。
絶対になんとかしてやるからな…！


### 自分で考えるのをやめて、画像からプロンプトを逆引きする

私もAI技術者の端くれであるので、自分のアイデア不足によってD言語くんの生成を諦めたくはありません。何としても流行の波に乗りたい。
とにかく作戦を考えて勝利を確定させましょう。

まず今回扱う `Stable Diffusion` 系の技術に限らないのですが、多くの画像生成AIは何かしらの入力を持っています。
今回の `Stable Diffusion` 系モデルの場合、プロンプトとシードと呼ばれる乱数を入力として画像を生成しますが、少し前に流行った `GAN` と呼ばれるモデルでは、実質ただの乱数列のみを入力として画像を生成します。（もちろん微妙に違う亜種もあります）

GANでもStable Diffusion系でも入力と出力の関係がり、当然プログラムなので決まった入力からは決まった出力になることが期待できます。
また今回のように出力が決まっているのであれば、その決められた入出力の関係を何とかして逆算できるのでは？というのが次の作戦です。

実はこれについては既に実績があり、研究された結果として「`Prompt inversion` （プロンプトの逆引き）」と呼ばれています。

この研究成果を活用し、なんとかして公式絵が生成できそうなプロンプトを逆引きしてみよう、ということです。

### 今回逆算する計算式とは？

逆算するにも逆算する計算式を明らかにせねばなりません。
といっても数式を取り扱うわけではなく理解するのは仕組みの概要だけです。

昨今流行っている画像生成の中核技術として、その名前はあまり出てこないのですが「CLIP（Contrastive Language–Image Pre-training）」と呼ばれる文字列と画像の関連性を計算するための仕組みがあります。

CLIPの説明については東京大学松尾研究所所属である松島さんが書かれている以下の記事が詳しいので参考としてみてください。

https://trail.t.u-tokyo.ac.jp/ja/blog/22-12-02-clip/#toc_text_to_image

CLIPが実現するのは「画像と文字列がどれくらい関連するか計算する」ということなのですが、この仕組みをハックして「特定の画像に関連度が高い文字列を探り当てる」という作業が今回目指す「Prompt inversion」となります。

なお実際問題として逆算対象となるCLIPのモデルもその規模や性能からいくつか種類があるのですが、今回使うのはインターネットのサービスなので内部実装がわかりません。逆引きに使えるものは一番良く使われるモデルのようなので、今回もそれに近いと考えましょう。その他細かいこととして考えないことにします。D言語くんさえ召喚できればそれでOKです。

さて、ここまでキーワードさえ押さえれば案外簡単に見つかるもので、深層学習界隈ではおなじみのHuggingFace様にホストされたCLIP-Interrogatorという画像→文字列なモデルが見つかります。
一応2種あり、画像を投げればプロンプトが出てくるUI付き。ありがたや。

https://huggingface.co/spaces/pharma/CLIP-Interrogator

https://huggingface.co/spaces/fffiloni/CLIP-Interrogator-2

これにD言語くんの公式画像を投げることでプロンプトが得られますので、興味のある方は実際やってみてください。
結果はちょっと載せて良いのか判断つかなかったためこの場では省略します。

あとは求めたプロンプトを生成AIに投げれば上手くいくはずです。

なお注意点として、このCLIP部分を攻略しても画像が完全再現できる情報が文章に埋め込まれるわけでもなく、別途組み合わせる乱数の要素が圧倒的に大きいです。
あくまでも特徴だけを抽出し、CLIP部分に効率良く伝える文章が手に入る、というくらいの気持ちでいきましょう。そうでないと心が折れるので。

## 生成したプロンプトを元にシードを変えながら何枚か生成する

あとは [Mage](https://www.mage.space) のサービスに戻って実際に生成してみましょう。

画像生成の内容はCLIPによる条件付けに加えシードの影響が非常に大きいので数試す必要があります。

当然上手くいかないことも多々あると思いますので、あとは執念をもってひたすらガチャを回しましょう。
聖杯はインターネットにあったのだ。感謝の気持ちがあれば無料で10連回せるぞ！（ヘビーに使う場合は課金しましょう）

## 結論

残念無念。今回は画像生成でD言語くんらしきものを生成することはできませんでした。
[自作絵](https://qiita.com/lempiji/items/dd44003481739e3101de)のプロンプトも混ぜたりしつつ、20回くらい生成して出てきたのがツイートの画像です。Dですらない。

実はCLIPが理解できる文章はそもそも学習用データセット(`WebImageText`)が明示されており、ここにD言語くん的な画像がなければそりゃ無理だろう、というお話なのでした。いや、AIの能力次第ではワンチャンあると思っていましたが。

__CLIPの論文関連リポジトリ__
https://github.com/openai/CLIP
（データセットそのものは置かれておらず、作るスクリプトなどがあるようです）

そういった制限から人々は様々な都合の良い拡張を作ろうと考え、たとえば日本語を理解するCLIPが開発されていたりします。

https://qiita.com/sonoisa/items/00e8e2861147842f0237

また、既存の仕組みでCLIP部分を差し替える記事もありますので、これらを組み合わせれば自在にD言語くんを生成できる日も必ずや訪れるでしょう。

https://zenn.dev/discus0434/articles/7ada798c5cc87d

あとはシードのほうも逆算できれば勝利確定なのですが、正直そこまでは手が出ませんでした。

数年前にGANで試して失敗、今年もほんのわずかあと一歩届かずというところでしたが、こういう失敗もあるよねということで仕組みの理解につながれば幸いです。

読者の皆さんもD言語くんを生成できるアイデアがあればぜひ挑戦してみてください！