Amazonがオープンソースで公開したディープラーニングのライブラリ「DSSTNE」を使ってみる


![スクリーンショット 2016-05-24 午後4.01.50.png](https://qiita-image-store.s3.amazonaws.com/0/1418/2090a56f-bd68-7970-3390-e16367589166.png "スクリーンショット 2016-05-24 午後4.01.50.png")


## DSSTNEとは？

DSSTNEは、Deep Scalable Sparse Tensor Network Engineの頭文字を並べたもので、読み方は“Destiny”と読むらしい。

## なぜ今アマゾンがDeep Learning(DL)のオープンソースを発表したのか？
DSSTNEは、既存のDeepLearningのオープンソースよりも、データがSparse(疎)なときに高いパフォーマンスを示すため、Amazonのように大量の商品データ、ユーザーデータを持ち、その二つのオブジェクトが購買、評価などの行動をした行動データを持つような疎行列データを持つ場合に強いDeapLearningのオープンソースと言える。

## スパース(疎)行列データとは？
疎行列（そぎょうれつ、英: sparse matrix）とは、成分のほとんどが零である行列のことをいう。 スパース行列とも言う。 有限差分法、有限体積法、有限要素法などで離散化された偏微分方程式は一般に疎行列を係数行列とした連立一次方程式となる。(引用：wikipedia)

SNSやフリマなどのCtoCサービスや、ECやメディアなどのユーザーとコンテンツの関係が変化していくサービスでは、大量のコンテンツとユーザーの間に、またはユーザーとユーザーとの間に疎行列のようなデータ構造ができあがることが多い。

その需要は今後も拡大していくことが予想される中で、DSSTNEは"使いやすい"DeepLearningのライブラリになりそうな気がする。


## DSSTNEは他に比べて何がすごいのか？
1. EC2のg2.8xlargeインスタンスで、GoogleのTensorFlowに比べて2.1倍のスピードが出る
2. マルチGPUでのスケーリングによりスピードと正確性の両立を実現している

詳しくは[ここ](https://github.com/amznlabs/amazon-dsstne/blob/master/FAQ.md)を参照(※英語を汲み取り間違えてたら教えて下さいw)


## DSSTNEの実装環境

DSSTNEを利用する方法として以下の主な手法になります。
- Docker
- AWS
- 開発マシン

AWSで実装する場合、事前に環境構築を完了した状態のAMIを用意してくれているので、今回はAWSで実装してみます。

この画面のCommunity AMIsを選択して、検索ボックスに「ami-d6f2e6bc」と入力して検索すると「Amazon DSSTNE Image」というのが出てくるので「Select」をクリックしてインスタンスを構築してください。

![スクリーンショット 2016-05-24 午前2.53.09.png](https://qiita-image-store.s3.amazonaws.com/0/1418/930033eb-35c0-16a3-b61c-8d89423d431f.png "スクリーンショット 2016-05-24 午前2.53.09.png")


## AWSのインスタンスにSSHでログインする
ここは各々の方法でログインしてください。

```console
ssh -i "dsstne-test.pem" ubuntu@ec2-server-id
```

## DSSTNEのソースをcloneしてくる
```console
#DSSTNEのソースを取得する
git clone https://github.com/amznlabs/amazon-dsstne.git

#DSSTNEのHOMEに移動
cd amazon-dsstne/src/amazon/dsstne

#mpiCCとnvccコンパイラへのパスを通す
export PATH=/usr/local/openmpi/bin:/usr/local/cuda/bin:$PATH
make
export PATH=`pwd`/bin:$PATH
```

これで環境構築は完了。AMIを用意してくれてるのでマジ簡単。

## DSSTNEに使うデータの生成
```console
#MovieLensのサンプルデータをダウンロード
wget https://s3-us-west-2.amazonaws.com/amazon-dsstne-samples/data/ml20m-all
```

ダウンロードしたデータの中身を見てみると、

```
head ml20m-all

=>
user_id	movie_id,timestamp:movie_id,timestamp:…………
1	2,1112486027:29,1112484676:32,1112484819:47,1112484727:50,1112484580:112,1094785740:151,1094785734:223,1112485573:253,1112484940:260,1112484826:293,1112484703:296,1112484767:318,1112484798:337,1094785709:367,1112485980:541,1112484603:589,1112485557:593,1112484661:653,1094785691:919,1094785621:924,1094785598:1009,1112486013:1036,1112485480:1079,1094785665:1080,1112485375:1089,1112484669:1090,1112485453:1097,1112485701:1136,1112484609:1193,1112484690:1196,1112484742:1198,1112484624:1200,1112484560:1201,1112484642:1208,1112484815:1214,1094785977:1215,1094786082:1217,1112484810:1219,1094785994:1222,1112484637:1240,1112485401:1243,1112485567:1246,1094785759:1249,1112485382:1258,1094785994:1259,1112485440:1261,1094786113:1262,1112484735:1266,1112485371:1278,1094785986:1291,1112485525:1304,1094785720:1321,1094786062:1333,1112484990:1348,1094786056:1350,1094786158:1358,1112485419:1370,1094785764:1374,1094785746:1387,1112484913:1525,1112486150:1584,1094785656:1750,1112486201:1848,1112486032:1920,1112486098:1967,1112485739:1994,1094786087:1997,1094786034:2021,1112485929:2100,1112485955:2118,1094786092:2138,1112485789:2140,1112485705:2143,1112485951:2173,1112485887:2174,1112485843:2193,1112485753:2194,1112485486:2253,1112486122:2288,1094786077:2291,1094785777:2542,1112485447:2628,1112485988:2644,1112484994:2648,1094786017:2664,1094786148:2683,1094785650:2692,1112484749:2716,1094786012:2761,1112484759:2762,1112485367:2804,1112485414:2872,1112485697:2918,1112485465:2944,1112485433:2947,1112485580:2959,1094785698:2968,1112485825:3000,1112484569:3030,1112484548:3037,1112485563:3081,1094786143:3153,1112485816:3265,1112484525:3438,1112486094:3476,1094786139:3479,1112485734:3489,1112486024:3499,1112484918:3889,1112486138:3932,1094786172:3996,1094785727:3997,1112486192:4011,1112485406:4027,1112485460:4105,1094786104:4128,1112484933:4133,1112486169:4226,1112484493:4306,1094785784:4446,1112485970:4467,1112485822:4571,1112485880:4720,1094786008:4754,1112484983:4878,1112484537:4896,1112485731:4911,1112485961:4915,1112486076:4941,1112486007:4980,1112486055:4993,1112484682:5026,1112485858:5039,1112485898:5040,1112486086:5146,1094786132:5171,1112486104:5540,1112485905:5679,1094786108:5797,1112485871:5816,1112485720:5898,1112486002:5952,1112484619:5999,1112486150:6093,1112485713:6242,1094786004:6333,1112485502:6502,1094786048:6539,1112485508:6754,1112485984:6755,1094786067:6774,1112485786:6807,1112484686:6834,1112486060:6888,1112486127:7001,1094786101:7045,1112485834:7046,1112485934:7153,1112484633:7164,1112485923:7247,1112485958:7387,1094786161:7389,1112486045:7438,1112484789:7449,1112486163:7454,1112486108:7482,1112484575:7757,1112485819:8368,1112485688:8482,1112485781:8507,1094786027:8636,1112485493:8690,1112484795:8961,1112485629:31696,1112485748
2	3,974820889:62,974820598:70,974820691:110,974820658:242,974820776:260,974821014:266,974820748:469,974820598:480,974820720:541,974821014:589,974820658:891,974820969:908,974820691:924,974821014:1121,974820598:1196,974821014:1210,974820598:1214,974821014:1249,974820691:1259,974820659:1270,974821014:1327,974820846:1356,974820598:1544,974820943:1580,974820748:1673,974820776:1748,974821014:1965,974820720:1969,974820969:1970,974820969:1971,974820943:1972,974820969:1973,974820916:1974,974820598:1986,974820969:2291,974820748:2454,974820916:2455,974820720:2791,974820659:2858,974820659:2948,974820659:2951,974820598:3150,974820720:3159,974820598:3173,974820869:3450,974820846:3513,974820659:3534,974820889:3555,974820748:3565,974820776:3703,974821014:3753,974820691:3917,974820720:3918,974820943:3923,974820943:3926,974820889:3927,974820748:3928,974820776:3930,974820943:3937,974820916:3959,974820659

```

ちょっとごちゃごちゃしてるので、表にすると、

|user_id|movie_id,timestamp|movie_id,timestamp|movie_id,timestamp|・・・|
|-----------:|------------:|------------:|------------:|------------:|
|1|2,timestamp|29,timestamp|32,timestamp|・・・|
|2|3,timestamp|62,timestamp|70,timestamp|・・・|

という感じで、user1がmovie2,29,32を評価したみたいなデータになっているようです。  
<br>

次はダウンロードしたデータを、DSSTNEで読み取れる形式(NetCDF形式)に変換する。

```console
#NetCDF形式に変換してインプットデータを生成
generateNetCDF -d gl_input -i ml20m-all -o gl_input.nc -f features_input -s samples_input -c

#NetCDF形式に変換してアウトプットデータの生成
generateNetCDF -d gl_output -i ml20m-all -o gl_output.nc -f features_output -s samples_input -c
```

## 生成したデータを学習させる

```console
#dsstneの設定ファイルを取得
wget https://s3-us-west-2.amazonaws.com/amazon-dsstne-samples/configs/config.json.
```

config.jsonの中身は、こんな感じ。

![スクリーンショット 2016-05-24 午後4.29.37.png](https://qiita-image-store.s3.amazonaws.com/0/1418/b3fb9043-8d50-06b6-7186-ecfe1124a7f5.png "スクリーンショット 2016-05-24 午後4.29.37.png")

NNのパラメータや誤差関数、角層のノード数や活性化関数の設定などがJSON形式で記述されていて、ここがチューニングのしどころ。

設定可能なパラメータは以下に記載されているので参照しておきます。。

[config.jsonを調整する方法](https://github.com/amznlabs/amazon-dsstne/blob/master/docs/getting_started/userguide.md)


```console
#学習させてモデルを生成する
train -c config.json -i gl_input.nc -o gl_output.nc -n gl.nc -b 256 -e 10
```

trainのログはこんな感じ。
![スクリーンショット 2016-05-26 午前11.26.34.png](https://qiita-image-store.s3.amazonaws.com/0/1418/bbefc3fd-6eaf-7948-6625-74c54fd467ed.png "スクリーンショット 2016-05-26 午前11.26.34.png")


## 予測する
```console
#生成したモデルを元に予測をする
#user_id毎に10個のmoviesをレコメンドしてくれる
predict -b 1024 -d gl -i features_input -o features_output -k 10 -n gl.nc -f ml20m-all -s recs -r ml20m-all
```

predictのログはこんな感じ。
![スクリーンショット 2016-05-26 午前11.27.23.png](https://qiita-image-store.s3.amazonaws.com/0/1418/47afb087-6420-a90b-1e8e-901aeb65542d.png "スクリーンショット 2016-05-26 午前11.27.23.png")



生成されたrecsというファイルがoutputデータになります。

```console
#レコメンドデータを見てみる
more recs
```

データはこんな感じで表示されます。

![recs.png](https://qiita-image-store.s3.amazonaws.com/0/1418/96dc180e-ca5e-c8ef-39e4-7791cde3ae78.png "recs.png")

user_id	 movie_id,score:movie_id,score:…
という形で出力されて、scoreが高いものをレコメンドするイメージ。

## まとめ

- 大規模スパース(疎)行列データを使ってDeepLearningをしたいときには超絶便利なオープンソースだと思う。
- グラフデータや行列データを持つ場合にはかなり使えそう

## 次にやってみたいこと
- - config.jsonを色々いじってみたい
- 実際のサービスに組み込んで精度を確かめてみたい