かれ4

かれこれ4個目のブログ

HiveでStringのArrayから、辞書順に並べて一番[最初|最後]のものを取り出す不細工な方法

辞書順に並べて最初のものを取り出す。

SELECT 
  REGEXP_REPLACE(
    CONCAT_WS('###',
      SORT_ARRAY(ARRAY("ag",
          "aa",
          "ab"))),
    "(.*?)###.*",
    "$1"
  );
aa

辞書順に並べて最後のものを取り出す。

SELECT 
  REGEXP_REPLACE(
    CONCAT_WS('###',
      SORT_ARRAY(ARRAY("ag",
          "aa",
          "ab"))),
    ".*###(.*)",
    "$1"
  );
ag

もっとかっこいい方法があるはず。

BrainScriptのデバッグ環境をDockerとmakeで整える

f:id:tottokug:20170302003757p:plain

MacではCognitive Toolkit (The Microsoft Cognitive Toolkit - Microsoft Research) (以下 cntk) をインストールすることが面倒だった。。。。

Intel MKL をMacにインストールするが大変なので、 以前からDockerを使ってcntkを動かすことにしていた

blog.tottokug.com

Dockerでcntkのコンテナを立ち上げておけば、そのコンテナ内で実行したりBrainScriptを編集する事は出来るけど、なんかいまいち効率が悪い気がする。

手元の環境でBrainScriptを編集して、 Containerで実行みたいな手軽にテストしていける環境が欲しかった。

普段はVisual Studio CodeでBrainScriptを書くことがおおいので、できればその中で完結させたかった。

そこで、Makefileでいい感じにBrainScript用とデータ用のVolume Containerを作り、データやBrainScriptのファイルをいれておき、 cntk実行用のContainerに2つのVolume Containerをマウントした状態で起動するというMakefileを作ってみた。

# cntkのdocker image
DOCKER_IMAGE := microsoft/cntk:1.7.2-runtime-cpu
# brainscriptをどこに置くか
SCRIPT_MOUNT_POINT := /var/cntk/scripts
# dataをどこに置くか
DATA_MOUNT_POINT := /var/cntk/data
# brainscript入りのVolume containerの名前、別で使っているところと衝突しないように
SCRIPT_VOLUME_CONTAINER := CNTKbrainscript000000
# data入りのVolume containerの名前、別で使っているところと衝突しないように
DATA_VOLUME_CONTAINER := CNTKdata000000

# brainscript directory
BS_DIR := $(CURDIR)/scripts
# data directory
DATA_DIR := $(CURDIR)/data

all: scriptvc 
  docker run --rm     --volumes-from ${SCRIPT_VOLUME_CONTAINER} --volumes-from ${DATA_VOLUME_CONTAINER} ${DOCKER_IMAGE} cntk configFile=${SCRIPT_MOUNT_POINT}/branddetect.cntk

shell: scriptvc
  docker run --rm -it --volumes-from ${SCRIPT_VOLUME_CONTAINER} --volumes-from ${DATA_VOLUME_CONTAINER} ${DOCKER_IMAGE} /bin/bash

scriptvc: datavc
  $(eval SCRIPT_VOLUME_EXISTS := $(shell docker ps -a --format={{.Names}} --filter=name=${SCRIPT_VOLUME_CONTAINER} | wc -l |awk '{print $1}'))
ifeq ($(SCRIPT_VOLUME_EXISTS),0)
   @echo "#========# create scripts volume #========#"
    docker create -v ${SCRIPT_MOUNT_POINT} --name ${SCRIPT_VOLUME_CONTAINER} busybox
else
   @echo "#========# already exists script volume #========#"
endif
    docker cp ${BS_DIR}/ ${SCRIPT_VOLUME_CONTAINER}:${SCRIPT_MOUNT_POINT}/

datavc:
  $(eval DATA_VOLUME_EXISTS := $(shell docker ps -a --format={{.Names}} --filter=name=$(DATA_VOLUME_CONTAINER) |wc -l |awk '{print $1}' ))
  $(info $(DATA_VOLUME_CONTAINER))
  $(info $(DATA_VOLUME_EXISTS))
