Google ColaboratoryとGoogle Driveを使ってPGGANを動かしてみた。

実際に生成してみた画像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/482ac0af-0ae8-f4e8-5cf0-a72f734c9577.png)



#本記事について
・**学習済みモデルのPGGANを使って画像生成をしてみる**

StyleGANが2018年12月、PGGANが2017年10月に発表されたものであるため、StyleGANと比べると劣る
StyleGANを使った画像生成に関しては下記の記事で行っている
>https://qiita.com/Phoeboooo/items/12d21916de56d125f0be

・**Google Driveへのマウントをすることで、Google DriveにあるファイルをGoogle Colaboratoryで使えるようになる**



#画像生成までの流れ（変更前）
###GitHub通りの手順

・本章ではGitHub通りの手順を参考として記載する

・画像生成までの流れ（変更後）の章から具体的にGoogle Colaboratoryで画像生成する場合の流れを見ていく

①PGGANのリポジトリを複製する

```python
git clone https://github.com/tkarras/progressive_growing_of_gans.git
```

②必要なPythonパッケージ(numpy等のバージョン)をインストールする

```python
pip install -r requirements-pip.txt
```
③import_example.py（画像生成を実行するファイル）をダウンロードする
④karras2018iclr-celebahq-1024x1024.pkl（学習済みモデル）をダウンロードする
⑤import_example.pyを実行する

```python
python import_example.py
```

⑥画像が10枚生成される
>https://github.com/tkarras/progressive_growing_of_gans

**Google Colaboratoryで実行したい場合は、この手順では上手くいかないため後述する変更を加える必要がある**

##問題点
上記の③・④のようにダウンロードをすると、**ダウンロードしたファイルは自分が使っているパソコン（ローカル）に入ってくるためGoogle Colaboratory上で使えない**

##目標

・**PGGANのリポジトリに、ダウンロードしたファイル２つを加えたものをGoogle Driveにアップロードもしくはコピーする**

・**Google ColaboratoryでGoogle Driveのファイルを使えるようにする**

次章から生成までの順序や詳細について説明する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/683cd327-34c2-a569-0617-6d60aec3613f.png)


#画像生成までの流れ（変更後）

###①ローカルにリポジトリを複製する

```python
git clone https://github.com/tkarras/progressive_growing_of_gans.git
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/2294a4b3-be88-470b-2338-06a49a7caa2a.png)


###②必要な２つのファイルをローカルにダウンロードする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/1f90269d-a360-9f51-7e2a-9d3cd8cc980b.png)



以下のGitHubの「Importing and using pre-trained networks」の章にあるためクリックのみで可能
https://github.com/tkarras/progressive_growing_of_gans

###③PGGANのリポジトリにダウンロードしたファイル２つを移動する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/5e41e384-f7c7-d761-23a0-032399898eb5.png)


単純にドラッグ＆ドロップをして移す
###④リポジトリをGoogle Driveにアップロードもしくはコピーする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/c597c92b-7610-6513-622f-235ae72a14e1.png)


Google Driveにアップロードもしくはコピーするリポジトリはダウンロードしたファイル２つ（import_example.pyとkarras2018iclr-celebahq-1024x1024.pkl）を含むもの

アップロード：Google Driveで右クリック→フォルダをアップロード
コピー：ドラッグ&ドロップ

###⑤マウント
④まで行うと下図の様な状況になっている

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/d8d63c90-3a69-3038-1cf2-12f62bea49cb.png)


**Google Driveへのマウントをすることで、Google Colaboratory上でGoogle Driveのファイルを使えるようにする**


>参考
https://qiita.com/uni-3/items/201aaa2708260cc790b8
https://qiita.com/k_uekado/items/45b76f9a6f920bf0f786

まずは下記のコードを入力する

```python
from google.colab import drive
drive.mount('/content/drive')
```
実行すると以下のような表示になる（URLの黒枠と赤線は説明のために追加したもの）
![drive1.png](https://qiita-image-store.s3.amazonaws.com/0/315063/89f6eaa4-f2bc-38f4-c97a-0a29d576575a.png)

authorization codeを得るためにURLをクリックする
↓
アカウントを選択する
↓
許可をクリック
↓
以下のように表示される
黒枠に表示されたコードをコピーして上図の赤線のところに貼り付ける
![drive1.png](https://qiita-image-store.s3.amazonaws.com/0/315063/7674c220-1e02-0482-3370-3758926637a7.png)
↓
キーボードのEnterを押す
↓
完了

###⑥ディレクトリ移動
```python
cd drive/My Drive/progressive_growing_of_gans
```
```python
ls
```
PGGANのリポジトリにimport_example.pyとkarras2018iclr-celebahq-1024x1024.pklがちゃんと含まれていることが確認できる


###⑦必要なpythonパッケージをインストール
numpy等を指定されたバージョンで使えるようにする

```python
!pip install -r requirements-pip.txt
```

###⑧実行
```python
!python import_example.py
```
**これで画像を生成することができた**

###⑨生成画像を見る
⑧で画像は生成できたが、その**生成画像はどこにあるのか**を確認する

```python
ls
```
下記のように表示されるはず
**現在のディレクトリ(progressive_growing_of_gans)に１０枚の生成画像がある**ことがわかる

>config.py          　　　　　　karras2018iclr-celebahq-1024x1024.pkl
dataset.py         　　　　　　legacy.py
dataset_tool.py    　　　　　　LICENSE.txt
img0.png           　　　　　　loss.py
img1.png           　　　　　　metrics/
img2.png           　　　　　　misc.py
img3.png           　　　　　　networks.py
img4.png           　　　　　　__pycache__/
img5.png           　　　　　　README.md
img6.png           　　　　　　representative_image_512x256.png
img7.png           　　　　　　requirements-pip.txt
img8.png           　　　　　　tfutil.py
img9.png           　　　　　　train.py
import_example.py  　　util_scripts.py

したがって、生成画像をGoogle colaboratory上で表示させたいときは下記のようになる

```python
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

