GANこの前はCNNを書いてみました。tsunotsuno.hatenablog.com今回はちょっぴりCNNの応用のGANってやつをやってみます。今回参考にさせていただいたのはこちら。elix-tech.github.ioめちゃくちゃ分かりやすかったです。ありがとうございます。いういろんな人に参考にされるブログが書けると良いなあ、なんて思った次第です。Networks代表的なGANのモデルであるDCGANの論文です。パラメータとかの具体的な値について参考にしました。Network)全体感まず、GANとはなんぞやというところを、いつも通りふわっと勉強してみました。GANはざっくりと言うと、2つのCNNを競争させながら学習する機械学習モデルです。イメージとしてはこんな感じです。GeneratorとDiscreminatorがいて、Generatorが精製した嘘のデータをDiscriminatorは本物かどうか見抜き続け、お互いに学習し合います。イメージは"ホコタテ"で、最終的に最強になるかどうかは置いておいて、いい感じの矛と盾が同時に出来上がります。ここらへんで私としては”???”ってなりました。困ったのはこちらの2箇所。教師無し学習なんてやったことない。ことで、こちらの2つについて細かく見てみました。Generatorどないすんねん、、、Discriminatorは前回までのCNNでいけそうな気がしたんですが、Generatorは全くイメージつきませんでした。そもそも、何を材料にして確率分布を生成すんねん、、、ってなって、上のサイトを参考にさせて頂きました。イメージはこんな感じになっているみたいです。入力はスカラ値のノイズで、そこから確率分布を生成するそうです。実際には、このネットワークが逆向きの畳み込みネットワークになっていたり、Pooling層がなかったりするんですが、まずはざっくりとした概要です。初めは適当な画像ができるんですが、だんだんやってくうちにDiscriminatorを騙し切れるように学習していきます。そんでもって、次に考えたのは畳み込みでどうやって行列のサイズを大きくしていくの?ってことです。一般的に畳み込みは入力データに対して一回り小さなデータが生成されます。下にある青いセルが入力データで、そこに対して畳み込み演算をすると出力は入力より一回り小さな緑のデータが生成されることがわかります。データが小さくすることを防ぐには、入力データの外側にパディングでデータを詰めていく調整をすることが一般的です。出力データを入力データより大きくするためには、かなりの量のパディングをすることになります。それって結局強烈なバイアスをかけていることに近いので、画像生成にはならないと思います。こんな感じで"???"ってなったので調べてみると、やっぱりやり方がありました。qiita.com下の青いセルが入力のデータで、そのデータを間引いて拡大します。拡大後のデータに対してコンボリューションすることで、出力のサイズを入力のサイズより大きくすることができます。こんな感じで入力データを拡大して、そこに畳み込み演算をしていくんですね。教師無し学習なんてやったことない。次にコケたのが、「教師なし学習」のモデル設計です。前回までやっていたCNNでは教師あり学習をやっていました。画像に対してなんの画像なのかのラベルをくっつけることで、「入力された画像がなんの数字なのか」を判定していました。上の記事を参考に見て見たところ、考え方が違うんですね。Discriminatorは「入力された画像が教師データなのか生成データなのか」を判定するんですね。イメージはこんな感じです。Discriminatorに入力された画像が生成されたものか教師データかは予めわかっているので、事実上の教師あり学習に変わります。判定結果を正解と比較することでlossを計算し、Discriminatorは学習します。概念的なレベルの疑問が解消されたところで、ちょっとずつ実装に入っていきたいと思います。今回は全体構成としてこんな感じで全体を構成します。そんでもってコードとしてはこんな感じにしてみました。試行錯誤してみた残骸(コード)はこちら。https://github.com/nogawanogawa/simpleGAN.gitGeneratorGeneratorのネットワークの構成としてはこんな感じになります。登場する層としては、DeconvolutionとReLUだけとなります。GeneratorのDeconvolutionをして画像を生成するので、そこだけ異なってきます。Deconvolution基本的にはConvolutionと同じ処理になりますが、入力に対して前処理を行って入力のサイズを拡大してからConvolutionを実行するみたいです。前回までのConvolutionの層の前に入力のPadding処理を入れてから実行しています。Tensorflowとかのライブラリを見る感じ、出力のサイズによってPaddingや間引きのサイズにルールがあるみたいですが、今回は簡略化してやってみます。dx_LeakyReLULeakyReLUはこんな関数になっています。x<0の領域で0一定ではなく負の値をもつReLU関数のイメージです。パラメータとかはめんどくさいので、論文を参考にしました。outDiscriminatorDiscriminatorは以前のCNNを流用、改良したので省略します。結果まず、教師データはこちらです。次にGANによって生成された画像がこちら。対角線方向に分布が形成されていることはわかります。ちなみに1800イテレーション終了時の画像がこちらで、これ以上学習させると今度は過学習なのか画像が真っ黒になります。鮮明な画像が出ないのは単純にGeneratorが簡易版で実装しているためですね。デコンボリューション時のバイアスの影響をもろに受けているので、格子状の模様が見えていますし。世の中に出回っているレベルの鮮明な画像生成ができるようになるにはまだまだ時間がかかりそうです。今回は理屈がどんなもんで、ちゃんと動いてそれっぽい画像が出てきたのでOKとします。あと、二度と(半)フルスクラッチでGANは書きたくないです。専用のライブラリを使っていかないと、理屈から勉強してたら時間がいくらあっても足りませんね。次はTensorFlowで実装したもので色々遊ぼうかと思います。(1)月別アーカイブはてなブログをはじめよう!nogawanogawaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。