こんにちは。
GANの発音を、「ガン」 or 「ギャン」のどっちかと言われたら、「ガン」な私です(いやまぁ気持ちだけ…)。
さて、先日某つぶやきサイトに流れてくるつぶやきを眺めていたら、衝撃的な動画を見つけました。
ぐぉォォ。。。マジカ。
— Hakky@Julia勉強中(´・∀・) (@St_Hakky) 2017年10月28日
==
Progressive Growing of GANs for Improved Quality, Stability, and Variation https://t.co/Qp8d4N4zXr via @YouTube
それが以下の動画です。
これは、今回読んだ「Progressive Growing of GANs for Improved Quality, Stability, and Variation」というタイトルの論文で提案されているGANで生成された画像なのですが、この動画の驚くべきところはこれが1024×1024のサイズの画像であるという点です...。
なんということでしょうか...永遠に見ていられますね…ちなみに1時間くらいあるやつもあります。
未来を感じますね。
さて、このように生成することが出来る今回の論文の手法なのですが、これまでのGANsと大きく異なると私が認識しているのは、次の3点です。
- 画像のサイズがこれまでよりも圧倒的に大きい
- 学習に黒魔術的なことをしなくても比較的安定して学習でき、且つ多様性を持っている
- 生成した画像が綺麗
これらをどのようにして実現しているかを、これからメモがてら説明していきます。
※追記:ちなみに、この論文はICLRに通りました。
ICLR通ったんだ。/ https://t.co/vNOHSbGtjs
— Hakky@Julia勉強中(´・∀・) (@St_Hakky) 2018年1月30日
ブログに書いてたのでよく覚えてる。また論文読み返してみようかな。【Progressive Growing of GANs for Improved Quality, Stability, and Variation】を読んだのでまとめる https://t.co/YE4BGXCC8V
論文周りの資料
実装
実装は、Lasagne/Theanoベースで、Pythonは2系です。今後はTensorflowも追加するとのこと。また、訓練済みのモデルも公開されているので、利用できます(といっても、それだけで27Gくらいありますが…)。
- Github:GitHub - tkarras/progressive_growing_of_gans: Progressive Growing of GANs for Improved Quality, Stability, and Variation
- モデル:celeba-hq-deltas - Google ドライブ
ちなみに、ソースコードをちら見していたらTheanoだったので、「Theanoで書かれているということは…もしや…!!!」と思ってREADME.mdを読んでいくと、「GPU1つじゃーん、個人でもできるかもじゃーん」って思いましたが、README.mdにかかれているGPUは1400万円します笑。
今回のこの論文はNVIDIA製なので、このGPUが使えるのも納得ですね笑。
個人での実装という意味では、以下のエントリで既にこの手法が試されていますので、こちらも参考になります(といってもハードル高めですが…)。
また、オフィシャルではないですが、他のフレームワークでの実装もあります。
実験により生成した画像が見れる動画
以下の二つです(上であげたのと同じです)。ちなみに、なんか長時間見てると気が狂いそうになります笑(私だけでしょうか笑)。
必要になる事前知識
この論文を隅から隅まで理解しようとすると、必要になる事前知識(Deep Learning周りとか)は結構あり、また当然といえば当然かもなのですが、これまでのGANsの経緯をそこそこ知っている必要があると思いました。
とりあえず、生成器(G)と識別器(D)が競い合うんだなぁでもいいっちゃいいんですが、結構それだけだときついです笑
まぁ、確かにざくっと知るだけならそれでもいいかもですが、それだと積み上げただけって感じの理解で終わると思います(私はこの論文を理解するにあたって結構いろんな論文読みましたがそれでもまだ理解しきれてないので…)。
ということで、必要になる部分(私が改めて見返したり、ここが重要そうって思った部分)についてあげておきます。
GANsについて
基本的なGANsの説明はすでにいっぱい良いものが出ているので、省きます(GeneratorとDiscriminatorが競い合うアレです)。参考になる資料は以下の通りです。
- はじめてのGAN
- できるだけ丁寧にGANとDCGANを理解する - 午睡二時四十分
- NIPS 2016 - Generative Adversarial Networks - Ian Goodfellow - YouTube
- [1701.00160] NIPS 2016 Tutorial: Generative Adversarial Networks
- Generative Adversarial Nets
- タカハシ春の GAN 祭り!〜 一日一GAN(๑•̀ㅂ•́)و✧ 〜 - ABEJA Arts Blog
- [1406.2661] Generative Adversarial Networks
GANsの種類
今回特に知っておくべきGANは次の2つです。
- WGAN-GP
- LSGAN
■WGAN-GP
[工事中]
■LSGAN
[工事中]
勾配降下法
AdamとかRMSPropをノリで理解していると、ちょっと乗り越えられない部分が出てくるので、以下の資料くらいの知識は欲しいかなと思います(私は自分の資料を読み返しました笑)。
www.slideshare.net
特に学習率をどうやって決めているかの部分について理解があるといい感じです。
Batch Normalization
今回はBatch Normalizationは使っていないのですが、使わなかった理由や、なんのために正則化を入れたいかという部分を知るためには知っておくべきポイントになります。
以下の資料が参考になります。
Introduction
注意:頑張ってはいますが、私の解釈が入っていたりする部分があるので、もしかしたら論文と内容が違う可能性があります。見つけた方はご指摘ください汗。
主要な生成モデル
さて、論文に入っていきます。まず、現在の主要な生成モデルとして、次の3つが挙げられます。
- Autoregressive Models : Pixcel CNN等
- Variational Autoencoders(VAE)
- Generative Adversarial Networks(GANs)
当然ですが、それぞれメリットもデメリットもあります。
例えば、Autoregressive Modelsは鮮明な画像を出しますが、latent representationを獲得できず、また実行速度が遅いです。
VAEは学習させることが簡単ですが、ぼやけた画像にどうしてもなってしまいます。
上の二つと比較して、これまでのGANsは綺麗な画像を出力することができるものの、その学習は不安定であり、またとても小さい画像に限られており、加えて表現できる幅も小さかったです。
今回の論文では、この「学習の不安定さの解消」と「より大きな画像及び多様性のある画像の生成」を可能にしました。
GANsの学習における問題点
GANsの学習における問題点としては、次の3つがあげられます。
■学習の難しさ・不安定さ
訓練用のデータの分布と生成用のデータの分布の間の距離を測った際に(つまり、最適化の式を計算した際に)、データの分布にかなりの重なりがなければ、ランダムな方向に勾配が計算されてしまうことです。
これが学習を難しくさせている原因で、いくつかの論文でこの手法を改善するために様々な目的関数が提案されていますが(Wasserstein distanceなど)、この論文ではそれらとは別のアプローチでやっています。
■高解像度の画像の生成
高解像度な画像を生成しようとすると、Discriminatorが容易に偽物を判別できてしまうようになることも問題です。そのため、上記の問題も起きやすくなります。また、高解像度の画像を生成しようとすると、minibatchのサイズも小さくする必要があります。これはメモリ的な制約によるものです。
■生成できる画像の多様性の欠如
GANsでは、普通にやると訓練データの一部のデータ表現しか捉えることができず、その関係で生成できる画像表現が小さくなってしまう問題があります。これに対する対処については、以下の論文が参考になります。
■まとめ
これらの問題を解決し、Quality、Stability, Variationの面でそれぞれ改善をしたのが提案されている手法です。今回の手法では、モデルも勿論ですが、それを含めたNetworkの初期化や学習のさせ方みたいなところも含めて工夫ポイントが結構多かったです。
Progressive Growing of GANs
今回提案されている手法は、簡単に言うと「低解像度の画像から徐々に学習させていき、高解像度のものに段階的にしていくもの」です。
Networkの構成と学習の過程
Networkの層が学習の過程でどんどん積みあがっていくのが今回のモデルの特徴です。
この図はいくつかのことを一つの図に入れているので、ちょっとわかりずらくなっていますが、まとめると以下のようなことです。
- 上段のNetworkがGeneratorで、下段のNetworkがDiscriminatorです
- GeneratorとDiscriminatorを交互に学習する従来のGANと違い、この手法では同時に学習していきます
- Generatorは低解像度の画像から徐々に高解像度にしていき、Discriminatorは逆に高解像度な画像から低解像度の画像にしていきます
- 図中の「N×N」というのは、CNNのfilterのサイズではなくて、画像のサイズです(一瞬こんがらがった笑)
- 初期の学習では、4×4のサイズの画像で学習していき、DiscriminatorとGeneratorのそれぞれのネットワークを学習が進むにつれて対象になるように追加していきます(つまり、徐々に解像度を上げていきます)
- 狙いとしては、最初は低解像度な画像で大きな特徴を捉えて、徐々に細かな部分をとらえていくというような感じです
- だいぶ前にあったAutoencoderを層別に学習させて積み上げていくようなイメージが一番近いですが、学習の過程で層を積み上げても、それまで積みあがっていた層は継続して学習できるようになっています
なるほど…って感じですね…(こういうDeep系の論文をとある勉強会で発表すると、某氏が必ず「うまくいったのに理由付けしたんじゃね」って言いますが、これでなぜうまくいくのかは「気持ちだけ」わかったって感じですね…)。
この方法のメリット
今回の手法では、徐々に解像度をあげて学習させていくのですが、これにはいくつかのメリットがあります。
- 低解像度の画像の生成は安定している
- 徐々に解像度をあげていくことで、latent vectorsからのマッピングを発見するというゴールいきなり達成するよりは、簡単なタスクにできる
- 学習時間を削減することができる(最終的に得る解像度にもよるが、従来の方法よりも2-6倍の速さで学習できる)
- これと似たような手法としてHierarchical GANがありますが、決定的に違うのは、Hierarchical GANが複雑な構成をしているのに対して、この手法では一つのGANのNetworkを使ってシンプルに実現しているところ
Autoencoderを層ごとに積み上げていくのに似たメリットですね。
toRGB/fromRGB
GeneratorとDiscriminatorの解像度を2倍または2分の1にするときに、新しいレイヤーをスムーズに鮮明にさせたい気持ちがあり、それに対応する方法も提案されています。以下に、16×16の画像(a)から、32×32の画像(c)にする例を示します。
上の図の解説をまとめると次のようになります。
- 16×16から32×32になる過程についてですが、まず(a)のNetworkから、一番上に層を追加し、(b)にします。そして、(b)のNetworkの学習が終わったら、(c)のNetworkになるという流れで進みます。
- (b)で、0から1の間の $α$ を用いています。これは、学習の過程で線形に増える重みがかけられたresidual blockのような操作をしています。(b)は、一番上の層にのみ適用され、その層の学習が終了するタイミングで、αが1になるようにしているんだと思います(自信ない)。そして、一番上だった層の上に新たな層をいれる時に、(c)になって、新しく一番上になった層でまた(b)をするみたいな感じだと思います(自信ない)。
- 「2×」と「0.5×」はそれぞれ、画像を2倍または0.5倍にする操作のことを指し、それぞれnearest neightborフィルタリングとaverage poolingを使用しています。
- 「toRGB」というのは、特徴ベクトル(ここはchannelのことを指すと思う)を、RGBにする操作で、「fromRGB」というのはその逆を行います。これには両方とも1×1のconvolutionを使います。
以上の部分が、主に「学習の安定さ」と「出力画像の質」に大きく関与する部分の改善です。ここからは主に学習の速度と多様性を出すための工夫についてみていきます。
Increasing variation using minibatch standard deviation
GANsは、訓練データの中に見られるvariationのsubsetしかとらえない傾向があり、これを解決する方法として「minibatch discrimination」があります。
minibatch discrimination
これはまだ実際に論文を全部読んでいないのですが、個々の画像だけでなくミニバッチ全体でも特徴的な統計量を計算し、生成された訓練画像のミニバッチに類似の統計量を表示するよう促すという方法らしいです。
画像単体での性質だけではなく、ミニバッチ全体での統計量を使うことで、生成する画像に幅を持たせることを促す、といったイメージでしょうか。
論文の説明している該当の文章をそのまま訳すと以下のような感じです。
これは、識別器の端にミニバッチ層を追加することによって実装されます。
ミニバッチ内の各サンプルについて個別の統計量のセットが生成され、層の出力に連結されて、Discriminatorが統計を内部的に使用できるようにします。
ここでは雰囲気さえわかっておけば(理解しようとすると、もう元論文を読むしか無いけど時間なかったのでまた今度読む(決意))、今回生成画像に多様性を持たせる方法を、本当に雰囲気だけですが、理解することができます。
本Networkでのminibatch discriminationの改良
今回の提案手法の中で使用されているアプローチでは、このアプローチを大幅に単純化しながら、生成画像のバリエーションを改善しており、学習可能なパラメータも新しいハイパーパラメータも持ちません。
やっていることは非常にシンプルで、以下のとおりです。
- 今、channel数K、高さH、幅Wのテンソルがあり、それが1つのミニバッチにおけるサンプル数分だけあったとします。
- この時、まず最初にミニバッチ上の各空間(pixel)における各channelの標準偏差を計算し、出力として1つのテンソルを返します。
- 次に、すべてのchannelと空間(pixel)でその値を平均して、スカラを出力します。
- この値をすべての空間的位置に用いて、一定の数のchannelを持つテンソルとして出力します(今回はchannelサイズ1のモノを作成)。
- 最終的に得たテンソルをミニバッチに連結し、追加の(一定の)channelを生成します。
これを図にすると以下のような感じになります。
この作った層はネットワークのどこにでも挿入することができますが、最後に挿入するのが最適だそうです(色々試したそうです。詳細はAppendixにあります)。
イメージだけですが、こうするとミニバッチ内のばらつきを表現することが出来るんでしょうか…それにしても一つの統計量でそれができるとは…。
Normalization in generator and discriminator
GANsでは、その学習の不安定さから、Batch NormalizationをGeneratorやDiscriminatorにこれまではいれ、これにより安定させようとしていました。共変量シフトを取り除くことを目的として、このBatch Normalizationは議論されることが多いと思います。
この辺りについては、以下の記事が参考になります。
しかし、この論文の著者らは、「そんなもん観測されなかった」として、GANで必要なのは、「信号の大きさ」と「競争」を制限することが大事と主張し、2つの異なるアプローチを提案しています(実際に、Batch Normalizationは入ってない)。以下ではその2つについて説明します。
Equalized learning rate
この提案手法においては、小難しい(慎重な)重みの初期化はせずに、 初期値として$N(0, 1)$ を使用し、学習時にscaleするようにしています。
Heの論文で紹介されているinitializationに従って $c$ を設定し、以下のように重みを動的に設定しているらしいです(この紹介されている論文の該当部分はまだ読んでないのでわからない)。
$$
\hat{w_i} = \frac{w_i}{c}
$$
こうすることで、スケール不変性が得られるので、Adamのような勾配計算方法を使った際により効果が得られます。
どういうことかというと、Adamは学習率を考える時に、パラメーターの勾配の標準偏差は考慮しますが、パラメーターの大きさとは独立に行われるので、dynamic rangeが大きいパラメーターは、更新に時間がかかります(詳しくは以下の資料を)。
www.slideshare.net
上のように重みを設定することで、学習率が大きいものも、小さいものも同時に扱うことができ、結果として学習が早くなります。
これが、パラメーターを上記のように設定することのメリットです。
Pixelwise feature vector normalization in generator
競い合わせていく過程として、GeneratorとDiscriminatorの大きさが制御不能になることを禁止するために、Generatorの中の各畳み込み層の後の各ピクセルのchannelベクトルを、単位長に正規化することをしています。
これは、2012年のImageNetに出てきたCNNを使ったNetworkで用いられたものに似ている、以下の式で実現しています。
$$
b_{x, y} = \frac{a_{x, y}}{ \sqrt{ \frac{1}{N} \sum^{N-1}_{j=0} (a_{x, y}^{j} )^2 + \epsilon} }, where \epsilon = 10^{-8}
$$
ここで、 $N$ はchannelの数で、 $a_{x,y}$ と $b_{x, y}$ はそれぞれオリジナルと正規化後の空間 $(x, y)$ におけるchannelの値を示しています。簡単に実現できる上に、これがかなり効いているらしく、学習の不安定さも解消されたとのことです。
Multi-scale statistical similarity for assessing GAN results
時間できたら書きます(逃げたんじゃない…!!!!)。
Experiments
今回はCELEBA、LSUN、CIFAR10のデータセットを使って、 inception scoreを使い評価したそうです。
inception score
これは、GANが生成した画像の評価値として使われることがあるscoreです。以下の記事がわかりやすいです。
各データセットでの実験結果について
いろんなデータせっとで試していますが、まぁ圧倒的ということで(書くのめんどいわけではないというか、時間できたら書きます)。
顔の生成以外だと、よく見るとおよ?みたいな部分もありますが、それでも凄いですね…(ちなみに、検証用のために大きな画像のGELEBAのデータを作ったそうです笑)
Appendix
今回の論文では、Appendixに結構重要なことがサラッと書いてあったり、論文中で「ん?なんだこれは?」ってなったところが、ここで理解できたので、そこ含め以下で追います。
ネットワークの詳細
ネットワークのより詳細は、Appendixに上がっている以下のようなものになります。詳細はappendixに譲りますが(めんどくさいわけではない)、簡単にまとめると以下のような感じです。
- Generatorの最後とDiscriminatorの最初にそれぞれtoRGBとfromRGBを使用。
- 全てのレイヤーにたいして、Leaky ReLUを使用。
- 512次元のlatent vectorは、[-1, 1]の間に収めたそう。
- minibatch discriminationがちゃんとDiscriminatorに入っていることに注目。
- batch normalizationやlayer normalization、weight normalizationは含めなかった。
他にもありますが、時間できたら追記します(決意)。
まとめ
論文の概要をまとめます。
このネットワークの利点
ネットワークの利点は、以下の通り。
- 低解像度の生成は、クラス情報が少なく、モードも少ないため、安定している。
- 解像度を徐々に上げていく方法は、一度にlatent vectorsを1024×1024の画像にマッピングするよりも簡単。
- 学習時間を減らすことができる。
- 多様性も担保
- 当然だけど、綺麗な画像を生成することができる。
感想
ちょっとこれまでのGANの研究をある程度さらっていないと完全な理解はキツイっすね(笑)。ちょいちょい周辺の論文とか読みながら、実際に試してみようかなと思います。
あんまり深く追えてない部分が多いので、何か間違えていたら、指摘して頂けるとうれしいです。
それでは。