ifeq ($(DATA_VOLUME_EXISTS),0)
    $(info #========# create data volume #========#)
    docker create -v ${DATA_MOUNT_POINT} --name ${DATA_VOLUME_CONTAINER} busybox
    docker cp -L ${DATA_DIR}/ ${DATA_VOLUME_CONTAINER}:${DATA_MOUNT_POINT}/
else
    $(info #========# already exists data volume #========#) 
endif

こんなMakefileを作っておけばVisual Studio CodeでIntegrated Terminalを開いておいて、 makeと打てばBrainScriptを手軽に動作させることが出来る。

f:id:tottokug:20170302002552p:plain こんな感じでVisual Stuio Code内だけで全て完結できて便利。

The Microsoft Cognitive Toolkitで、Machine Learning 界のHello World. MNISTを試す

準備編

環境の準備をして blog.tottokug.com

CNTKの使い方をざっくりと理解して blog.tottokug.com

確認編

cntkにはコマンドラインで使う方法と、python から使う方法などがありますが、 まずはコマンドラインで使う方法を試してみます。

cntkのコマンドが使える状況に

$ docker run -it --rm microsoft/cntk:1.7.2-cpu-only
root@9f0cb764ac5a:/cntk# cntk
-------------------------------------------------------------------
Build info:

        Built time: Oct  1 2016 21:16:06
        Last modified date: Sat Oct  1 21:14:58 2016
        Build type: release
        Build target: CPU-only
        With 1bit-SGD: no
        Math lib: mkl
        Build Branch: HEAD
        Build SHA1: d1ad5fcc9b71c9b6122623a2a0c3d126a64cbe94
        Built by philly on 9b019bb2e014
        Build Path: /home/philly/jenkins/workspace/CNTK-Build-Linux
-------------------------------------------------------------------
No command-line argument given.
-------------------------------------------------------------------
Usage: cntk configFile=yourConfigFile
For detailed information please consult the CNTK book
"An Introduction to Computational Networks and the Computational Network Toolkit"
-------------------------------------------------------------------

無事にcontainer上でcntkが使えています.

実践編

ここからはすべてコンテナ内での操作になります。

データのダウンロード

まずはMNIST用のデータを用意します。 データを用意するためのスクリプトgithubに上がっているので、それをダウンロードしてきます。

# cd /cntk/Examples/Image/MNIST/Data
# wget https://raw.githubusercontent.com/Microsoft/CNTK/master/Examples/Image/DataSets/MNIST/install_mnist.py
# wget https://raw.githubusercontent.com/Microsoft/CNTK/master/Examples/Image/DataSets/MNIST/mnist_utils.py 
# python install_mnist.py
〜略〜
# ll
total 127392
drwxr-xr-x. 1 1000 1000      4096 Dec 11 05:40 ./
drwxr-xr-x. 1 1000 1000      4096 Dec  8 23:21 ../
-rw-r--r--. 1 root root  18649443 Dec 11 05:40 Test-28x28_cntk_text.txt
-rw-r--r--. 1 root root 111735994 Dec 11 05:40 Train-28x28_cntk_text.txt
-rw-r--r--. 1 root root       637 Dec 11 05:39 install_mnist.py
-rw-r--r--. 2 1000 1000        20 Oct  1 23:28 labelsmap.txt
-rw-r--r--. 1 root root      2463 Dec 11 05:39 mnist_utils.py
-rw-r--r--. 1 root root      2982 Dec 11 05:39 mnist_utils.pyc

無事にデータのダウンロードが完了しました。

データのフォーマット

$ head -n 1 Train-28x28_cntk_text.txt
|labels 0 0 0 0 0 1 0 0 0 0 |features 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136 175 26 166 255 247 127 0 0 0 0 0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253 253 253 225 172 253 242 195 64 0 0 0 0 0 0 0 0 0 0 0 49 238 253 253 253 253 253 253 253 253 251 93 82 82 56 39 0 0 0 0 0 0 0 0 0 0 0 0 18 219 253 253 253 253 253 198 182 247 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 156 107 253 253 205 11 0 43 154 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 139 253 190 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 190 253 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 241 225 160 108 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 81 240 253 253 119 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 186 253 253 150 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 93 252 253 187 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 249 253 249 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 130 183 253 253 207 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39 148 229 253 253 253 250 182 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 114 221 253 253 253 253 201 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23 66 213 253 253 253 253 198 81 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 171 219 253 253 253 253 195 80 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 172 226 253 253 253 253 244 133 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 136 253 253 253 212 135 132 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

これが一行の内容で、labelsには10bitで0-1の数字が記録されている。(なんかもったいない)

下記の場合は左から6番目に1が付いているので(0,1,2,3,4,5)で5を表している。

|labels 0 0 0 0 0 1 0 0 0 0 |

featuresには28x28個の0-255の値が記載されたデータが入っている。 1行に並んで居ると見づらいので、数字28個毎に改行を入れてみる。

$ head -n 1  Train-28x28_cntk_text.txt |perl -pe "s/(.*?features )((\d+ ){28})/\1\n\2\n/g"
|labels 0 0 0 0 0 1 0 0 0 0 
|features 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136 175 26 166 255 247 127 0 0 0 0
0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253 253 253 225 172 253 242 195 64 0 0 0 0
0 0 0 0 0 0 0 49 238 253 253 253 253 253 253 253 253 251 93 82 82 56 39 0 0 0 0 0
0 0 0 0 0 0 0 18 219 253 253 253 253 253 198 182 247 241 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 80 156 107 253 253 205 11 0 43 154 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 139 253 190 2 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 11 190 253 70 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 35 241 225 160 108 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 81 240 253 253 119 25 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 186 253 253 150 27 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 93 252 253 187 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 249 253 249 64 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 130 183 253 253 207 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 39 148 229 253 253 253 250 182 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 24 114 221 253 253 253 253 201 78 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 23 66 213 253 253 253 253 198 81 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 18 171 219 253 253 253 253 195 80 9 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 55 172 226 253 253 253 253 244 133 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 136 253 253 253 212 135 132 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

改行を入れるとなんとなく5っぽいなというのも見える。

学習と検証

データ確認は済んだところで実際に学習と検証までをやってみます。

今回使用するのはContainerに最初から用意されているMNIST用の構成ファイル この構成ファイルはBrainScriptと呼ばれているようです。 '/cntk/Examples/Image/MNIST/Config/01_OneHidden.cntk'を利用します。 おそらくgithubにあるこれとほぼ同じものになると思います。

# cd /cntk/Examples/Image/MNIST/Config
# date ; cntk configFile=01_OneHidden.cntk ; date
Sun Dec 11 10:29:39 UTC 2016
CNTK 1.7.2 (HEAD d1ad5f, Oct  1 2016 21:16:06) on localhost at 2016/12/11 10:29:39

cntk  configFile=01_OneHidden.cntk
Redirecting stderr to file ../Output/01_OneHidden_bs_out
Sun Dec 11 10:31:31 UTC 2016

こちらMacbook Air上のParallelsで動かしているCoreOS上のDocker(とりあえず、そこまでいいスペックではない環境)で実行して だいたい 2分くらいで完了しました。

実行中にstderrの内容は../Output/01_OneHidden_bs_outに保存してあるからと言われているので、軽く見てみます。

# cat ../Output/01_OneHidden_bs_out
〜略〜

Minibatch[1-10]: errs = 1.880% * 10000; ce = 0.06162033 * 10000
Final Results: Minibatch[1-10]: errs = 1.880% * 10000; ce = 0.06162033 * 10000; perplexity = 1.06355847

なんだかしっかりとTestまで終わってますよ的な事が出ています。 てか、上記の検証結果のようにこれ標準出力に出してくれても良いんじゃないか? と思うような内容もstderrに出ていたので要注意です。

そして、肝心の学習したモデルはというと、 BrainScriptに書いてある

modelPath = "$outputDir$/Models/01_OneHidden"

に吐き出されているはずなので、見てみます。

# cd /cntk/Examples/Image/MNIST/Output/Models
# ls -la 01_OneHidden*
-rw-r--r--. 1 root root 638877 Dec 11 10:31 01_OneHidden
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.0
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.1
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.10
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.11
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.12
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.13
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.14
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.15
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.16
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.17
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.18
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.19
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.2
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.20
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.21
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.22
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.23
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.24
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.25
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.26
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.27
-rw-r--r--. 1 root root 638877 Dec 11 10:30 01_OneHidden.28
-rw-r--r--. 1 root root 638877 Dec 11 10:31 01_OneHidden.29
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.3
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.4
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.5
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.6
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.7
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.8
-rw-r--r--. 1 root root 638877 Dec 11 10:29 01_OneHidden.9
-rw-r--r--. 1 root root 636600 Dec 11 10:31 01_OneHidden.ckp

きちんとできていそうです。よかった。

ちなみにExampleについている 02_Convolution.cntkとか03_ConvBatchNorm.cntkについても どうようにできますが、cpu-onlyのイメージでは全然実行が終わりません。

参考までにdocker statsで見てみると

f:id:tottokug:20161211201231p:plain

CPUやばし、これはGPU積んでるマシンでやりましょう。

ここまでかMacbook Air

plotしてみる

Plot command · Microsoft/CNTK Wiki · GitHub ここにネットワークを描画出来るようなことが書いてあります。

This command loads a given computation network and describes the network topology (usually a DAG) using the DOT (http://www.graphviz.org/doc/info/lang.html) language. It can also optionally call a third-part tool (http://www.graphviz.org/Documentation/dotguide.pdf) to render the network topology. Note that many DOT rendering tools are optimized for DAG, and the rendered graph becomes quite messy if the network structure is non-DAG. The non-DAG structure is usually caused by the use of delay node. In this case, this command will treat all the delay nodes as leaf nodes.

描画にはgraphvizを使うようなのですが、 microsoft/cntk:1.7.2-cpu-only はUbuntu 14.04ベースで、 CNTKを動作させる環境は一通り入っては居るものの、graphbizは最初からインストールされていません。 なので、インストールします。

# apt-get update
# apt-get install  graphviz

そして、さっきの 01_OneHidden.cntkをコピーして編集します。

# cp 01_OneHidden{,_plot}.cntk
# vi 01_OneHidden_plot.cntk

commandの最後に:で区切ってtopoplotを追加して、 さらにtopoplotのブロックを追加します。

# command = trainNetwork:testNetwork 
command = trainNetwork:testNetwork:topoplot

# plot CONFIG
topoplot = [
    action = "plot"
    modelPath = "$modelPath$"

    # outputdotFile specifies the dot file to output
    # if the user does not specify this, it will be ${modelPath}.dot
    outputdotFile = "$outputDir$/Visualize/01_OneHidden.dot"

    # outputFile specifies the rendered image
    outputFile="$outputDir$/Visualize/01_OneHidden.jpg"

    # if RenderCmd is specified, CNTK will call the plot command after replacing
    # <IN> with ${outputdotFile} and <OUT> with ${outputfile}
    renderCmd="/usr/bin/dot -Tjpg <IN> -o<OUT>"
]

これで下記コマンドを実行すれば、/cntk/Examples/Image/MNIST/Output/Visualize には画像ファイルとdotファイルができているはずです。

# cntk configFile=01_OneHidden-plot.cntk
# ll /cntk/Examples/Image/MNIST/Output/Visualize/
drwxr-xr-x. 2 root root   4096 Dec 11 12:17 ./
drwxr-xr-x. 4 root root   4096 Dec 11 12:17 ../
-rw-r--r--. 1 root root   2182 Dec 11 12:17 01_OneHidden.dot
-rw-r--r--. 1 root root 130944 Dec 11 12:17 01_OneHidden.jpg

無事にできていました。

せっかくなので、手元に持ってきて表示してみます。

$ docker cp {containerID}:/cntk/Examples/Image/MNIST/Output/Visualize/01_OneHidden.jpg ./01_OneHidden.jpg
$ open 01_OneHidden.jpg

f:id:tottokug:20161211212033j:plain すごくシンプルな有向非巡回グラフが出てきました。 なんか可視化されると嬉しい。

さいごに

dockerを使った事によって、手軽に始めることができました。

MNISTを他の構成でもやってみたかったのですが、GPUがないためか全然終わらず、、、 やはりMacbook Airには荷が重かったという事で、諦めました。

BrainScriptについてはplotまでが定義できたりと、結構便利そうだなという印象です。

f:id:tottokug:20161211213044p:plain

Visual Studio CodeのExtensionはまだないようなので、今度時間あったら作ります。

というわけで、 CNTKの準備 から、ざっくり概念的な説明、使ってみるというところまでが終わりました。

次回は、実際にモデルを利用する事か、PythonからCNTKを使う事かのどちらかをしてみたいと思います。

CNTK usage overview

はじめに

このページはこのWikiの内容から何かがわかる気がしたので、翻訳+追記したものになります。 github.com

原文はNikos Karampatziakisによって2016年10月26日・27日に編集されました。


CNTKを使用するには、実行可能なバイナリをダウンロードするか、 ソースコードをダウンロードしてマシン上でコンパイルする必要があります。 (詳細)。

もしくは、Dockerを利用することができます。 blog.tottokug.com

この記事はDockerで動かしている環境で試してました。

CNTKでサポートされている主な3つのタスク

  • Train : トレーニングデータを使用して訓練されたモデルを作成するために、ネットワークを定義してトレーニングする
  • Evaluate : 訓練されたモデルをテストして、テストデータを使用してそのパフォーマンスを評価する
  • Deploy : 訓練されたモデルを使用します(例:独自のソリューションで新しいインスタンスを分類する

これらの各タスクの概要を以下に示し、より詳細な説明へのポインタを提供します。

CNTKは他にも - 既存のモデルの編集 - ノード出力のファイルへの書き込み などのタスクもサポートしています

これらの詳細は、「Advanced Topics」セクションの「Top-level commands」ページにあります。

CNTKを使用したモデルトレーニング

CNTKでニューラルネットワークをトレーニングするには、 3つのコンポーネントで構成する必要があります。

  • ネットワーク : ニューラルネットワークは、その構造/公式、モデルパラメータを含む。 トレーニング基準と評価基準もここに含まれています。
  • リーダー : トレーニングデータの読み方
  • SGD : 確率勾配プロセスのハイパーパラメータ

CNTK実行ファイルを呼び出すときの最初の引数として、 この情報を記述した構成ファイルを使用して指定する必要があります。

構成ファイルは独自の構文を使用します。 構成ファイルの詳細については、Config file overviewを参照してください。

CNTKの構成ファイル例 - MNIST

'01_OneHidden.cntk'

この構成ファイルを使いMNISTの例を示します。

詳細は Image/GettingStarted を参照してください。

この例のCNTKコマンドラインは、

$ cntk configFile=01_OneHidden.cntk

です。

次のスニペットは、トレーニングに関連する設定ファイルの内容の概要を示しています。

modelDir = "$OutputDir$/Models"
deviceId = 0
command = MNISTtrain

modelPath = "$modelDir$/01_OneHidden"

MNISTtrain = {
    action = "train"

    # network definition   
    BrainScriptNetworkBuilder = (new ComputationNetwork
        include "$ConfigDir$/01_OneHidden.bs"
    )

    # learner configuration       
    SGD = [
        ...
    ]

    # reader configuration   
    reader = [
        readerType = "CNTKTextFormatReader"
        file = "$DataDir$/Train-28x28_cntk_text.txt"
        ...
    ]    
}

command

上記のコードスニペットでは"MNISTtrain"として定義されたタスクを 実行するcommandであると定義されています。

いくつかのタスクを連続して実行することもできます。 例えばtrainとtestを行うには、 commandにコロン区切りで指定することができます。

例)
command = "MNISTtrain:testNetwork"

deviceId

deviceIdパラメータは、CPUまたはGPUのどちらを使用するかを指定します。 "auto"に設定すると、CNTKは利用可能なデバイスを選択します。 CPUを使用する場合は-1に設定し、特定のGPUを使用する場合は0以上の値に設定します。

modelPath

modelPathは、中間および最終訓練モデルを格納する場所を定義します。 この例では、構成ファイルの先頭に定義されたModelDir変数を使用しています。

MNISTtrain

commandで指定した文字列と同じ文字列のパラメータでは、 トレーニングに必要な3つのコンポーネントを定義します。

action = "train" トレーニングするactionであることが定義されています。 サポートされている他のactionには、"test""write"があります。

action = "train" のために最低限必要な3つの構成ブロックは、 ネットワーク(NetworkBuilder)、 トレーニングアルゴリズムのパラメータ(SGD)、 データリーダーのためのパラメータ(reader) になります。

  • NetworkBuilder

    レイヤーのサイズと数、 ノードのタイプなど、ネットワークのトポロジーと詳細を定義します。 標準モデルにはSimple Network Builderを、 カスタムモデルにはBrainScript Network Builderを使用できます。 詳細は対応するWikiページを参照してください。

    (@see Simple Network Builder, BrainScript Network Builder)

  • SGD確率的勾配降下

    このブロックでは、トレーニングアルゴリズムをパラメータ化できます。 設定可能なオプションには、運動量、適応学習率、適応ミニバットサイズ、並列訓練などがあります。 詳細については、SGDブロックを参照してください。

  • reader

    readerブロックは、使用するリーダーと、対応する入力ファイルの場所を定義します。 CNTKはさまざまなフォーマットとタスクのためにいくつかのデータリーダーを提供しています (readerブロックを参照)。

トレーニングされたモデルの評価

'01_OneHidden.cntk' の構成は、次のようになります。

訓練されたモデルの精度を評価するには、evalまたはtestコマンドを使用します(詳細は、Train、Test、Evalも参照してください)。

testNetwork = {
    action = "test"
    minibatchSize = 1024    # reduce this if you run out of memory

    reader = {
        readerType = "CNTKTextFormatReader"
        file = "$DataDir$/Test-28x28_cntk_text.txt"
        input = {
            features = { dim = 784 ; format = "dense" }
            labels =   { dim = 10  ; format = "dense" }
        }
    }
}

この例では、modelPathtestNetworkブロック内にはありません。 最上位に定義されています(例ではTest-28x28.txtを使用)。

実行するには構成ファイルのcommandを

command = testNetwork

とし実行します。

$ cntk configFile = 01_OneHidden.cntk

テストの結果は以下のように出力されます。

Final Results: Minibatch[1-625]: errs = 2.39% * 10000; ce = 0.076812531 * 10000; Perplexity = 1.0798396
COMPLETED!

1つの構成ファイルに複数のタスクも可(原文にはありません)

'01_OneHidden.cntk'

の例を見るとわかりますが、 1. trainNetworkというactionがtrainのタスク 1. testNetworkというactionがtestのタスク の2つが定義されています。

そしてcommandには trainNetwork:testNetworkとして、 trainNetworkとtestNetworkが順番に指定されています。 原文では何度か 下記のような記述が出てきましたが、Exampleとして用意されている01_OneHidden.cntk を使って実行するとトレーニングとテストのタスクが行われるようになっています。

$ cntk configFile = 01_OneHidden.cntk

CoreOSをディスクにインストールした時のcloud-configはいづこ?

/var/lib/coreos-install/user_data

coreos.com

coreosの設定を変えたい時は

# 設定の変更
$ sudo vi /var/lib/coreos-install/user_data
# 適用
$ sudo coreos-cloudinit -from-file=/var/lib/coreos-install/user_data

Docker for macを辞めたら、Docker Clientだけをスマートに入れる方法を見つけた。

Docker for macが出てから、しばらく使っていたけれど、 どうしてもディスクの喰い方がつらくて、Docker for macを卒業。

現在のローカルのDockerの環境は Parallels + CoreOS Stable channel + Docker client という構成に。 というか戻った。

paralllels + CoreOSのところは一旦置いておいて MacにDocker clientだけをスマートに入れる方法はないかと模索したところ toolboxのソースにあるDockerfile.osxにヒントが。

 36 RUN curl -fsSL -o dockerbins.tgz "https://get.docker.com/builds/Darwin/x86_64/docker-${DOCKER_VERSION}.tgz" && \
 37     tar xvf dockerbins.tgz docker/docker --strip-components 1 && \
 38     rm dockerbins.tgz
 39
 40 RUN chmod +x /docker

https://get.docker.com/builds/Darwin/x86_64/docker-${DOCKER_VERSION}.tgz

このURLさえあれば、動いたり動かなかったりするDocker toolboxのインストーラーにやきもきすることもなく、 Docker clientだけをMacにスマートに入れられる。

$ DOCKER_VERSION=1.11.2
$ wget https://get.docker.com/builds/Darwin/x86_64/docker-${DOCKER_VERSION}.tgz
$ tar zxf docker-${DOCKER_VERSION}.tgz
$ mv docker/docker /usr/local/bin/docker-${DOCKER_VERSION}
$ pushd /usr/local/bin/
$ chmod +x docker-${DOCKER_VERSION}
$ ln -s docker-${DOCKER_VERSION} docker

これでclientだけを入れる事ができた。 あとは環境変数のDOCKER_HOSTにtcp://${COREOS_HOST}:2375 とか入れておけばOK