functionDiscriminatorの目的関数(数式のLはLossではなく、Likelihoodだと思われる)を数式で書くと下のようになる*1この式を解読すると下のように考えられる。Discriminatorの目的関数は正解画像を入れたときと偽物画像を入れたときの2項から構成されるD(・)はDiscriminatorの出力で0〜1を返す。1に近いほど本物と判定されたことを意味するG(z)はGeneratorが乱数zから生成した偽物画像を表す本物画像xをDに入力したとき(1項目)はD(x)が1(本物)に近いほどlogの値が大きくなる(=Dは本物画像を本物と正しく判定できた)偽物画像G(z)をDに入力したとき(2項目)はD(G(z))が0(偽物)に近いほどlogの値が大きくなる(=Dは偽物画像を偽物と正しく判定できた)次はGeneratorの目的関数。この式を解読すると下のように考えられる。偽物画像G(z)をDに入力したときにD(G(z))が1(本物)に近いほどlogの値が大きくなる(=Gが生成した偽物画像をDに本物画像と誤って判定させることができた)上の式をコードに落とすと下のようになる。GitHubちなみに参考元のコードはほとんどの実装でdetach()が入ってない。公式のは入ってるので入れておいた画像を生成する関数。学習途中のエポックでGeneratorを使ってサンプル画像を生成するのに使う。f)実験結果まずは、DiscriminatorとGeneratorのlossをプロットしてみる。label='G_loss')plt.xlabel('epoch')plt.ylabel('loss')plt.legend()plt.grid()学習が進むとDiscriminatorが強くなってGeneratorが競り負けていることがわかるGANの発明者のGoodfellowも言及しているが、Generatorは贋作者(counterfeiter)でDiscriminatorは警察(police)に例えられるつまり、Generatorを応援することは犯罪者を応援することにつながる(笑)この例えあまりよくないよね〜Generatorもっと頑張れ!途中のエポック(1、10、25エポック)で生成した画像を描画してみよう。ImageImage('logs/epoch_001.png')Image('logs/epoch_010.png')Image('logs/epoch_025.png')学習が進むにつれてDiscriminatorに見破られないような精巧な偽物画像をGeneratorが生成できるようになったことがわかる。追記(2018/3/9)コメントでご指摘いただいたようにGeneratorの更新の前にノイズを新しく生成しなおす必要があります。元の論文でもDiscriminatorの更新とGeneratorの更新では別のノイズを使っていました。G_loss.data[0]Notebookも更新済みです。こちらでも実験してみたのですが、大きく結果が変わるということはないようでした。(horse2zebra)今回はCycleGANの実験をした。(CelebA)今回はDCGANをCelebAのデータで試してみた。AutoencoderAutoencoderの実験!MNISTで試してみよう。»プロフィールid:aidiary人工知能とその関連分野に興味があります。)はてなブログをはじめよう!aidiaryさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。