nvidia/tensorflowコンテナイメージでShow and Tell

[NVIDIA GPU CLOUD](https://ngc.nvidia.com/)の[nvidia/tensorflow](https://ngc.nvidia.com/registry/nvidia-tensorflow)コンテナイメージで、[Show and Tell: A Neural Image Caption Generator](https://github.com/tensorflow/models/tree/master/research/im2txt)を試す。

## システム構成
* Ubuntu Server 16.04.3 LTS
* NVIDIA GeForce GTX 1080
* 1.0TB SSHD（学習データで150GB以上を使うのでディスクには余裕が必要）

## 事前準備
 *  [NVIDIA GPU CLOUD（NGC）](https://ngc.nvidia.com/)でアカウントを作成
 *  [Docker CEのインストールとNGCからコンテナイメージを実行](https://qiita.com/m1takahashi/items/c653c90419aefec1e315)できるようにしておく

## nvidia/tensorflowコンテナイメージの内容
#### インストール済み
 * python 2.7
 * tensorflow 1.4.0
 * numpy 1.11.0
 * NLTK 3.2.5

#### 追加インストールが必要
 * bazel 0.5.4

## コンテナのカスタマイズ
#### dockerにログイン（NGC画面右の[GET API Key]で取得したkeyをPasswordに入力）
```
# docker login nvcr.io
Username: $oauthtoken
Password: 
```

#### ベースになるイメージの取得（ホストマシン）
```
# docker pull nvcr.io/nvidia/tensorflow:17.12
```
#### nvidia/tensorflowコンテナの起動＆ログイン（ホストマシン）
```
# nvidia-docker run -it nvcr.io/nvidia/tensorflow:17.12
```
#### ライブラリのインストール（コンテナ）
```
# apt-get install libcupti-dev
```
```
# apt-get update
# apt-get install openjdk-8-jdk
# echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
# curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
# apt-get update && apt-get install bazel
# apt-get upgrade bazel
```

#### バージョンの確認とpunktのダウンロード（コンテナ）
```
>>> import numpy as np
>>> np.version.full_version

>>> import tensorflow as tf
>>> tf.__version__

>>> import nltk
>>> nltk.__version__

>>> import nltk
>>> nltk.download('punkt')
```
#### カスタムコンテナの保存（ホストマシン）
```
$ nvidia-docker ps
$ nvidia-docker stop [コンテナ名]
$ nvidia-docker commit [コンテナ名] custom_tensorflow:00.01
```
クリーンな実行環境を作成しておくことで、やり直しがしやすくなります。


## カスタムコンテナの起動
 * ```-p 6006:6006``` TensorBoard用のポートフォワード
 * ```-v /root/data/im2txt:/root/im2txt``` ホストマシンのディレクトリをマウント

```
# nvidia-docker run -p 6006:6006 -v /root/data/im2txt:/root/im2txt -it --name "custom_tensorflow" custom_tensorflow:00.01 /bin/bash
```

## Show and Tellモデルを学習させる（コンテナ）
```
# git clone https://github.com/tensorflow/models.git
```
```
# cd models/research/im2txt/
# MSCOCO_DIR="${HOME}/im2txt/data/mscoco"
# bazel build //im2txt:download_and_preprocess_mscoco
```
#### 学習データ画像のダウンロードリンク変更
アーカイブのURLを指定した方が、早くダウンロードできます。

```
# vi bazel-bin/im2txt/download_and_preprocess_mscoco
BASE_IMAGE_URL="http://msvocds.blob.core.windows.net/coco2014"
↓
BASE_IMAGE_URL="http://images.cocodataset.org/zips"
```
#### 学習データの準備
```
# MSCOCO_DIR="${HOME}/im2txt/data/mscoco"
# cd research/im2txt
# bazel build //im2txt:download_and_preprocess_mscoco
# bazel-bin/im2txt/download_and_preprocess_mscoco "${MSCOCO_DIR}"
```

#### Inception v3のダウンロード
```
# INCEPTION_DIR="${HOME}/im2txt/data"
# mkdir -p ${INCEPTION_DIR}

# wget "http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz"
# tar -xvf "inception_v3_2016_08_28.tar.gz" -C ${INCEPTION_DIR}
# rm "inception_v3_2016_08_28.tar.gz"
```

#### 学習開始
```
# MSCOCO_DIR="${HOME}/im2txt/data/mscoco"
# INCEPTION_CHECKPOINT="${HOME}/im2txt/data/inception_v3.ckpt"
# MODEL_DIR="${HOME}/im2txt/model"
# cd research/im2txt
# bazel build -c opt //im2txt/...
```
```
# bazel-bin/im2txt/train \
  --input_file_pattern="${MSCOCO_DIR}/train-?????-of-00256" \
  --inception_checkpoint_file="${INCEPTION_CHECKPOINT}" \
  --train_dir="${MODEL_DIR}/train" \
  --train_inception=false \
  --number_of_steps=1000000
```
途中からでも学習は再開できるので、とりあえず```--number_of_steps=10000```ぐらいで試して、現実的に処理できるか（主に時間）を確認した方が良いと思います。

## Tips
### TensorBoadの起動
#### 起動
```
# MODEL_DIR="${HOME}/im2txt/model"
# tensorboard --logdir="${MODEL_DIR}"
```

#### 確認
```
http://localhost:6006/
```