TecoGANについてのメモ帳

こんにちは

最近機械学習について勉強し始めたので、自分用に書きます。
初めて書くので書き方に間違いがあればご指摘いただけると嬉しいです。

今回は動画の超解像を行えるTecoGANについて動かしてみました。
ソース：https://github.com/thunil/TecoGAN
論文：https://arxiv.org/pdf/1811.09393.pdf

理解が浅いと思うので何かあればつっこんでください…
また、今後修正するかもです。
また、OSはubuntuを用いています。
TecoGANはなにかとwgetを使用するので、windowsだとめんどくさいからです。
###PCスペック
OS : Ubuntu　18.04
CPU: i5 4670k
GPU: Geforce 2060SP
メモリ：16GB
言語: python 3.6

#TecoGANの導入
基本的にgitの手順どおりに進めます。
まずgitからソースコードをもらいます。

```ruby:cmd
git clone https://github.com/thunil/TecoGAN.git
```

次いで、必要なパッケージをインストールしましょう。

```ruby:cmd
pip install --upgrade pip 
pip3 install tensorflow-gpu==1.14.0 
　# tensorflow-gpuのインストール。gpuを使わない方はここはtensorflowのみで。
pip3 install -r requirements.txt
　#　その他必要なパッケージのインストール
```
tensorflow-gpuをインストールする点でgitと違いますが、これはgitの手順だとtensorflow-gpuのバージョンが2.xになってしまい、バージョン違いによるプログラムの動作不良が起きるためです。

また、仮想環境を構築してそこにパッケージをインストールするのが安心かもしれません。
自分ははじめに着手したのがTecoGANのため、構築していません。

##環境整備
私はGPUを使ってTecoGANの計算を行いましたので、CUDAやcudnnを入れています。
``CUDA　cudnn 対応バージョン早見表``
https://www.tensorflow.org/install/source?hl=ja#gpu_support_2
上記のサイトはtensorflowとCUDA, cudnnが正常に動くバージョンの早見表となっています。
これを守らないとGPUを認識してくれないことがあります。

tensorflow-gpu==1.14.0を確認すると、CUDA10.0、cudnn7.4が正常に動くようです。

まずはじめに

```ruby:cmd
sudo apt update
sudo apt upgrade
```
####GPUドライバのインストール
ドライバについてメモ程度に

```ruby:cmd
ubuntu-drivers devices
```
推奨ドライバが複数出現
``recommended``と記載されたドライバをインストール

```ruby:cmd
sudo apt install nvidia-driver-xxx
```
再起動することで、nvidia-smiコマンドが使用可能になります。
これはgpuの使用率や、gpuの機器がわかります。

####CUDAをインストール
すでにCUDAの違うバージョンをインストールしている場合、最初に以下のコマンドを実行。

```ruby:cmd
sudo apt --purge remove cuda*
sudo apt autoremove
```
これで違うバージョンのものが消せると思います。
次にCUDA10.0をインストールするため以下を実行

```ruby:cmd
wget https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda-repo-ubuntu1804-10-0-local-10.0.130-410.48_1.0-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-10-0-local-10.0.130-410.48_1.0-1_amd64
sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub
sudo apt update
sudo apt-get install cuda-toolkit-10-0
```
これで完了です。

```ruby:cmd
nvcc -V
```
上記コマンドを打つとCUDAのバージョンが表示されます。

####cudnnをインストール
少しだけ面倒です。
というのも会員登録をしなくてはなりません。
https://developer.nvidia.com/cudnn
上記リンクから[Download cuDNN]を選択し、その後[Join now]で登録してください。

その後は、ログイン後[I Agree ~~]にチェックを入れ、自分の所望するバージョンのcudnnを選択します。
今回で言えばcudnn v7.4.2になります。

[cudnn Library for Linux] を選択し、ダウンロードが終わるのを待ちます。
その後ダウンロードしたフォルダ下に行き、解凍し、環境に組み込んでいきます。


