こんにちは。技術研究所の鍋です。

 

最近、機械学習の分野に触れ始めました。

機械学習用のフレームワークは近年いろいろなところから出ていますが、せっかくなので弊研究所では使ったことがないものを使ってみようということで、Microsoft Cognitive Toolkit(通称:CNTK)を導入して、サンプルコードが動くところまで確認しました。

基本的には公式の手順に沿っていますが、個人的に飲み込むのに時間がかかった部分もあったので覚書として残しておきます。

※Step~ は公式の手順に対応しています。

その1.Linux編

導入環境

今回はAWS上にGPUインスタンスを立てることにしました。

  • インスタンスタイプ
    • g2.2xlarge
  • OS
    • Ubuntu 16.04.2 LTS
  • 導入ソフトウェア
    • CUDA8.0
    • cuDNN6.2
  • ※ちなみに、最初からCNTKを含むいくつかのDeepLearnigフレームワークが入っているAMIもあるようですが、導入難度の調査も兼ねているので今回は自分で入れました。使うだけならそちらで事足りるかもしれません。

    Step1 導入対象の選定・ダウンロード

    CNTKには、プログラムから使うためのライブラリと、単独実行するための実行ファイルが用意されています。

    実行ファイル(BrainScriptと呼ぶらしい)を使えるようにしておくと、プログラムを実際に作りこまなくとも定義ファイルだけで学習・評価をさせることができるようです。

    便利そうなので、今回は両方入れることにします。

    公式からLinux > Script-driven installationを選択して、リンクを辿って行ってリリースページからパッケージをダウンロードしようとしたところ、LinuxのGPU向けらしいパッケージが2種類ありました。

    • CNTK for Linux v.2.0 GPU
    • CNTK for Linux v.2.0 GPU with 1bit-SGD

    調べてみたところ、1bit-SGDとは、複数のGPUもしくはサーバーで並列処理をしているときに、通信コストを下げてパフォーマンスを向上させるオプションらしいということがわかりました。(原理はよくわからず。。。)

    ※ただし、こちらを使う場合は通常とはライセンス形態が異なるようなので要注意です。

    今回はとりあえず普通?のCNTK for Linux v.2.0 GPUを使えばよさそうです。

    ダウンロードが終わったら、scp等でAWSインスタンス上に配置し、以下のコマンドで展開します。

    tar -xzvf CNTK-2-0-Linux-64bit-GPU.tar.gz

    Step2 インストールスクリプト実行

    あとは手順の通り、Step1で展開したものの中にあるスクリプトを使ってインストールします。

    実行時にPythonのバージョンを指定すればAnacondaまで自動で入れてくれます。

    Pythonを別途導入する必要はありません。便利ですねぇ。

    # パスは上記tar.gzを展開したディレクトリからの相対パスで記載しています(以降のコマンドも同じ)
    # 各自の環境に合わせてください
    ./cntk/Scripts/install/linux/install-cntk.sh --py-version 36 --anaconda-basepath /usr/local/anaconda3

    しばらく待って、「CNTK install complete.」というメッセージが出力されればインストール完了です。

    公式では次はGPUの最新ドライバを導入しろとなっていますが、今回の本筋とはズレるので割愛します。

    Step3 Pythonライブラリ導入結果確認

    ダウンロードしたパッケージの中にチュートリアル用の環境とPythonモジュールが用意されていますので、そちらを使って導入結果を確認していきます。

    # まず環境をactivate
    source ./cntk/activate-cntk
    # Tutorialの下にある、FeedForwardNet.pyを起動します。
    python ./cntk/Tutorials/NumpyInterop/FeedForwardNet.py

    以下のような出力がされれば、PythonからCNTKを利用することができています。

    Learning rate per minibatch: 0.5
    Minibatch[ 1- 128]: loss = 0.582338 * 3200, metric = 28.19% * 3200;
    Minibatch[ 129- 256]: loss = 0.312840 * 3200, metric = 12.34% * 3200;
    Minibatch[ 257- 384]: loss = 0.291944 * 3200, metric = 11.28% * 3200;
    Minibatch[ 385- 512]: loss = 0.266468 * 3200, metric = 10.28% * 3200;
    Minibatch[ 513- 640]: loss = 0.249985 * 3200, metric = 8.91% * 3200;
    Minibatch[ 641- 768]: loss = 0.232742 * 3200, metric = 8.94% * 3200;
    Minibatch[ 769- 896]: loss = 0.230655 * 3200, metric = 8.59% * 3200;
    Minibatch[ 897-1024]: loss = 0.215014 * 3200, metric = 8.25% * 3200;
    Finished Epoch[1]: loss = 0.297748 * 25600, metric = 12.10% * 25600 2.110s (12132.7 samples/s);
    error rate on an unseen minibatch 0.040000

    Step4 BrainScript導入結果確認

    今度はPythonから呼び出すのではなく、CNTKの実行モジュールを実行してみます。

    こちらもテスト用の定義ファイルが用意されていますので、それを使って実行してみましょう。

    # この定義ファイル(lr_bs.cntk)では、学習したモデルをカレントディレクトリ直下に生成しようするので、
    # 定義ファイルと同じディレクトリへ移動
    cd ./cntk/Tutorials/HelloWorld-LogisticRegression/
    # CNTK実行
    cntk configfile=./lr_bs.cntk makeMode=false command=Train

    こちらも、以下のような表示がされればうまく動いています。

    ##############################################################################
    # #
    # Train command (train action) #
    # #
    ##############################################################################
    Model has 9 nodes. Using CPU.
    Training criterion: lr = Logistic
    Evaluation criterion: err = SquareError
    Training 3 parameters in 2 parameter tensors.
    Finished Epoch[ 1 of 50]: [Training] lr = 0.31759283 * 1000; err = 0.09908522 * 1000; totalSamplesSeen = 1000; learningRatePerSample = 0.039999999; epochTime=0.453629sFinished Epoch[ 2 of 50]: [Training] lr = 0.11039351 * 1000; err = 0.02357974 * 1000; totalSamplesSeen = 2000; learningRatePerSample = 0.039999999; epochTime=0.0120032s
    ~中略~
    Finished Epoch[49 of 50]: [Training] lr = 0.04173198 * 1000; err = 0.01124937 * 1000; totalSamplesSeen = 49000; learningRatePerSample = 0.039999999; epochTime=0.0209203s
    Finished Epoch[50 of 50]: [Training] lr = 0.04399340 * 1000; err = 0.01202173 * 1000; totalSamplesSeen = 50000; learningRatePerSample = 0.039999999; epochTime=0.0193613s
    COMPLETED.

    ただし、

    Model has 9 nodes. Using CPU.

    という表示の通り、このままだとせっかくのGPUが使えていません。

    使用するデバイスをオプションで指定してあげる必要がありますが、今回はautoで実行してみます。

    cntk configfile=./lr_bs.cntk makeMode=false command=Train deviceId=auto

    すると、以下のように結果が変わりました。

    ##############################################################################
    # #
    # Train command (train action) #
    # #
    ##############################################################################
    Model has 9 nodes. Using GPU 0.

    これで、GPUを有効にさせることができました。

    その2.Windows編

    MicrosoftなのでWindowsとも相性がいいだろう(たぶん)ということで、WindowsのローカルPCにも導入してみました。

    PCのスペックは「最新とはいかないけれども、普通に使う分には困らない程度」という感じです。

    とはいえ機械学習のようなリソースを大量に必要とする処理に無理をして使う必要もないので、あくまでお試し導入という位置づけです。

    導入環境

    • OS:Windows10 Enterprise x64
    • GPUなし
    • Anaconda3導入済み

    Step1 導入対象の選定・ダウンロード

    Windows版も、Linux版同様にライブラリと実行モジュールが用意されていますが、これまた同様に両方導入しておくことにします。

    公式からWindows > Scripted Installを選択し、リリースページから自分の環境にあったパッケージをダウンロードします。私の環境では、GPUがないのでCPU-Onlyを選択しました。

    Step2 インストールスクリプト実行

    Step1でダウンロードしたzipを任意のパスに展開したら、手順に従ってコマンドプロンプトからbatを実行します。

    ここで注意点がひとつ。そのまま素直にbatを起動すると、C:\localにAnaconda3をインストールして、Python3.5用の環境を作ろうとします。

    今回はAnaconda3はインストール済みですし、Python3.6で環境を作りたいので以下のオプションを追加しました。

    # Anaconda3のインストール済パスが C:\ProgramData\Anaconda3 の場合の例
    # 既存のパスを指定すると導入済みとしてAnacondaの導入をスキップしてるようです
    install.bat -AnacondaBasePath C:\ProgramData\Anaconda3 -PyVersion 36

    途中で各種プログラムのインストール確認の画面が何度かでますが、「はい」を連打して進めていきます。

    「CNTK v2 Python install complete.」というメッセージが出力されたらWindows版も導入完了です。

    Step3 GPUドライバ更新

    GPUは乗っていないので省略!!

    Step4 Pythonライブラリ導入確認

    Linux版同様、サンプルが用意されていますのでそれを起動してみます。

    Step2でインストールが正常に行われていれば、cntk-pyXX(XXはPythonバージョン)という環境ができているはずですのでその環境をactivateして使いましょう。

    # 環境をactivate
    # 公式だとbatを実行するように言われていますが、やっていることは同じです
    activate cntk-py36
    # 展開したzipのTutorials配下のFeedForwardNet.pyを実行
    python .\cntk\Tutorials\NumpyInterop\FeedForwardNet.py

    以下のような表示がされればOKです。

    Learning rate per minibatch: 0.5
    Minibatch[ 1- 128]: loss = 0.582338 * 3200, metric = 28.19% * 3200;
    Minibatch[ 129- 256]: loss = 0.312840 * 3200, metric = 12.34% * 3200;
    Minibatch[ 257- 384]: loss = 0.291944 * 3200, metric = 11.28% * 3200;
    Minibatch[ 385- 512]: loss = 0.266468 * 3200, metric = 10.28% * 3200;
    Minibatch[ 513- 640]: loss = 0.249985 * 3200, metric = 8.91% * 3200;
    Minibatch[ 641- 768]: loss = 0.232742 * 3200, metric = 8.94% * 3200;
    Minibatch[ 769- 896]: loss = 0.230655 * 3200, metric = 8.59% * 3200;
    Minibatch[ 897-1024]: loss = 0.215014 * 3200, metric = 8.25% * 3200;
    Finished Epoch[1]: loss = 0.297748 * 25600, metric = 12.10% * 25600 2.124s (12052.7 samples/s);
    error rate on an unseen minibatch 0.040000

    (Linux版とおんなじことを書いているような・・・)

    Step5 BrainScript導入確認

    用意済みの定義ファイルを使って(以下略)

    cd .\cntk\Tutorials\HelloWorld-LogisticRegression\
    cntk configfile=lr_bs.cntk makemode=false command=Train

    以下の表示がされれば(以下略)

    ##############################################################################
    # #
    # Train command (train action) #
    # #
    ##############################################################################
    Model has 9 nodes. Using CPU.
    Training criterion: lr = Logistic
    Evaluation criterion: err = SquareError
    Training 3 parameters in 2 parameter tensors.
    Finished Epoch[ 1 of 50]: [Training] lr = 0.31759286 * 1000; err = 0.09908522 * 1000; totalSamplesSeen = 1000; learningRatePerSample = 0.039999999; epochTime=0.218899s
    Finished Epoch[ 2 of 50]: [Training] lr = 0.11039351 * 1000; err = 0.02357974 * 1000; totalSamplesSeen = 2000; learningRatePerSample = 0.039999999; epochTime=0.0689561s
    ~中略~
    Finished Epoch[49 of 50]: [Training] lr = 0.04173198 * 1000; err = 0.01124937 * 1000; totalSamplesSeen = 49000; learningRatePerSample = 0.039999999; epochTime=0.0557148s
    Finished Epoch[50 of 50]: [Training] lr = 0.04399340 * 1000; err = 0.01202173 * 1000; totalSamplesSeen = 50000; learningRatePerSample = 0.039999999; epochTime=0.0626549s
    COMPLETED.

    まとめ

    というわけで、導入から簡単な動作確認まで一通りやってみましたが、ここまではあまりハードルは高くないかなという印象です。

    今回は導入スクリプトを使い、足りないものは自動的にDLしてくれましたが、オフライン環境で導入するにはもう少し工夫が必要そうです。

    (必要なライブラリ等をあらかじめ導入したうえでスクリプトを叩けばいけるのか、あるいはマニュアルインストールをする必要があるのか、、、)

    機会と時間があれば、そちらも試してみようかと思います。