はじめに
以下のリポジトリにDomain Adaptationに関する2つの論文のサンプルコードが置いてあります。
これらを動かすのに一手間かかったので備忘録として残しておきます。
https://github.com/tensorflow/models/tree/master/research/domain_adaptation
環境
ホストOS: Ubuntu16.04
GPU: GeforceGTX1080
メモリ: 8G
nvidia-docker2を使ったコンテナ内で動作させます。
学習の結果などはtensorboardで確認するので、コンテナポート6006をホストのどこかにマッピングさせておきましょう。
version: '2.3'
services:
deeplearning:
image: nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
runtime: nvidia
tty: true
ports:
- "16006:6006"
手順
環境構築
# ツール類のインストール
apt-get update
apt-get install git vim python
# pipのインストール
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
# numpy, tensorflowのインストール
pip install numpy tensorflow-gpu
# bazel(ビルドツール)のインストール
apt-get install apt-get install pkg-config zip g++ zlib1g-dev unzip python
curl -O https://github.com/bazelbuild/bazel/releases/download/0.17.2/bazel-0.17.2-installer-linux-x86_64.sh
sh bazel-0.17.2-installer-linux-x86_64.sh
ソースの準備
domain_adaptationを含むmodels/research配下のディレクトリ郡は、以前はmodels配下に全部配置されていたようなのですが、今のディレクトリ構成だと動かないので昔の状態に戻します。
なお、動作確認時に使用した最新のコミットは91b2debda873c77a5886ca76b3ca50cfbe8a1d4e
です。
git clone https://github.com/tensorflow/models.git
mv models/research/* models
ビルドと実行
ここからREADMEの手順に従って実行します。
Initial Setup
私の環境では、以下のように読み換えました。
export DSN_DATA_DIR=/your/dir
->
export DSN_DATA_DIR=/root/dev/data
export PYTHONPATH=$PYTHONPATH:$PWD:$PWD/slim
->
export PYTHONPATH=$PYTHONPATH:/root/dev/tensorflow/models:/root/dev/tensorflow/models/slim
Getting the datasets
modelsフォルダに移動して、mnistのデータ取得コマンドを実行します。
cd /root/dev/tensorflow/models
bazel run slim:download_and_convert_data -- --dataset_dir $DSN_DATA_DIR --dataset_name=mnist
次に、MNIST-Mのデータをリンク先からダウンロードし、$DSN_DATA_DIRに展開します。
tar zxvf mnist_m.tar.gz
mv mnist_m $DSN_DATA_DIR
bazel run domain_adaptation/datasets:download_and_convert_mnist_m -- --dataset_dir $DSN_DATA_DIR
Running PixelDA from MNIST to MNIST-M
学習を行います。このとき、論文の結果を得た時のハイパーパラメータも同時に指定します。
bazel run domain_adaptation/pixel_domain_adaptation:pixelda_train -- --dataset_dir $DSN_DATA_DIR --source_dataset mnist --target_dataset mnist_m --hparams arch=resnet,domain_loss_weight=0.135603587834,num_training_examples=16000000,style_transfer_loss_weight=0.0113173311334,task_loss_in_g_weight=0.0100959947002,task_tower=mnist,task_tower_in_g_step=true
評価を行います。学習時のハイパーパラメータを指定する必要があります。
bazel run domain_adaptation/pixel_domain_adaptation:pixelda_eval -- --dataset_dir $DSN_DATA_DIR --source_dataset mnist --target_dataset mnist_m --target_split_name test --hparams arch=resnet,domain_loss_weight=0.135603587834,num_training_examples=16000000,style_transfer_loss_weight=0.0113173311334,task_loss_in_g_weight=0.0100959947002,task_tower=mnist,task_tower_in_g_step=true
tensorboardを起動し、ブラウザでアクセスすると学習結果などのサマリが確認できます。
tensorboard --logdir=/tmp/pixelda --host 0.0.0.0
Running DSN code for adapting MNIST to MNIST-M
このコードを動かす前に、.soファイルを動作環境に合わせてコンパイルしなおす必要があります。うまくいけば_grl_ops.soが新たに生成されるはずです。
mv _grl_ops.so _grl_ops.so.bak
cd domain_adaptation/domain_separation
TF_CFLAGS=( $(python -c 'import tensorflow as tf; print(" ".join(tf.sysconfig.get_compile_flags()))') )
TF_LFLAGS=( $(python -c 'import tensorflow as tf; print(" ".join(tf.sysconfig.get_link_flags()))') )
g++ -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++11 -shared grl_ops.cc grl_op_kernels.cc -o _grl_ops.so -fPIC ${TF_CFLAGS[@]} ${TF_LFLAGS[@]} -O2
学習用コマンドのビルドを行います。
bazel build -c opt domain_adaptation/domain_separation/...
学習を行います。
./bazel-bin/domain_adaptation/domain_separation/dsn_train \
--similarity_loss=dann_loss \
--basic_tower=dann_mnist \
--source_dataset=mnist \
--target_dataset=mnist_m \
--learning_rate=0.0117249 \
--gamma_weight=0.251175 \
--weight_decay=1e-6 \
--layers_to_regularize=fc3 \
--nouse_separation \
--master="" \
--dataset_dir=${DSN_DATA_DIR} \
-v --use_logging
評価を行います。
./bazel-bin/domain_adaptation/domain_separation/dsn_eval \
-v --dataset mnist_m --split test --num_examples=9001 \
--dataset_dir=${DSN_DATA_DIR}
踏んだ轍
- 適当にインストールした最新のtensorflow, CUDA, cuDNNでは動作しなかったのでnvidia提供のコンテナ環境を使うようにした
- python3ではmnistのデータ変換がうまくいかなかったので2.7を使うようにした
- ハイパーパラメータをつけないで学習させてたら延々と学習してて終わらなかった