```ruby:cmd
tar -xvzf cudnn-10.0-linux-x64-v7.4.2.24.tgz
cp -a cuda/lib64/* /usr/local/cuda/lib64/
cp -a cuda/include/* /usr/local/cuda/include/
```
これで完了です。
cudnnに関してはwgetを使うとエラーが発生します。
ログインしないからかな。



####GPUの動作確認
以下の二行のコードで確認できます。

```ruby:python
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```
以下のような言葉が下の方に書かれていたらGPUは認識してます。

```
Created TensorFlow device (/device:GPU:0 with 6654 MB memory) -> physical GPU (device: 0, name: GeForce RTX 2060 SUPER, pci bus id: 0000:01:00.0, compute capability: 7.5)
```


##TecoGAN動作
TecoGANは学習済みモデルが用意されており、それを軸にプログラムを動作させています。
ですので、学習済みモデルと低解像度動画、高解像度動画をインストールします。
10分くらいかかったかも。

```ruby:cmd
cd TecoGAN
python runGan.py 0
```

インストール完了後以下のコードで動作させます。

```ruby:cmd
python runGan.py 1
```

超解像されたカレンダーの画像が生成されます。
結果はTecoGANフォルダ下、resultsのフォルダにあります。

やっぱり画像で出力されるんですね。
エンコードするためにはほかのツールが必要となり、TecoGANではffmpegが推奨されています。

```
sudo apt-get install ffmpeg
```
インストールして動画にして比べてみてください。
結構きれいになっているようです。

ちなみに

```
python runGan.py 2
```
で数値的な評価もできます。
指標は
PSNR
SSIM
LRIPS
tLP100
tOF
だそうですが、まだちゃんと理解できてないです。
特に下3つ
誰か教えてください。


###TecoGAN動作　〜〜好きな動画で〜〜
テスト画像動かしてもつまらないので。
最初に、自分の好きな動画を低解像度にしてください。

```
ffmpeg -i 動画のpath.mp4 -vf scale=270:-1  低解像度動画出力path.mp4
```
scaleでは片方の画素数を指定してやれば、勝手に元の動画と同じアスペクト比に調整してくれます。
私は元の動画が1920*1080ですので、解像度を落とした動画は480*270になっています。

というのもTecoGANの拡大は4倍で固定されているため、超解像後の動画とオリジナルの動画を比較するためこの解像度にしています。

次に低解像度化した動画をffmpegなどでフレームごとに画像にしてください。

```
ffmpeg -i 動画のpath.mp4 -vcodec png 画像を出力するフォルダ/%04d.png
```


###準備ができたら動かしてみる
さて、好きな動画をフレーム群にしたならば、超解像をします。
`TecoGAN/LR` に自分の好きな名前でフォルダを作成します。
今回は適当に`hogehoge`としました。
`TecoGAN/LR/hogehoge`に自分のフレーム群を投入します。

次に`runGan.py`のプログラムを確認します。

```ruby:runGan.py
elif( runcase == 1 ): # inference a trained model
    
    dirstr = './results/' # the place to save the results
#    testpre = ['calendar'] # the test cases
    testpre = ['hogehoge'] # the test cases　#追加
    if (not os.path.exists(dirstr)): os.mkdir(dirstr)
```

一行プログラムを追加します。
これで準備は完了です。

```
python runGan.py 1
```
動かせば超解像されたフレーム群が生成されているはずです。
`results/hogehoge`を確認してください。

たぶんですがそこまでいい結果が得られてないのではないかなと思います。
モデルを学習させないといけません。
この先のモデルの学習については次にメモしたいと思います。
初めてでたくさん書いて疲れました。
もし何か見づらい点あればご指摘いただけると幸いです。

#おまけ
GPUがよわよわだとフルHDへの超解像はできないです。
メモリ不足に陥ります。
そこで`Google colaboratory`は非常に有用です。
最近触り始めたばかりなのであれですが、どうやらgoogle driveと連携が取りやすくなったとか。

