今回は、BigGANの学習済みモデルを使って、サクッと遊んでみようと思います。
こんにちは cedroです。
みなさんBigGAN をご存じですか。BigGAN は、最大512×512ピクセルの高解像度画像を条件付きで生成するモデルで、学習には Imagenet の画像を使っており、なんと1000カテゴリーの画像を生成出来ます。作ったのは、あのDeepMind。
ベースはSA-GAN(Self Attention GAN)で、学習時のバッチサイズを8倍(256→2048)に、全ての層のチャンネル数を1.5倍(64→96)にして大幅なスケールアップを図っています。また画像生成においては多様性と画質がトレードオフになりますが、これを Truncated Trick という手法で上手く両立させています。
BigGAN はそのスケールの大きさから、学習コストも相当かかるようです。当然 Google Cloudを時間貸しで使用することになるわけですが、512×512ピクセルの学習には Google TPUコアを512個使用して48時間掛る模様で、1TPUで4.5$/hなので、 4.5$×512×48=110,592$ (たった1回の学習に100万円以上かかる!)と学習コストもBigです。
今回、この とんでもないスケールのBigGAN の学習済みモデルを、なんとブラウザから簡単に試せることを知り、ワクワクしています。さすが Google さん、この太っ腹!
ということで、今回は、BigGAN の学習済みモデルを使って、サクッと遊んでみようと思います。
まず、デモを動かしてみます
BigGAN TF Hub Demo に行き、Google account でログインします。なお、以下のデモは、スマホでも動きますので、本当に気軽に試せます。
まず、128×128、256×256、512×512の3つのモデルの内、どれを使うか選択するところです。ここでは、デフォルトの256×256をそのまま使います。赤丸の [ ] をクリックするとこの部分のコードが実行されます。
コードの実行が完了すると、[ ] がこんな表示に変わります。後は、これと同じことを繰り返すだけでデモが進んで行きます。
Setup です。必要なライブラリーを読み込みます。
Load a BigGAN generator module from TF Hub です。Web から BigGAN の学習済みモデルをダウンロードします。少し時間がかかります。
Define some functions for sampling and displaying BigGAN images です。読み込んだ BigGAN の学習済みモデルを使って画像表示や画像間補完をさせるための関数を定義します(表示は抜粋です)。
Create a TensorFlow session and initialize variables です。セッションと変数を初期化します。
さて、いよいよ画像生成です。num_samples は生成する画像数の指定です。truncation は閾値(しきいち)の指定で、閾値を大きくすると多様性が大きくなる一方画質は落ちるというトレードオフの関係があるので、適当なところでバランスを取ります。
noise_seed は入力に使っている組み込まれている疑似乱数系列のどれを使うかの指定で、noise_seed が同じであれば、毎回同じ乱数が同じ順序で発生するので、同じ画像を生成します。category は Imagenet の1000個のカテゴリーの中から何を画像生成するのかの指定です。
まずは、デフォルトのチーズバーガーを画像生成してみました。高解像度でリアルです。なんか、急にお腹が減って来ました(笑)。
そしていよいよ、画像間補完です。画像Aから画像Bへのいわゆるモーフィング画像を生成します。num_samples はモーフィングを何回やるかの指定。num_interps はモーフィングを何枚の画像でやるかの指定。truncation と noise_seed は先程と同様ですね。
ゴールデンレトリバーから鶏へのモーフィングです。5枚からなるモーフィングを2回やっています。4枚目あたりは、かなり不気味な感じになりますね(笑)。
デモを動かしている時に、こんな表示が出る時がありますが、迷わず「無視」を押せばOKです。問題なく継続します。
実は、このデモはGoogle Colab というサーバー上のディープラーニングマシンで動いていて、デモプログラムは各個人に割り当てられたメモリを目一杯使う設定になっているので、こんな警告が出るようです。
それにしても、学習は既に終わっていて画像生成するだけなのに、9.20GB のGPUが必要な訳ね。うー、やっぱりBigだわ。
生成画像全体を見てみる
BigGAN は1000カテゴリーの画像生成ができるのですが、具体的にどんなものがあるかザッと見てみたいですよね。実は、このデモは Jupiter Notebook という形式で書かれているので、コードを簡単に追加できるんです。1000カテゴリーの画像を一覧で見るコードを追加してみます。
ページ上部にある、赤丸の+コードをクリックします。
すると、コードを入力するところが表示されます。ここに、コードを書き込んで、ボタンを押せば、この部分だけが追加で実行されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import matplotlib.pyplot as plt z = truncated_z_sample(1, 0.4, 0) for cnt in range(0,999,100): print str(cnt)+'-'+str(cnt+99) r,c =10,10 fig, axs = plt.subplots(r, c, figsize=(15,15)) for i in range(r): for j in range(c): ims = sample(sess, z, cnt, truncation=0.4) axs[i,j].imshow(ims[0]) axs[i,j].axis('off') cnt +=1 plt.show() |
1000カテゴリーの画像を1カテゴリー1枚で、10×10=100枚の単位で表示するコードです。これを先ほどのところにコピペします。
はい、これでボタンを押せば、ここの部分が追加で実行されます。
コードを実行すると、10×10の画像が10枚出力されます。これはその一部で100-199の生成画像です。前半は水辺にいる動物、後半は犬が多いようです。
これで、画像はまとめて見れますが、カテゴリー名一覧も見たいですよね。それを見るには、
先程、チーズバーガーを画像生成したここをダブルクリックします。
そうすると左側にコードが現れます。Categoryの行には、登録カテゴリー名が全て記載してありますので、これを何処かにコピーして検索すれば、カテゴリー名からNo.を知ることが出来ます。
画像ピックアップ
私の独断と偏見で、どんな生成画像があるか、いくつかピックアップしてみます。
1000カテゴリーの画像の中で最も数が多い動物は「犬」です。人類が初めて飼い始めた家畜が「犬」だそうで(猟犬として使っていたようです)、人気です。確かに、高解像度で完成度が高いです。
家畜と言えば、猫も外せませんが、カテゴリー数はあまり多くありません。282トラ猫と260エジプト猫は、全く同じ姿勢なのですが、なぜでしょうか。
動物系です。ニワトリ、ペンギン、インド象、パンダ。
乗り物系です。779スクールバスは、猫バスのモーフィングを作る時に欠かせません(笑)。
スポーツ系です。今までかなりの高解像度の画像生成でしたが、人物の画像生成はまだ不得意なようです。全体の雰囲気は出ているのですが、顔や手足の細部の表現が難しいようです。
コスチューム系です。これも人が絡んでいますので画像生成はあまり上手くいっていません。445ビキニは安物のダッチワイフみたいですね(笑)。697パジャマは、1000カテゴリーの中で一番怖かったです。なんで顔がここまで不気味なんでしょうか。
料理系です。主にファストフードがあるくらいで、あまり多くないです。
その他です。850ティディベアは、動物をぬいぐるみ化する時に使いたいなと思っています(笑)。
以上、ざっと見てきましたが、人間が絡む画像以外はかなりのクオリティで画像生成が行われているようです。
truncation(閾値)を変化させてみる
1 2 3 4 5 6 7 8 9 10 |
truncation = [0.1, 0.4, 0.7, 1.0] for i in range(4): z = truncated_z_sample(num_samples, truncation[i], noise_seed) y = int(category.split(')')[0]) print(truncation[i]) ims = sample(sess, z, y, truncation=truncation[i]) imshow(imgrid(ims, cols=min(num_samples, 5))) |
3行目の truncation = … は先頭に#を付けてコメントアウト(無効化)し、category = … から下の行に先程のコードを上書きします。閾値は、0.1, 0.4, 0.7, 1.0 と4段階に変化させ、各閾値毎に5枚の画像を生成させます、noise_seed は 9 で、category は282トラ猫です。
画像生成の結果です。左端の数字が閾値で、閾値が大きくなるに従って、多様性は大きくなる一方で画質は低下するというトレードオフの関係があることが分かると思います。
モデル内部でこれをどう活用しているかと言うと、学習時は入力に正規分布のランダムノイズを使いますが、学習完了後の画像生成時は入力の正規分布のランダムノイズの幅を狭める(幅が大きいランダムノイズは使わずに再度発生させる)ことで、多様性と画質の両立を図っています。どの程度ランダムノイズの幅を狭めるかの指定に使っているのが閾値なのです。また、この手法を論文では、Truncated Trick と呼んでいます。
モーフィングをやってみる
3×3でモーフィングの画像を生成します。num_samples = 3 にして3回トライ、num_interps = 9(3×3⁼9枚)、282トラ猫から779スクールバスへのモーフィングをさせます。また、3×3の形にするために、コード最終行の cols = interps → cols = 3 に変更しています。
猫バスです。こういうのが出来るとトトロの実写版が出来るかも(笑)。
187ヨークシャテリアから247セントバーナードへのモーフィングです。同じジャンルの動物だとモーフィング途中も、自然な感じですね。
モーフィングをGIF動画にしてみる
猫バスのモーフィングをGIF動画にするために、コードをちょっと修正します。num_interps が最大10では滑らかなGIF動画になりませんので、スライダーの設定を max:10 → max:40 にし、num_interps = 40 にします。
また、生成画像は1枚1枚単独になったものが欲しいので、一番最後の行を上記のように、修正します。画像生成が完了したら、必要な画像をブラウザからドラッグアンドドロップで保存できます。
猫バスです。GIF動画は、GIFアニメ作成というサイトを使って作成しました。
おまけに、猫ピザもどうぞ!(笑)
生成画像を合成してみる
207ゴールデンレトリバーから850ティディベアへのモーフィングですが、赤枠の丁度中間点を見て下さい。ゴールデンレトリバーの可愛いヌイグルミに見えませんか。形が大体同じで質感も似ているものは、その中間点は上手く合成されたものになるようです。
385インド象から847戦車へのモーフィングです。赤枠の中間地点を見て下さい。なんか、トランスフォーマーという感じになっています。
いやー、BigGANデモ、色々遊べて楽しいです。これ映像関係の人とか、かなりイマジネーションがわくツールになるんじゃないかな。
では、また。
コメントを残す