Re:ゼロから始めるML生活

どちらかといえばエミリア派です

【実装:StackGAN】StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks

だいぶ前にStackGANの実装をサボっていました。

tsunotsuno.hatenablog.com

理論云々は上の記事を見てもらうとして、実装にフォーカスします。

ネットワークの概念図

StackGAN
ネットワークの概念図

実装サンプル

最近はDefine by runの実行モデルを頭に叩き込むためにpytorchを使うようにしているので今回はPytorchを使います。

Condition Augmentation

ここで結構ハマりました。下記のデータセットを使うと書いてあるんですが、これの使い方がなかなかわかりませんでした。

  • Caltech-UCSD Bird(CUB)
  • Oxford-102 flower

どこかからか持ってきたREADMEを見てみるとこんな感じで書いてあります。

  1. Download our preprocessed char-CNN-RNN text embeddings for birds and flowers and save them to 'Data/'.

    • [Optional] Follow the instructions here to download the pretrained char-CNN-RNN text encoders and extract your own text embeddings.
  2. Download the birds and flowers image data. Extract them to 'Data/birds/' and 'Data/flowers/', respectively.

  3. Preprocess images.

    • For birds: 'python ./misc/preprocess_birds.py'
    • For flowers: 'python ./misc/preprocess_flowers.py'

そんなわけで、とりあえずこのあたりからファイルをダウンロードします。

落として来たら、/Dataの下に落とした.zipファイルを展開・配置します。 今度は

からCUB-200-2011をダウンロードして、これもDataの中に展開・配置します。

この次に前処理なんですが、前処理ししようとしたらこんなエラー。

NameError: name 'xrange' is not defined

どうやら、Python2.xを想定しているらしく、Python3.xで動くように

"xrange" => "range"

に書き換えたら動きました。

改めて中身を見てみると、こんなファイル構成になっていました。

birds
- CUB_200_2011
 - attributes
 - images
  - xxx.画像名
   - 画像名.jpg
 - parts
 - bounding_boxes.txt
 - classes.txt
 - image_class_labels.txt
 - README
 - train_test_split.txt
- test
 - xxx.pickle
- text_c10
 - xxx.画像名
  -画像名.txt
- train
 - yyy.pickle
- example_captions.txt
- readme

見た感じ、学習はtrain/、テストはtest/から使えばいいみたいですね。 さらに中身を見ていくと下のようになっていました。

  • char-CNN-RNN-embeddings.pickle : Textが数値化された10×1024の行列が8855個
  • class_info.pickle : 2-200までの整数が8855個
  • filenames.pickle : ファイル名が8855個

StackGANを実装する上ではEmbedding(Textの数値化したもの)とEmbeddingに対応する画像ファイルが分かれば問題無いはずなので、char-CNN-RNN-embeddings.pickleとfilenames.pickle、画像ファイルがあれば事足りそうです。 (他のファイルは別のことに使うんだと信じてます。間違ってたらごめんなさい。)

Embeddingの概念図
Condition Augmentationの概念図

そんなわけで、char-CNN-RNN-embeddings.pickleを使用して、Condition Augmentationを作ってみます。

Trainer

StackGANの学習の特徴として、前半600epochはStage-Iのみを学習、後半600epochはStage-Ⅱのみを学習します。 そのため、学習は便宜上前半部と後半部を実行時に指定し、どちらの学習かを確認して、該当の学習を実行します。

Stage-Ⅰ

こんな感じでしょうか。

Stage-Ⅱ

実際に動かしてみた結果

こんな感じでした。

64 ×64

f:id:nogawanogawa:20181125152450p:plain

f:id:nogawanogawa:20181125152434p:plain

f:id:nogawanogawa:20181125152416p:plain

256×256

もうだいぶ鳥っぽくなってますね。 ところどころ、「あれっ?」ってなる部分はあるものの、大枠としては鳥に見えそうです。 Stage-IIを100epochくらい回してこんなもんなので、600epochやれば論文みたいにすべて鳥っぽくなりそうですね。

f:id:nogawanogawa:20181120152458p:plain

f:id:nogawanogawa:20181120152518p:plain

f:id:nogawanogawa:20181120152541p:plain

感想

使用するデータセットやらGPU使うための環境だったり、いろいろ手こずりました。 StackGAN自体も結構なコードのボリュームになるので、初めに作った人すごいなあとしみじみ思いました。。。