なので動作させるためにちょっと触れときます。
メモ程度なので見にくかったら申し訳ないです。

まず、google colaboratoryではただで高スペックのGPUを使用することができます。
具体的には、「ランタイム」→「ランタイムのタイプを変更」→「None」→「GPU」にするだけです。
非常に簡単。

google colaboratoryでは機械学習に必要な各種パッケージがはじめから入っています。
もちろんtensorflowも最新版が導入されています。

しかしTecoGANではtensorflowはバージョン1.xではないと動きません。（動くのですがエラーをたくさん吐きます）

ですので、バージョンをまず下げます。

```
!pip uninstall -y tensorflow
!pip install tensorflow-gpu==1.14.0
```
google colaboratotyでは基本的にコマンドは文頭に「！」をつけます。
先にも言ったとおり、tensorflowのバージョンを下げたためcudaとcudnnのバージョンと不具合を起こしGPUを認識しなくなります。

ですので、CUDAとcudnnをインストールし直してください。

```
!apt-get --purge remove cuda*
!apt autoremove
```
上記コマンドではcudaをすべて削除しています。
通常と同じです。
cudnnは消さなくてもいけるっぽいです。
ただ、cudnnをインストール後、下記プログラムを動作させるといいかもしれないです。

```
import os 
os.environ["CUDA_HOME"]="/usr/local/cuda"
os.environ["LIBRARY_PATH"]="/usr/local/cuda/lib64"
```
不具合でたらごめんなさい。

念の為、ランタイムを再起動し、tensorflowのバージョンを確認します。

```
!pip freeze | grep -i -e tensorflow
--
tensorflow-addons==0.8.3
tensorflow-datasets==2.1.0
tensorflow-estimator==1.14.0
tensorflow-gcs-config==2.3.0
tensorflow-gpu==1.14.0
tensorflow-hub==0.8.0
tensorflow-metadata==0.22.2
tensorflow-privacy==0.2.2
tensorflow-probability==0.11.0
```

良さそうです。
GPUを確認します。

```
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
---
[name: "/device:CPU:0"
 device_type: "CPU"
 memory_limit: 268435456
 locality {
 }
 incarnation: 7140650767936614436, name: "/device:XLA_GPU:0"
 device_type: "XLA_GPU"
 memory_limit: 17179869184
 locality {
 }
 incarnation: 10124152797065672754
 physical_device_desc: "device: XLA_GPU device", name: "/device:XLA_CPU:0"
 device_type: "XLA_CPU"
 memory_limit: 17179869184
 locality {
 }
 incarnation: 8094731668087896846
 physical_device_desc: "device: XLA_CPU device", name: "/device:GPU:0"
 device_type: "GPU"
 memory_limit: 15956161332
 locality {
   bus_id: 1
   links {
   }
 }
 incarnation: 845827148846290348
 physical_device_desc: "device: 0, name: Tesla P100-PCIE-16GB, pci bus id: 0000:00:04.0, compute capability: 6.0"]
```
認識されてます。
あとは同じようにTecoGANで遊んでください。


ただ、確かモデルの学習に必要な動画(vimeo)を落とせなかった気がします。

```
!python3 dataPrepare.py --start_id 2000 --duration 120 --REMOVE --disk_path TrainingDataPath　#確かできなかった気が…？
```
自分で動画落としてフレームに分割する必要が出てくるのでちょぴっと大変かもしれません。
まぁ好きな動画をきれいに超解像するならばその道は通らなくては行けない道かもしれませんので問題じゃないかもです。

#最後に
動かないや誤字などの指摘お願いいたします。

また、私は現在TecoGANの超解像を2倍や3倍、6倍にしたいと考えており奮闘しているのですがうまく行っていません。
ourFRVSRがそもそも4倍のモデルのためです。
なにかアドバイス等あればよろしくお願いいたします。

ありがとうございました。