DSSTNEを試してみた
DSSTNEとは
DSSTNEとは、Amazonが2016年5月12日に公開した深層学習向けライブラリです。
特徴として、Sparseなデータに対する最適化された高速な処理や、マルチGPUでのスケーリングなどが挙げられています。
g2.8xlargeの環境下において、Sparseなデータを対象に、Googleが提供するTensorFlowと比較して処理速度2.1倍という結果を残しています。
今回は、ドキュメントから実際にDSSTNEを試してみて見ようと思います。
DSSTNEのセットアップ
まずは、DSSTNEのセットアップを行ってみます。
DSSTNEのセットアップ方法は、以下の3つがドキュメントにまとめられています。
- Dockerを用いたセットアップ
- AWSを用いたセットアップ
- 開発マシンへのセットアップ
今回は、このうちAWSを用いた場合のセットアップ手順を試してみたいと思います。
インスタンスの準備
はじめに、DSSTNEを動かすためのEC2インスタンスを準備します。
今回は、米国東部リージョン(us-east1)にすでにDSSTNE向けAMIが準備されているようなので、こちらを利用することにします。
- ami-d6f2e6bc
このAMIを利用すると、DSSTNE自体はインストールされていませんが、必要な事前セットアップが完了しているという状態の環境を手に入れることができます。
ちなみに、DSSTNEを動かすためには以下のライブラリが必要となります。
- GCC : GCC compiler with C++11 is required.
- CuBLAS : Blas Libraries
- Cuda Toolkit >= 7.0 is required
- OpenMPI : CUDA aware OpenMPI is required.
- NetCDF : NetCDF is the native format which DSSTNE engine supports
- JsonCPP : Configurations are parsed through Json
- CUB : Dependent CUDA libraries which is required by DSSTNE
Prerequisites · amazon-dsstne/setup.md at master
AMIを利用せずに環境のセットアップを行う場合は、各ライブラリのセットアップ手順がまとめられています。
EC2インスタンス作成後は、sshでインスタンスにログインし、セットアップ作業を行います。
今回利用するAMIは、Amazon Linuxではなくubuntuの環境をベースにしているため、デフォルトのログインユーザもec2-user
ではなく、ubuntu
にする必要があります。
ssh -i .ssh/xxxx.pem ubuntu@<instance address>
DSSTNEのセットアップ
続いてDSSTNEのセットアップに移ります。
githubからDSSTNEのリポジトリを取得し、そのままビルドします。
# Ubuntu/Linux 64-bit git clone https://github.com/amznlabs/amazon-dsstne.git cd amazon-dsstne/src/amazon/dsstne # Add the mpiCC and nvcc compiler in the path export PATH=/usr/local/openmpi/bin:/usr/local/cuda/bin:$PATH make export PATH=`pwd`/bin:$PATH
Download the code and build - amazon-dsstne/setup.md
使ってみる
DSSTNEのSetupが完了したので、次は実際に動かしてみたいと思います。
DSSTNEのドキュメントでは、Exampleとして、MovieLensという映画のレビューサイトが公開しているDataset から、ユーザのレーティング情報をもとに映画の推薦モデルの構築を行っています。
このドキュメントの手順をもとに、実際に推薦モデルの作成までの流れを見ていきます。
データの準備
DSSTINEにおけるデータ形式について
DSSTNEは、NetCDFと呼ばれるフォーマットに従ったデータのみを入力として受け付けます。このため、学習データなどを作成する際には元データのフォーマットからNetCDFへと変換する必要があります。
NetCDFはバイナリベースのデータ形式なので直接作成することは難しいですが、DSTNNEでは定められたフォーマットのテキストデータからNetCDFへの変換を行うためのツールを提供しています。
フォーマットを整えたのちにこのツールを利用することで、テキストベースのデータからNetCDF形式のデータを手軽に作成することができます。
ドキュメントによると、以下の形式のテキストデータからNetCDF形式の入力データを作成することができます。ExampleとFeatureの間はTABで区切られ、Feature間は":"(セミコロン)で区切られる形となります。
Exampleは各レコードのindexにあたる部分で、実際には学習に用いられませんが、後述の出力データなど、複数のデータ間でレコードを結びつけるために必要な情報です。 Featureは、学習に用いられるNeural Networkの各入力ノード部分に対応し、Feature名の有無がそのまま対応するノードの入力の有無になります。
Example1 Feature1:Feature2:Feature3 Example2 Feature5:Feature2:Feature4 Example3 Feature6:Feature7:Feature8
ドキュメントには記載されていませんが、以下の形式でも入力を受け取ることは可能です。
Example1 Feature1,FeatureValue1:Feature2,FeatureValue2:Feature3,FeatureValue2 ...
issueによると、入力にアナログ値を含んだ場合のフォーマットも用意されていますが、DSSTNEのエンジン側が未対応のようです。
このフォーマットを利用した場合の挙動については詳しく触れていませんが、おそらく値は省略され、Featureのみのデータとして解釈されると思われます。
Examplesでのデータ変換手順
MovieLensのレーティング情報を元にNetCDFに変換可能な形式に整えられたデータがS3上に準備されているため、これを元にNetCDF形式のデータへと変換を行います。
提供されているデータの中身を覗いてみると、以下のようなデータが記述されています。
wget https://s3-us-west-2.amazonaws.com/amazon-dsstne-samples/data/ml20m-all head ml20m-all 1 2,1112486027:29,1112484676:32,1112484819:47,1112484727:... 2 3,974820889:62,974820598:70,974820691:110,776:3930,974820943:...
アナログ値を用いたデータフォーマットとなっていますが、各項目が何を示しているかはドキュメントにも詳しく書かれていないようです。
元データをあたったところ、rating.csv
から各ユーザ毎の映画のレーティング情報を取り出し、レーティングを行ったtimestampとともに出力しているようです。
user_id movie_id,timestamp:movie_id,timestamp:...
元となるrating.csv
には、そのほかにも評価の大きさを示すレート値が含まれていますが、今回の加工済みデータから除外されてます。
つまり、今回のデータでは、あるユーザに対してその映画にレーティングを行ったどうかだけを基準にデータをまとめているようです(なぜデータにTimestampを含めたのかについては不明ですが...)。
この元データをもとに、NetCDF形式のデータを作成します。
generateNetCDF -d gl_input -i ml20m-all -o gl_input.nc -f features_input -s samples_input -c generateNetCDF -d gl_output -i ml20m-all -o gl_output.nc -f features_output -s samples_input -c
同一のデータからNetCDF形式のデータを2つ作成していますが、これについてはモデル作成の際に、それぞれの役割を説明します。
モデルの作成
NetCDF形式のデータを作成できたら、それをもとにNeural Network(NN)モデルを作成していきます。
DSSTNEにおけるNNモデルの記述
DSSTNEでは、NNモデルの定義はJSON形式で記述します。
Exampleに記載されている内容を見てみると、このように定義が記述されています。
wget https://s3-us-west-2.amazonaws.com/amazon-dsstne-samples/configs/config.json. cat config.json { "Version" : 0.7, "Name" : "AE", "Kind" : "FeedForward", "SparsenessPenalty" : { "p" : 0.5, "beta" : 2.0 }, "ShuffleIndices" : false, "Denoising" : { "p" : 0.2 }, "ScaledMarginalCrossEntropy" : { "oneTarget" : 1.0, "zeroTarget" : 0.0, "oneScale" : 1.0, "zeroScale" : 1.0 }, "Layers" : [ { "Name" : "Input", "Kind" : "Input", "N" : "auto", "DataSet" : "gl_input", "Sparse" : true }, { "Name" : "Hidden", "Kind" : "Hidden", "Type" : "FullyConnected", "N" : 128, "Activation" : "Sigmoid", "Sparse" : true }, { "Name" : "Output", "Kind" : "Output", "Type" : "FullyConnected", "DataSet" : "gl_output", "N" : "auto", "Activation" : "Sigmoid", "Sparse" : true } ], "ErrorFunction" : "ScaledMarginalCrossEntropy" }
NNのパラメータや誤差関数、角層のノード数や活性化関数の設定などがJSON形式で記述されていることが分かります。
各項目についての詳細は以下にまとめられています。
- amazon-dsstne/userguide.md at master · amznlabs/amazon-dsstne
- amazon-dsstne/CDL.txt at master · amznlabs/amazon-dsstne
- amazon-dsstne/LDL.txt at master · amznlabs/amazon-dsstne
Examplesで利用するNNモデルについて
Examplesでは、Auto Encoderを用いたNNモデルを利用して、ユーザに映画を推薦するモデルを構築します。
Auto Encoderは、NNにおける次元圧縮の一手法であり、特徴として入力層と出力層で同じデータを用いて教師あり学習を行います。 基本的には3層構造のNNであり、中間にある隠れ層で圧縮されながら、入力と同じ出力を行わせるように学習が進みます。
データ作成時に入出力データを同じテキストデータから同一の形式で作成していたのは、Auto Encoderの学習では同じデータを入力信号と教師信号として利用するためです。
Auto Encoderを推薦モデルとして扱う手法については今回初めて聞いたのですが、おそらくこちらのことではないかと思います。
考え方としては、各ユーザの視聴履歴をAuto Encoderにかけることで、視聴傾向の近いユーザをまとめた結果が出力として得られ、その結果をマッチングの推論結果として利用するというもののようです。
このあたりについてはあまり詳しく調査できていないので、認識に間違いがあるかもしれません。
もし詳しい方がおりましたら、コメントにてご指摘いただけると大変助かります。
ExamplesでのNNモデル構築手順
実際にモデルを構築するための手順は、以下の流れになっています。
wget https://s3-us-west-2.amazonaws.com/amazon-dsstne-samples/configs/config.json train -c config.json -i gl_input.nc -o gl_output.nc -n gl.nc -b 256 -e 10
学習結果となる各ノードのパラメータは、gl.nc
に格納されており、これを利用して推薦結果を以下のように出力することができます。
predict -b 1024 -d gl -i features_input -o features_output -k 10 -n gl.nc -f ml20m-all -s recs -r ml20m-all
推薦結果はrecs
に以下のような形で格納されます。
$ head recs 1 1197,0.935:3793,0.896:2571,0.840:1206,0.814:551,0.810:2987,0.754:1347,0.723:1073,0.714:1274,0.714:608,0.690: 2 1200,0.423:1097,0.391:1240,0.380:356,0.311:780,0.293:2628,0.283:3471,0.252:32,0.251:1387,0.250:1206,0.250: 3 750,0.913:1371,0.887:2021,0.856:1580,0.831:1320,0.807:1253,0.800:608,0.780:527,0.763:1527,0.757:3471,0.757: 4 457,0.701:500,0.676:597,0.501:364,0.478:466,0.449:485,0.443:587,0.422:780,0.421:442,0.418:474,0.412: 5 356,0.971:1,0.896:539,0.867:527,0.834:597,0.831:586,0.812:34,0.668:733,0.647:357,0.614:592,0.580: 6 95,0.658:5,0.602:786,0.583:376,0.427:104,0.421:32,0.404:25,0.318:784,0.316:1356,0.311:36,0.309: 7 3471,0.908:2571,0.810:4022,0.810:2724,0.752:2997,0.712:1569,0.680:4025,0.680:1584,0.675:2369,0.654:1959,0.653: 8 586,0.717:420,0.650:225,0.633:315,0.617:474,0.612:410,0.610:440,0.571:160,0.551:736,0.549:318,0.507: 9 2858,0.308:3578,0.290:2762,0.278:3273,0.274:3005,0.218:2694,0.218:3617,0.208:3752,0.204:2541,0.195:3826,0.190: 10 110,0.748:1193,0.395:1233,0.359:1291,0.319:1214,0.301:1201,0.291:1234,0.255:1954,0.253:1262,0.248:920,0.234:
先頭の項目がユーザID, 各項目がMovie IDとその推薦スコアのペアになっていることが分かります。
項目数については、predict
のオプションで上位10件までにフィルタリングされています。
おわりに
DSSTNEのセットアップから実際にマッチング結果を取得するところまでを行いました。
リリースしたてということもあり、まだまだ機能にドキュメントがおいついていない印象ですが、今後に期待してチェックしていきたいと思います。