Single GANs(SinGAN)で遊んでみた （+実装しようとして苦労した点（path通し, Linuxコマンド, googlecolab活用等） もまとめた） 

#はじめに
　
　GANs：敵対的生成ネットワークの技術は日々進歩しています。非ＩＴ系の仕事（製造業での技術者）をしている私ですら強く興味が惹かれる技術です。より深く技術を理解するために、実装して遊んでみることが一番です。
　従って今回は、**Single GANs**と呼ばれる2019年に発表されたアルゴリズムを実装してみたいと思います。単一の画像から合成画像を生成するアルゴリズムとなっていますので、実際に動かしてみた記事になります。

　しかし、この最新の論文を実装すること、それ自体が私にとってはいくつハードルがありましたので、その苦労した点にも着目して記事を作成しています。


##今回の論文

　今回実装したい論文はこちらです。
>SinGAN: Learning a Generative Model from a Single Natural Image
https://arxiv.org/abs/1905.01164

　単一の画像のみを教師データとして、新しくその教師データに近い画像を生成することができます。さらに、手書きの画像から元画像に近い画像を生成させたり(Paint to image）、別の画像を重ね合わせて同じ作風へ変換させることができます（Harmonization）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/25aa6d64-6a01-36f1-5431-02b9a4ace3b9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/cf3be69e-e8dd-8ebb-f506-356e85803ff3.png)


　詳しいアルゴリズムの説明については私自身理解しきれないところがあるため、他の方の説明をご覧頂けると幸甚です。

>【論文解説】SinGAN: Learning a Generative Model from a Single Natural Image
https://qiita.com/takoroy/items/27f918a2fe54954b29d6

>SinGANの論文を読んだらテラすごかった
https://qiita.com/yoyoyo_/items/81f0b4ca899152ac8806


　さて、実装させるためにはまずこちらのgithubからプログラム一式をダウンロードして、zipファイルを解凍しました。
https://github.com/tamarott/SinGAN




##環境ファイルパスを通す

　さて、論文の内容を実装するにあたり、下記画像のようにターミナルからコマンドで指示することがよくあります。

```:Terminal
python -m pip install -r requirements.txt
```


最初にこれで必要なライブラリをインストールしようとしたら下記エラーメッセージが出ました。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/cadf9265-ec07-7ff6-af9c-87b4fcf00865.png)

これは、pythonというコマンドによってpython.exeを起動させることができていない＝パスが通っていないことを示します。従って、パスを通すための設定を行う必要があります。

Windowsアイコンを右クリック⇒設定を行います（当方Windows 10 Home）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/f6db748e-89b7-3eae-27b6-5c8de224979e.png)

そして、検索欄に環境と打つと、システム環境変数の編集欄が現れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/56a658a9-bc8e-2016-70bc-820ff095d523.png)

次に、システムのプロパティから環境変数をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/8557e5f8-a651-3036-6700-346ea1ada3f8.png)

ここのPathの編集を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/3e23e15b-5322-4ee6-32ce-4b0da113f006.png)
新規を選択し、python.exeが格納されているフォルダのパスを入れ込みます。これにより、パスが通すことができるようになり先ほどの問題が解決します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/1fe9b08a-ee07-9ccb-98ff-9942e77666d3.png)

成功するとこのように確認することができます。


##Argument Parserを理解する

 次に、pythonコマンドが通ったと思い次に進むとこのようなコマンドが現れました。random_samples.pyを実行することは理解しましたがその後の--とハイフンが二つ重なったコマンドになっています。
　調べたところ、これはターミナルコマンドから引数を指定することができるArgument Parserというモジュールを利用したものになります。

参考URL
https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0

```:Terminal
python random_samples.py --input_name <training_image_file_name> --mode random_samples --gen_start_scale <generation start scale number>
```

　コマンドラインから指定できることは便利なのですが、vs codeやjupyter上のカーネルで利用したい場合はどのようにすればよいのでしょうか。
　こちらのURLに詳しく載っていました。
http://flat-leon.hatenablog.com/entry/python_argparse


```python

# 3.ArgumentParserオブジェクトを使って起動パラメータを解析する
args = parser.parse_args()
```

 こちらで起動時のパラメータを解析しているようなので、listなどを作ってここに渡してあげることでカーネル上でも起動できるようです。


##いざ学習開始

　さて、ファイルパスやargumentについても理解できたところで早速実行します。しかし、小職のPCだと非常に学習に時間がかかることが分かりました。