#画像内に線を表示しない
fig,ax = plt.subplots()
ax.tick_params(labelbottom="off",bottom="off")
ax.tick_params(labelleft="off",left="off")
ax.set_xticklabels([]) 
ax.axis('off')
#画像の読み込み
im = Image.open("img0.png")
#画像をarrayに変換
im_list = np.asarray(im)
#貼り付け
plt.imshow(im_list)
#表示
plt.show()
```
![pg1.png](https://qiita-image-store.s3.amazonaws.com/0/315063/e7513169-9191-c522-b50e-45153922495d.png)

###⑩生成画像をダウンロードする

```python
from google.colab import files
files.download("img0.png")
```
上記のコードで生成画像をダウンロードできる

#様々な顔画像を生成したい場合

上述のようにimport_example.pyを実行するだけでは同じ画像しか生成されない
　　　　　　　　　　　　　↓
**ハイパーパラメータを変えることで多様な画像を生成することができる**

##画像生成のコード



import_example.pyのコードは以下のようになっている

```python
import pickle
import numpy as np
import tensorflow as tf
import PIL.Image

# Initialize TensorFlow session.
tf.InteractiveSession()

# Import official CelebA-HQ networks.
with open('karras2018iclr-celebahq-1024x1024.pkl', 'rb') as file:
    G, D, Gs = pickle.load(file)

# Generate latent vectors. 512次元の潜在変数
latents = np.random.RandomState(1000).randn(1000, *Gs.input_shapes[0][1:]) # 1000 random latents
latents = latents[[477, 56, 83, 887, 583, 391, 86, 340, 341, 415]] # hand-picked top-10

# Generate dummy labels (not used by the official networks).
labels = np.zeros([latents.shape[0]] + Gs.input_shapes[1][1:])

# Run the generator to produce a set of images.
images = Gs.run(latents, labels)

# Convert images to PIL-compatible format.
images = np.clip(np.rint((images + 1.0) / 2.0 * 255.0), 0.0, 255.0).astype(np.uint8) # [-1,1] => [0,255]
images = images.transpose(0, 2, 3, 1) # NCHW => NHWC

# Save images as PNG.
for idx in range(images.shape[0]):
    PIL.Image.fromarray(images[idx], 'RGB').save('img%d.png' % idx)
```

##各自で変更できるところ
上記のコードから変更できる部分を抜粋

```python
# Generate latent vectors. 
latents = np.random.RandomState(1000).randn(1000, *Gs.input_shapes[0][1:]) # 1000 random latents
latents = latents[[477, 56, 83, 887, 583, 391, 86, 340, 341, 415]] # hand-picked top-10
```

この部分を言語化すると以下のようになる
###１行目
・RandomStateを1000に設定して、512次元の潜在変数を1000個用意する

・潜在変数をshapeで表すと（1000,512）

・RandomStateと潜在変数の数がどちらも1000になっているが、これは偶然同じ数字なだけであり、違う数字でも問題ない（例　RandomState：800、潜在変数の数：500）

変更できるところ：**①RandomStateの数字
　　　　　　　　　②潜在変数の数**

###２行目
・1000個の潜在変数の中から10個を選んでいる

・潜在変数をshapeで表すと（10,512）

・「477, 56, 83, 887, 583, 391, 86, 340, 341, 415」は1000個の中の478番目(0スタートのため1つずれる)、57番目、 84番目・・・を選んでいるという意味

変更できるところ：**①いくつ潜在変数を使うか（潜在変数の個数＝生成画像の枚数）
　　　　　　　　　②何番目の潜在変数を使うか**

#生成画像
ハイパーパラメータを変えて生成した画像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/315063/71bd318f-9bd5-5840-98ed-38ce8339b749.png)


#まとめ・感想
・PGGANの方が以前のモデルのため当然ではあるが、StyleGANと比べて画像の多様性・画質ともに劣っている
・言い換えると**約１年での進歩の速さ**を実感できる（PGGAN・StyleGANともにNVIDIA）


・**Google Driveへのマウントをすることで、Google Colaboratory上でGoogle Driveにあるファイルを利用することができる**


#参考
>https://qiita.com/uni-3/items/201aaa2708260cc790b8
https://qiita.com/k_uekado/items/45b76f9a6f920bf0f786

#コード
>https://github.com/tkarras/progressive_growing_of_gans