Network)を解説していきます。Goodfellowが考案したモデルです。2016でもGANのチュートリアルが行われるなど非常に注目を集めている分野で、次々に論文が出てきています。LeCunが、この10年の機械学習で最も面白いアイディアと述べていたりもします。LeCunGANは聞いたことはあるけれどあまり追えてないという人向けに基礎から解説していきたいと思います。それでは順に見ていきましょう。論文紹介まとめ基礎理論この章ではGANの基本を解説していきます。生成モデル訓練データを学習し、それらのデータと似たような新しいデータを生成するモデルのことを生成モデルと呼びます。別の言い方をすると、訓練データの分布と生成データの分布が一致するように学習していくようなモデルです。GANはこの生成モデルの一種です。通常、モデルが持つパラメータ数に対して訓練データの量が圧倒的に大きいため、モデルは重要な特徴を捉えることを求められます。Autoencoder)など他にも注目されているモデルがあり、それぞれ長所・短所があります。GANは学習が不安定ですが、他の手法に比べてくっきりとした画像が生成される傾向があります。今回はこのGANに焦点を当てて解説していきます。VAEなどはまた別の機会に紹介できればと思います。GANの仕組みGANではgeneratorとdiscriminatorという2つのネットワークが登場します。Generatorは訓練データと同じようなデータを生成しようとします。discriminatorはデータが訓練データから来たものか、それとも生成モデルから来たものかを識別します。この関係は紙幣の偽造者と警察の関係によく例えられます。偽造者は本物の紙幣とできるだけ似ている偽造紙幣を造ります。警察は本物の紙幣と偽造紙幣を見分けようとします。次第に警察の能力が上がり、本物の紙幣と偽造紙幣をうまく見分けられるようになったとします。すると偽造者は偽造紙幣を使えなくなってしまうため、更に本物に近い偽造紙幣を造るようになります。警察は本物と偽造紙幣を見分けられるようにさらに改善し...という風に繰り返していくと、最終的には偽造者は本物と区別が付かない偽造紙幣を製造できるようになるでしょう。GANではこれと同じ仕組みで、generatorとdiscriminatorの学習が進んでいきます。最終的には、generatorは訓練データと同じようなデータを生成できるようになることが期待されます。このような状態では、訓練データと生成データを見分けることができなくなるため、discriminatorの正答率は50%になります。(2014)によって最初に提案されました。この研究ではgeneratorもdiscriminatorもどちらも基本的には多層パーセプトロンで、ドロップアウトを使って学習させています(一部CNNをつかっているものもあります)。大まかにGANの仕組みが分かったので、次に数式を使って見てみましょう。\(G\)はgenerator、\(D\)はdiscriminator、\(\boldsymbol{x}\)は訓練データ、\(\boldsymbol{z}\)はノイズを表します。\(G\)はノイズ\(\boldsymbol{z}\)を入力としてデータを生成します。\(D(\boldsymbol{x})\)は、そのデータが訓練データである確率を表します。確率なのでスカラーです。\(D\)は訓練データと生成データに対して正しくラベル付けを行う確率を最大化しようとします。\)を最小化しようとします。これらをまとめて以下のように表現します。\)が大きくなります。\)は大きくなります。\)は小さくなるという構造になっています。学習時は、以下のようにdiscriminatorとgeneratorを交互に更新していきます。(2014)の実験結果を見てみましょう。黄色い枠で囲まれている画像は訓練データで、それ以外は生成された画像です。訓練データによく似た画像を生成できている様子が分かります。GAN)というモデルを紹介していきます。network)を使ったモデルになっています。CNNは画像関連を中心に大きな成功を収めているモデルであり、画像を生成するのであればやはりGANでもCNNを使うのがよいと考えられます。CNNを使ったGANで最初に高解像度画像の生成に成功したのはLAPGANだと思いますが、何段にも分けて画像を生成する必要がありました(この記事の後半でも紹介します)。DCGANでは一発で高解像度画像を生成することに成功しています。GANは学習が難しいことで知られていますが、この論文では学習をうまく進めるための様々なテクニックが紹介されています。2015年の論文ですが、未だに役に立つテクニックなので、ここでもそれらを紹介していきます。(2015)より引用プーリングをやめるCNNでは最大プーリングを使ってダウンサンプリングするのが一般的ですが、discriminatorではこれをストライド2の畳み込みに置き換えます。convolutionを使ってアップサンプリングします。(余談:これはdeconvolutionと呼ばれることもありますが、deconvolutionというのは既に他の手法に割り当てられた名前であるため厳密には間違いです。convolutionという名前なども使われます。間違いと分かっていても言いやすいのでdeconvolutionと呼んでいる人も多い気がします。poolingに置き換えます。(2013)で提案された手法です。poolingでは、全結合層の代わりに一つの特徴マップに一つのクラスを対応させるという方法で分類を行います。特徴マップごとの平均を取り、そのベクトルをソフトマックス分類器にかけます。下図を見ると分かりやすいかと思います。poolingではパラメータがなくなるため、過学習を防ぐ効果があります。poolingを使うと安定性は増すものの、収束が遅くなってしまうようです。normalizationがよく使われます。各層でのデータ分布を正規化してやることにより、学習を速くしたり、パラメータの初期化をそれほど気にしなくて済むようになります。過学習を防ぐ効果もあります。normalizationをgeneratorとdiscriminatorの両方に適用します。全ての層に適用すると不安定になってしまうようで、generatorの出力層と、discriminatorの入力層には適用しないようにします。ReLUを使うGeneratorでは活性化関数に出力層だけTanhを使いますが、それ以外の層では全てReLUを使います。ReLUについてはあまり馴染みがない人もいるかもしれないので、簡単に説明しておきたいと思います。下図のような関数形になっています。\)という値が使われています。\)も含めて学習してしまおうというのがPReLUです。\)の領域では勾配が0になってしまうため、誤差逆伝播がそこでストップし、それ以上そのニューロンの学習は進まなくなってしまいます。ReLUは勾配がゼロにならず、この問題を回避することができます。ReLUの方が良いのではないかと思うかもしれませんが、そう単純でもありません。実験結果ベッドルームの画像のデータセットを使って学習した結果です。本物と見間違ってしまいそうなレベルの画像を生成できていることが分かります。(2015)より引用もう一つ面白い結果を紹介します。Word2Vecという単語ベクトルで「王様」-「男」+「女」=「女王」という演算ができることは有名ですが、GANにおける入力である\(z\)ベクトルを使っても同様の演算を行うことができます。下の例では、「サングラスをかけた男」-「男」+「女」=「サングラスをかけた女」という演算を行っています。(2015)より引用その他のテクニックここまでDCGANについて解説してきましたが、GANの学習をうまく進めるためのテクニックは他にもたくさんあります。GAN?というページに様々なテクニックがまとまっています。GANsも参考になります。実装それでは実装してみましょう。GANを使った面白い例はたくさんあるのですが、ここではGANの理解を深めることが目的なので、シンプルなデータセットであるMNISTを使用します。KerasでもDCGANの実装はいくつか公開されています。ここではこちらのコードをベースにして実装していきます。normalizationが入っていなかったりと、DCGANの論文とは異なる設定が多いため、なるべく論文に近い形に変更しながら実装していきます。generatorを作成します。model入力として100次元のベクトルがあり、これが全結合層を経て、畳み込み層に7x7の画像として与えられます。そこから2回upsamplingが行われることによって、MNISTと同じサイズの28x28の画像が出力されます。DCGAN論文の通りに、活性化関数は基本的にReLUで、出力層だけTanhです。normalizationも入れています。次にdiscriminatorを作成します。ReLUにしています。2)としてストライド2の畳み込みを行うことによってダウンサンプリングしています。architectures.”とあります。poolingを使った方が良いようですが、このdiscriminatorは浅いのでそのまま全結合層にしておきます。normalizationが入っていません。生成画像と本物の画像を同じバッチに入れているのがよくなさそうなので分けてみるなど、色々と試してみたのですがこちらの記事にもあるようにどうもうまくいきませんでした。(一応動くことには動くのですが、クオリティが落ちてしまいました。normalizationを入れるとdiscriminatorが強くなりすぎてうまくいかない場合があるとのことなので、そういうことなのかもしれません。normalizationが入っていないものがほとんどです。ここではこれ以上は深堀らないでおくことにします。生成画像を並べて表示するための関数も用意しておきます。combined_image最後に学習部分です。discriminator.save_weights('discriminator.h5')DCGAN論文では、Adamオプティマイザの学習係数は0.0002、\(\beta_1\)は0.5となっていますが、これだとうまく進みませんでした。discriminatorの学習だけ早く進んでしまうようです。結局こちらの記事を参考に、上記の値を採用しました。Discriminatorの重みを更新し、次にdiscriminatorの重みを固定した状態でgeneratorの重みを更新するという流れを繰り返しています。Falseとしているため、discriminatorの重みが更新されなくなってしまうのではないかと思うかもしれませんが、大丈夫です。trainableプロパティの変更を反映するためにはcompile()を呼ぶ必要があり、重みが固定されるのはdcganの中のdiscriminatorの部分だけになります。詳しくは公式ドキュメントなどを参考にしてみてください。[1]*BATCH_SIZE)の所が少し分かりにくいかもしれません。生成画像をラベルが1の本物の画像として扱うことにより、discriminatorを騙そうとしています。\)を最小化するように学習していることになります。学習初期においてgeneratorから生成された画像はかなり質が低いため、簡単にdiscriminatorに見破られてしまいます。パラメーターを変えてもどれも見破られてしまうため、どのような変更を加えたらdiscriminatorをだませるような画像を生成できるのか分かりにくい状態にあります。言い換えると、学習初期には勾配が小さくなりがちです。\)を使うことによって、より大きな勾配を得られるようにしています。結果はこのようになり、手書きっぽい数字を出力することができました。長く計算すると、もう少しクオリティが上がるはずです。ハイパーパラメータを色々と変えて実験していたのですが、長時間計算していると出力が全部1になってしまうことがよくありました。色んな数字を出力せずとも、単純に全部1にしてdiscriminatorを騙せてしまうということなのかもしれません。このようなモードの崩壊はよく知られている問題で、対処法も提案されてきています。論文紹介この章ではGANに関連する論文を幾つか紹介していきます。あるので全部紹介することはできませんが、論文を読み進めていく上での参考になればと思います。この記事をアップデートする形で、他の論文も紹介していく予定です。GAN関連の論文はAdversarialNetsPapersというリポジトリにまとまっています。GoodfellowによるGANのチュートリアルも公開されていて、こちらもおすすめです。Networks)はCNNを使ったモデルで、下図のように段階的により高解像度な画像を生成していくのが特徴です。GANは学習が不安定という問題がありました。高解像度の画像を生成するのは難しいかもしれません。低解像度の画像を生成することは簡単でしょう。その低解像度画像を使って、もう少しだけ解像度の高い画像を生成することもそれほど難しくはないだろう、というのがLAPGANの主なアイディアです。これを繰り返していくことによって、最終的に解像度の高い画像を生成します。図の流れに従ってもう少し詳細を見ていきましょう。\(G_3\)が\(\tilde{I}_3\)を生成します。これをupsampleし、\(l_2\)を生成します。これとノイズ\(z_2\)を\(G_2\)に与えることにより、画像の差分である\(\tilde{h}_2\)を生成します。\(l_2\)と\(\tilde{h}_2\)を足し合わせることより\(\tilde{I}_2\)が出来上がります。この流れを繰り返していくことにより、最終的な出力画像を得ます。図では3段階になっていますが、これはあくまでも一例で、最終的に得たい画像の解像度などによって段数が違ってきます。結果を見ると本物っぽい画像が生成されている様子が分かります。LAPGANのことで、「飛行機」や「犬」などクラスを指定して生成できるようにしたバージョンのLAPGANです。(2015)より引用また、右図のようなUIで本物に見えるか偽物に見えるか人間に評価してもらうというテストも行っています。グラフを見ると、オリジナルのGANでは10%以下の割合でしか本物に見えないようですが、LAPGANでは約40%となっています。ちなみに本物の画像では90%程度の値となっています。(2016)これはGANを超解像(super-resolution)に応用した研究です。Technologyという会社が行っていた研究で、$150MでTwitterに買収されています。その後にこの論文が出ています。超解像というのは、低解像度画像から高解像度画像を生成する技術のことです。低解像度画像を入力とし、高解像度画像を出力するようにニューラルネットワークを訓練します。教師あり学習は、データセットを用意することが困難であることがよくあります。既存の手法で高解像度画像から低解像度画像を生成する事は容易であるため、超解像では簡単にデータセットを用意することができるという特徴があります。単純には、autoencoder型のCNNを用意し、損失関数をピクセルレベルでのMSE(平均二乗誤差)にして学習させれば良いと考えられます。この方法である程度はうまく行くのですが、どうしてもぼやけた画像になりがちです。低解像度画像から高解像度を生成する時に答えは一つではありません。図中の赤枠の画像のように、自然に見えるパターンというのは何パターンも考えられるわけです。MSEベースで考えると、どのパターンと比較して損失を計算することになったとしても、それなりに損失が小さくなるように平均的なぼやけた画像が生成されてしまいます。この問題を解決するためにGANを使うことを考えます。GANではdiscriminatorを騙すことさえできればどんなパターンでも良いため、平均的な画像ではなく、本物っぽいシャープな画像が生成されることが期待されます。上記の議論を踏まえ、下記のような損失関数を採用します。GANに関する損失です。ピクセルレベルでの比較ではなく、VGGのある層における特徴マップで比較します。こちらの方が、ピクセルレベルで比較するよりもシャープな画像が得られることが分かっています。VGGを損失関数として使う手法は他の研究でも使われていて、前回のブログでも少し触れています。モデルは下図のようにResNetとなっています。低解像度画像を縦横4倍ずつの高解像度にしています。SRResNetというのは、GANを使わずにMSEのみで学習させた比較用のモデルです。SRGANでは非常にはっきりとした画像を生成できている様子が分かります。頭や首周りの細かい構造を見ると、SRResNetではぼやけてしまっているのに対し、SRGANでははっきりしていることが分かります。していますが、オリジナルの画像と比較すると必ずしもそれが本物ではないことも分かります。Discriminatorをだますためには、「本物っぽく」ありさえすれば良いからです。(2016)これまでは似たような問題設定でも個別のモデルで個別の研究として扱われてきました。この研究では下図のように似たようなタスクは一つのモデルでやってしまおうという研究です。衛星写真をマップにしたり、白黒画像をカラー化したり、昼の写真を夜にしたりと、モデルで様々なタスクをこなすことができています。GANになっていて、入力画像はGとDの両方に与えられます。通常Gはノイズをサンプルしますが、このモデルでは直接ノイズをサンプルするのではなく、複数の層に渡ってドロップアウトという形でノイズを入れるようにしています。ドロップアウトは普通は学習時だけに入れるものですが、このモデルではテスト時にも入れるようになっています。connnectionがあるモデルが採用されています。することで、エッジのような浅い層で獲得された特徴も直接利用できるようになり、よりクオリティの高い画像が得られるようになります。一つのモデルでこれだけ面白い様々な変換ができてしまうのはすごいですね。ソースコードも公開されているので自分で実験してみるのも楽しいかもしれません。(2016)これはGANを二段階にすることにより、クオリティの高い画像を生成することに成功した研究です。結果の図を見ると分かりやすいです。テキストに合わせた画像を生成するというタスクになっています。画像はStage-IとStage-IIの二段階に分けて生成します。Stage-Iでは、色やレイアウトなど大まかな部分を描き、低解像度画像を出力します。Stage-IIでは、その低解像度画像とテキストを元に詳細部分を描き、クオリティの高い高解像度画像を生成します。(2016)より引用モデルの詳細はこのようになっています。GANになっています。embedding)が入力として与えられます。embeddingからガウス分布を作り、そこからサンプルするという手法を用いています。Stage-IIのgeneratorには、Stage-Iで生成された画像とテキストが入力として与えられます。Discriminatorの方はStage-IもStage-IIもほとんど構造で同じで、画像とテキストが与えられます。結果をもう少し見てみましょう。(2016)より引用Stage-Iで大まかに描いて、Stage-IIで詳細を描けていることが分かります。細かく見てみると、Stage-Iでの失敗をStage-IIで修正できる場合もあることも分かります。右から3列目を見ると本当は赤茶色にしなければならなかった部分がStage-Iでは青くなってしまっていますが、Stage-IIうまく修正してくれている様子が分かります。一つ結果を紹介します。「真っ赤な鳥」から「真っ黄色な鳥」に向かって徐々に変化させていくというような実験です。スムーズに画像が変化していっている様子が分かります。StackGANは余りにもキレイな画像を生成できているので、単純に訓練データの画像をコピーして近い画像を表示しているのではないかと疑う人もいるかもしれませんが、上図はちゃんと生成していることを示す例の一つです。それにしてもこんなにキレイな画像を生成できてしまうのは凄いですね。(2016)秘密主義を貫いてきたAppleですが、最近Appleの研究者も論文を投稿できるようになりました。これがその最初の論文です。教師あり学習では、ラベル付きのデータを手に入れるのにコストがかかるという問題があります。image)を使うという方法があります。ラベルも既に分かっているため、こちらのやり方の方が圧倒的に効率がよい場合があります。有名な例としてはMicrosoftのKinectがあります(参考)。このやり方にも問題があります。imageを使って学習しても、実際に本物画像に対して使った時にうまく動かない場合があります。imageをより本物っぽくしてしまおうというのがこの研究です。下図が分かりやすいです。imageが入力となります。lossという損失も考慮します。imageとgeneratorによって生成された画像の差分を小さくするためのものです。これが必要かというと、例えば目の画像の場合、本物っぽく見えさえすれば何でもいいわけではなく、視線方向などを保ちたいからです。クオリティの高い画像を生成するために幾つかの工夫が施されています。discriminatorに画像を与える時に、新しくできた生成画像だけでなく、過去の生成画像の一部も混ぜてやります。Replayっぽい感じで面白いです。まとめそもそもGANとはどういうモデルかという所から始まり、学習をうまく進めるためのテクニックの紹介や実装を行いました。幾つか論文も紹介しましたが、面白い論文がまだまだたくさんあるので今後も紹介していければと思います。businesses.株式会社Elixはディープラーニングに特化したテクノロジーカンパニーです。最新の研究成果をいち早く産業に応用し、ビジネスの発展に貢献します。お気軽にご相談ください。