MXNet の GPU 版 R パッケージを無理やり Windows にインストールする

[公式サイトのインストール手順](http://mxnet.io/get_started/windows_setup.html#installing-mxnet-on-a-computer-with-a-gpu-processor)が更新されておらず役に立たないので自分で試行錯誤した結果のメモ。

# インストール手順

## 0. 準備：CUDA Toolkit をインストールする

[CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit) をインストールします。細かいことは NVIDIA の公式ドキュメントを読んでください。

## 1. いったん普通に MXNet をインストールする

```r
install.packages("drat", repos="https://cran.rstudio.com")
drat:::addRepo("dmlc")
install.packages("mxnet")
```

私の場合は `<マイドキュメント>/R/win-library/3.3/mxnet/` にインストールされました（※以降、この `<マイドキュメント>/R/win-library/3.3/` を `%R_LIBS%` と表記します。適宜自分の環境設定に合わせて読み替えてください）。**このディレクトリ内のファイルを以降の手順で入手するファイルに置き換えることで、GPU 版を無理やりインストールします……**

## 2. ビルド済み MXNet を入手する（※必要な DLL が入手できる）

[公式サイトのインストール手順](http://mxnet.io/get_started/windows_setup.html#installing-mxnet-on-a-computer-with-a-gpu-processor)には

> "Download the most recent GPU-enabled MXNet package from the Releases tab."

と書いてありますが、残念なことに[本家による Windows 向けビルド済み MXNet](https://github.com/dmlc/mxnet/releases/tag/20160531) の配布は2016年5月で止まってしまっています。代わりに [yajiedesign](https://github.com/yajiedesign) という方が公開してくれているビルド済み MXNet をダウンロードします。

* https://github.com/yajiedesign/mxnet/releases

> build windows update 20170225
> @yajiedesign yajiedesign released this 2 days ago
> 
> if you are first download.please download base package first
> 　vc12 base package
> 　vc14 base package
> 
> vc12 cudnn is update to v5.1. please download cudnnv5.1
> 
> Downloads
> 　20170225_mxnet_x64_vc14_cpu.7z
> 　20170225_mxnet_x64_vc14_gpu.7z
> 　Source code (zip)
> 　Source code (tar.gz)

上記のうち、"vc14 base package" と "20170225_mxnet_x64_vc14_gpu.7z" をダウンロードします。

解凍したら、"20170225_mxnet_x64_vc14_gpu.7z" の中身を "vc14 base package" に移して統合します（両方とも、解凍するとだいたい同じディレクトリ構成になっているはず）。

## 3. CuDNN を入手する

NVIDIA から [CuDNN](https://developer.nvidia.com/cudnn) をダウンロードします。会員登録が必要です。

解凍したら、3つのディレクトリ（`bin`、`include`、`lib`）を "20170225_mxnet_x64_vc14_gpu.7z" を解凍して作ったディレクトリ（※以降、このディレクトリを `%PREBUILD%` と表記します）の下にある `3rdparty/cudnn/` に移します。

## 4. ファイルを GPU版に置き換える

手順1でインストールしたファイルを、手順2～3で入手したファイルに置き換えます。

* `%R_LIBS%/mxnet/include/` に、以下のファイルをコピーする。重複するものは上書きする。
    * `%PREBUILD%/include/*`
    * `%PREBUILD%/nnvm/include/*`
* `%R_LIBS%/mxnet/libs/x64/` に、以下のファイルをコピーする。重複するものは上書きする。
    * `%PREBUILD%/lib/*`
    * `%PREBUILD%/3rdparty/` 以下にある DLL すべて（ディレクトリ構造は破棄してフラットにコピー）

# 動作確認

チュートリアルの [Handwritten Digits Classification Competition](http://mxnet.io/tutorials/r/mnistCompetition.html) を CPU と GPU でやってみます。

```r:CPU
> tic <- proc.time()
> model <- mx.model.FeedForward.create(
+   lenet, X = train.array, y = train.y,
+   ctx = device.cpu, num.round = 5, array.batch.size = 100,
+   learning.rate = 0.05, momentum = 0.9, wd = 0.00001,
+   eval.metric = mx.metric.accuracy,
+   epoch.end.callback = mx.callback.log.train.metric(100))
Start training with 1 devices
[1] Train-accuracy=0.55708830548926
[2] Train-accuracy=0.969023809523813
[3] Train-accuracy=0.981476190476194
[4] Train-accuracy=0.987190476190479
[5] Train-accuracy=0.990880952380955
> 
> print(proc.time() - tic)
   ユーザ   システム       経過  
   1026.73     300.65     754.62 
```

```r:GPU
> tic <- proc.time()
> model <- mx.model.FeedForward.create(
+   lenet, X = train.array, y = train.y,
+   ctx = device.gpu, num.round = 5, array.batch.size = 100,
+   learning.rate = 0.05, momentum = 0.9, wd = 0.00001,
+   eval.metric = mx.metric.accuracy,
+   epoch.end.callback = mx.callback.log.train.metric(100))
Start training with 1 devices
[1] Train-accuracy=0.553484486873508
[2] Train-accuracy=0.969190476190479
[3] Train-accuracy=0.981547619047622
[4] Train-accuracy=0.988357142857145
[5] Train-accuracy=0.991523809523812
> 
> print(proc.time() - tic)
   ユーザ   システム       経過  
     12.50      14.38      14.61 
```

50倍くらい速いですね……！うまくインストールできたようです。

# 環境

* GeForce GTX 1060
* Windows 10 Pro 64bit
* Microsoft Visual Studio Community 2015 (Microsoft Visual C++ 2015)
* CUDA Toolkit 8.0
* CuDNN 5.1
* R version 3.3.1
* MXNet 0.9.4

# 参考にしたページ

* [Installing MXNet on a Computer with a GPU Processor](http://mxnet.io/get_started/windows_setup.html#installing-mxnet-on-a-computer-with-a-gpu-processor)
* [cannot install latest (20170206) gpu version r package on windows 10 #4896](https://github.com/dmlc/mxnet/issues/4896)