SageMakerで画像を生成する(DCGANs):Amazon SageMaker Advent Calendar 2018

GAN系は汎用性高くて面白い。
2018.12.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

こんにちは、データインテグレーション部のyoshimです。
この記事は「クラスメソッド Amazon SageMaker Advent Calendar」の16日目の記事となります。

今日は、SageMakerで「サンプル画像群と似たような性質の画像を生成する」ことが出来る「DCGANs(Deep Convolutional Generative Adversarial Networks)」というアルゴリズムを使って、セレブ画像を生成してみようと思います。
今回のコードはSageMaker側で用意されているスクリプトを使います。
「SageMaker Examples」の「Aditional Examples」をクリックして

「dcgan_faces_tutorial.ipynb」、こいつを使います。

目次

1.やること

セレブ画像をINPUTとしてネットワークを学習し、「セレブっぽい画像」を生成するモデルを学習してみます。
つまり、下記のような画像を大量に投入することで、「なんとなくセレブっぽい」画像を生成するネットワークを学習させる、というものです。

また、セレブではなく犬の画像でも同様のことをやってみようと思います。

2.DCGANsについて

「DCGANs(Deep Convolutional Generative Adversarial Networks)」は2016年に発表された「GAN」と「CNN」を組み合わせたアルゴリズムです。

主要な登場人物と役割について、概要だけ説明します。
もしアルゴリズムの詳細について調べたい方は、既に解説ブログが多々存在しているのでそちらをご参照ください。
論文
GANについて概念から実装まで ~DCGANによるキルミーベイベー生成~
できるだけ丁寧にGANとDCGANを理解する
また、GANをトレーニングする際のTipsも参考になります。

●latent space(noise)

潜在的な特徴を保持した変数空間。このデータを元にGeneratorは画像を生成します。
今回のチュートリアルでは平均が0、分散が1の正規分布を利用しています。
この変数の扱い方いかんによっては、「ある程度狙った画像」を生成できるようになります。
例えば、「笑顔の女性」、「真顔の女性」、「真顔の男性」の画像を生成する「latent space(noise)」から新しく計算した「latent space(noise)」を使って、「笑顔の男性」の画像を生成できます。
引用:arxivのFigure7

ただし、今回のチュートリアルではそこまでは触れません。

●Generator

「latent space(noise)」で作成されたデータから目的とするデータ(今回は画像)を生成します。
「Discriminator」を騙せるように学習するため、段々と「本物の画像」に似た画像を生成するように学習します。
論文中で提案されている構成図は下記の通りです。

引用:arxiv

あくまでも「学習に利用した画像」と似たような画像しか生成できない、という点にはご注意ください。

●Discriminator

「Generatorが生成した画像」か「本物の画像」かを判別します。
段々と「本物の画像かGeneratorが生成した画像か」を上手く判断できるように学習します。

3.セレブ画像を生成

基本的には対象のノートブックファイルを実行していくだけですが、私が実行した際の注意点を4点ほど書いておきます。

  • インスタンスは「p3.8xlarge」で実行しました(GPU4つで並列実行させたかったので)
  • 「kernel」は「conda_pytorch_p36」で実行しています。
  • 対象ノートブックファイルがあるディレクトリと同じ階層に「data/celeba」フォルダを作成します(「dataroot」変数で指定しているパス。変更可能。)
  • こちらからデータをダウンロードして、「dataroot」に指定しているパスに格納し、解凍する。
    このファイルです

あとはぽちぽち上から実行していくだけで実行できるかと思います。
私が実行した際は、5エポックで20分くらいかかりました。(利用した画像ファイル数は「202,600」個)

また、学習の過程を眺めるのも面白いです。例えば、学習中に評価指標として出力されている「D(G(z))」*は「Generatorが生成した画像」をINPUTとした際の、「Discriminator」の出力の平均(画像が本物なら1、Generatorが生成した画像なら0を出力する)ですが、これがなかなか上がらずにヤキモキするのが最高です。

*D(G(z)):最初は0くらいから始まる(Discriminatorを全く騙せていない)が、最終的には0.5に近づく(Discriminatorが全く判断が付かず、1/2の確率でしか当たらない状態)のが理想です

学習も完了したので、早速Generatorが作成した画像を見てみましょう。
結構それっぽい画像ができているように見えます。

本物の画像と比較してみました。流石に本物の画像と比較するとまだ粗が見えます。

下記はGeneratorの学習過程を可視化しています。
だんだんと「セレブっぽい画像」を出力できるようになってます。

もう少しチューニングしてみたかったのですが、GPUインスタンスはお値段が高いので今回はここまでとしておきます...。

4.犬画像を生成

では、続いて犬画像を与えて画像生成を試してみます。
画像はkaggleで昔実施された「Dogs vs. Cats」コンペから取得しました(画像ファイルは合計12,500枚)。
今回は単純に参照するデータを変更してエポック数を100に変更しただけなので、結果だけお見せしておきます。

評価指標を確認してもDiscriminatorを騙せていないことが明確だったので、微妙な画像ばかりとなってしまいました。
もう少しチューニングしていきたかったのですが、p3.8xlargeインスタンスがお高いので今日は一旦ここまでにしようと思います...。

5.まとめ

「DCGANs」というアルゴリズムを使って画像生成をしてみました。

もし「ある程度綺麗な画像を生成したい」、となった場合は「latent space(noise)」、「Generator」、「Discriminator」等々の修正やパラメータチューニングが必要になり大変ですが、とりあえず一回触ってみるくらいだったら簡単にできます。
もしよかったら皆さんもお気に入りの画像を使って年末年始に試してみてください。

また、今回は「画像生成」でしたが、他にもGANを使ったもので「画像の変換」、「画像の異常検知」等面白そうなアルゴリズムはいっぱいあるので、興味のある方は是非こちらも挑戦してみてください。