deep3d に挑戦して敗れた話

# はじめに

本記事は、[Python Advent Calendar 2016](http://qiita.com/advent-calendar/2016/python)の 3 日目の記事です。
敗れた話なので、最後はエラーで終わります。

---

# deep3dとは

DeepLearning を使って、画像を 3D 用に変換する[ライブラリ](https://github.com/piiswrong/deep3d)です。

![teaser.png](https://qiita-image-store.s3.amazonaws.com/0/39090/9691958f-961a-bc3b-1e88-3b6f20d842ca.png)

---

# これが

![demo.jpg](https://qiita-image-store.s3.amazonaws.com/0/39090/7269a56c-34dc-dfb0-8639-28b59827a711.jpeg)

---

# こうなるんじゃ！

![demo.gif](https://qiita-image-store.s3.amazonaws.com/0/39090/8be4416b-c6cb-8923-2ef3-48c471f3d1eb.gif)

---

# 夢が広がりますね (人´∀｀)

---

# ここからは簡単な手順の解説

---

# GPU が使えるマシンを準備

- AWS の g2.2xlarge、もしくは g2.8xlarge の EC2 インスタンスを作る
    - 事前に使用制限解除の申請をする必要あり
    - 結構ストレージを使うので、無料枠は 30GB 全部使う
- もちろん AWS 以外でも全然おｋ

---

# ライブラリをインストール

- CUDA（GPU の統合開発環境）
- cuDNN（GPU で neural network を動かすためのライブラリ）
    - NVIDIA に developer 登録する必要あり
- MXNet（DeepLearning のライブラリ）

---

# 参考

- [Setup Amazon AWS GPU instance with MXnet](https://no2147483647.wordpress.com/2016/01/16/setup-amazon-aws-gpu-instance-with-mxnet/)
    - 上記の LD_LIBRARY_PATH に /usr/local/cuda/lib64/ も追加する必要あり
    - g2.2xlarge を選んでいたら、```nvidia-smi``` で表示される GPU は 1 つ
- [Deep3Dに対応させたMXNet 0.7.0をインストールしてみた](https://soralab.space-ichikawa.com/2016/08/mxnet-install/)
    - MXNet で deep3d を処理するには、上記を参考にしてね

---

# python の準備

- pyenv をインストールする
    - [PyenvによるPython3.x環境構築(CentOS, Ubuntu)](http://qiita.com/akito1986/items/be5dcd1a502aaf22010b)
- anaconda と openCV をインストールする
    - [pythonでOpenCVを使う一番簡単な方法](http://qiita.com/massaru129/items/8a1a75cdf713d4fa6bc8)
- images2gif も入れる
    - [PinguCarsti / packages / images2gif](https://anaconda.org/pingucarsti/images2gif)

---

# 画像を準備する

![demo2.png](https://qiita-image-store.s3.amazonaws.com/0/39090/382f0b17-d70b-342c-cbc9-d6d630c06a97.png)

---

# サンプルと同じように実行

- これ参考にするのが良いかと
    - [deep3d.ipynb](https://github.com/piiswrong/deep3d/blob/master/deep3d.ipynb)
- 画像は事前に差し替える
- git clone してきた deep3d ディレクトリで実行しないと、deep3d-symbol.json の読み込みエラーが発生する
    - 実行したいディレクトリにコピーしてもおｋ
- 今回、jupyter は使わなかった

---

# サンプルと同じように実行

```
import mxnet as mx
import numpy as np
import os
import urllib
import cv2
from PIL import Image
from images2gif import writeGif
import logging
logging.basicConfig(level=logging.DEBUG)
```

---

# サンプルと同じように実行

```
if not os.path.exists('deep3d-0050.params'):
    urllib.urlretrieve('http://homes.cs.washington.edu/~jxie/download/deep3d-0050.params', 'deep3d-0050.params')
model = mx.model.FeedForward.load('deep3d', 50, mx.gpu(0))
shape = (384, 160)
img = cv2.imread('demo.jpg')
raw_shape = (img.shape[1], img.shape[0])
img = cv2.resize(img, shape)
X = img.astype(np.float32).transpose((2,0,1))
X = X.reshape((1,)+X.shape)
test_iter = mx.io.NDArrayIter({'left': X, 'left0':X})
Y = model.predict(test_iter)
```

---

# FATAL ERROR!!!!

```
>>> test_iter = mx.io.NDArrayIter({'left': X, 'left0':X})
>>> Y = model.predict(test_iter)
[16:21:56] src/operator/./reshape-inl.h:311: Using target_shape will be deprecated.
[16:21:57] src/operator/./reshape-inl.h:311: Using target_shape will be deprecated.
[16:21:57] src/operator/./reshape-inl.h:311: Using target_shape will be deprecated.
[16:21:57] /home/ubuntu/mxnet/dmlc-core/include/dmlc/logging.h:235: [16:21:57] src/operator/./cudnn_softmax_activation-inl.h:44: Check failed: (in_data[softmax_activation::kData].ndim()) == (2) Input need to have 2 dimensions when mode=instance.
[16:21:57] /home/ubuntu/mxnet/dmlc-core/include/dmlc/logging.h:235: [16:21:57] src/engine/./threaded_engine.h:306: [16:21:57] src/operator/./cudnn_softmax_activation-inl.h:44: Check failed: (in_data[softmax_activation::kData].ndim()) == (2) Input need to have 2 dimensions when mode=instance.
An fatal error occurred in asynchronous engine operation. If you do not know what caused this error, you can try set environment variable MXNET_ENGINE_TYPE to NaiveEngine and run with debugger (i.e. gdb). This will force all operations to be synchronous and backtrace will give you the series of calls that lead to this error. Remember to set MXNET_ENGINE_TYPE back to empty after debugging.
terminate called after throwing an instance of 'dmlc::Error'
  what():  [16:21:57] src/engine/./threaded_engine.h:306: [16:21:57] src/operator/./cudnn_softmax_activation-inl.h:44: Check failed: (in_data[softmax_activation::kData].ndim()) == (2) Input need to have 2 dimensions when mode=instance.
An fatal error occurred in asynchronous engine operation. If you do not know what caused this error, you can try set environment variable MXNET_ENGINE_TYPE to NaiveEngine and run with debugger (i.e. gdb). This will force all operations to be synchronous and backtrace will give you the series of calls that lead to this error. Remember to set MXNET_ENGINE_TYPE back to empty after debugging.
Aborted (core dumped)
```

---

# why?

- ```Input need to have 2 dimensions when mode=instance.```
    - 渡してるやん？
    - ```test_iter = mx.io.NDArrayIter({'left': X, 'left0':X})```
- c++ のソースコード読んだけど、解決に至らず・・

---

# (´・ω・`)

---

# おわりに

- deep3d は動画にも使えるらしいので、もうちょっと頑張りたい
    - そのうち DeepLearning のロジックとかも理解したい
- AWS がマジ便利
- python がホント便利
    - 今回は特に anaconda が神がかってた