+ RAM 8GB
+ intel core i7
+ 計算用のGPUは**無**

　今回の最初に行う学習では全9回（scale8）のうち6回（scale5中）を実行している断面で３時間程度経過していました。やはりGAN含め画像処理の計算は非常に時間がかかることが分かります。従って、ここは素直にGoogle Colab様のGPUを使用させて頂くことにしました。

Google Drive上に今回のフォルダをまとめてアップロードします。
そして、まずはその格納フォルダへディレクトリを移動します。

```:GoogleColab
cd  /content/drive/My Drive/SinGAN-master
```

これで、あとはLinuxコマンドを用いることで.pyファイルなどを動かすことができます。

##ノイズからの画像生成(Train）
　ノイズ画像から元の画像へ似せていく学習をさせていきます。学習初期は非常に小さい画像サイズから始まって、徐々に元の画像のサイズへ大きくなっていきます。

```:GoogleColab
!python main_train.py --input_name cows.png
```

Linuxコマンドを用いる場合は!を最初に入れることで動作します。
いざ動かしてみると、非常に早く進めることができます。凡そ30分くらいで計算が終了しました。
ライブラリのインストールも非常に楽ですので、処理時間を要するものはGoogleColabですね。。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/6357e5d7-426d-7842-c1bf-53ef4cf22038.png)

さて、生成した画像と元の画像を比べてみます。scale数が増えていくことは計算回数が増えていった結果です。
**うーん本物と区別がつかない笑。**画像サイズはscale数が低い時は小さいのですが、分かりやすく比較するために同じサイズにしています。
こうしてみると、徐々に鮮明な元の画像に近い画像に変化していくことが分かります。さらに、画質が上がっていくだけでなく、牛さん達の配置も毎回違うことが分かります。単純に画質を上げる処理ではないことが分かります。


　
##手書き画像から元の画像へ似せる処理（Paint to Image）

　次に、手書き画像から教師データ画像に似せるプログラムを実行します。これを行う際は最初に似せたい教師データを上記の訓練を行っておく必要があります。

```:GoogleColab
!python paint2image.py --input_name volacano.png --ref_name volacano3.png --paint_start_scale 1

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/03fea5f3-99d4-67e8-323b-7d38ae735aa8.png)


　結果を見てみましょう。**上手く再現はできませんでしたね。**元の画像が右下です。そして、start_scaleの値は小さいほど訓練数が高いものとなっています。今回は、start_scale3,4あたりが一番近いような気がします。

 おそらく、手書きによる**元画像の出来具合が似ていないと似せることは難しいようです**。

##画像サイズを自由に変更してみる（Random samples of arbitrery sizes）

次に、元画像をベースとして画像のサイズを変えた処理をします。

```:GoogleColab
!python random_samples.py --input_name cows.png --mode random_samples_arbitrary_sizes --scale_h 5 --scale_v 4
```
scale_hが横方向(horizonal）の縮尺で1が1倍を示します。また、scale_vが縦方向（vertical）の縮尺です。


![49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/b437d942-c714-835f-33bd-6a0e697eaf75.png)



試しに、大きな画像を作ってみました。**が、気持ち悪いですね。。大草原に密集した牛さんたちがいる画像になってしまいました。失礼致しました。。**


##元の作風に近づけて合成する（Harmonization）

　最後に、元の画像の作風に合わせて修正するという処理です。この処理の場合も最初にtrainで訓練させる必要があります。
　今回は、私が撮影した写真とフリー画像の魚を合成させてみました。

```:GoogleColab
!python harmonization.py --input_name fish.png --ref_name fish1.png --harmonization_start_scale 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/c92f0161-84d6-bef4-9fd4-40fccb92b170.png)


なんと大きな一匹の魚はスイミー（もしくはポケモンのヨワシ）のように水色の魚群と化しました。元々の朱色の魚群を元に処理されたのでしょう。非常に面白いアルゴリズムですね。





#おわりに
　
　GANの最新論文であるSingle GANsを実際に手を動かして遊んでみました。非常に簡便に使用できることが分かりました。

　実装させるにあたり、環境構築に関してもとても勉強になりました。特に、Google Colabがあることで計算負荷が高いモデルでも簡単に動かせて結果を見れることに感動を覚えました。Googleさんの偉大さを改めて感じました。

　今回は実装して遊んでみるところに注力したため、理論的な中身についても理解を深めていこうと思います。派生した論文もいくつかすでに出ているため、それとの関連についても学びたいです。