はらぺこらいおん

日々、思ったことを。

AWSのEC2 P2スポットインスタンスにCUDA8.0とChainerをセットアップ

AWSでP2インスタンスがリリースされました!(結構前になりますが。。。)

Amazon EC2 P2 インスタンス| AWS

今までのG2インスタンスやElasticGPU(インスタンスにアタッチできるGPU)より、汎用的な計算に向いており、Tesla K80を搭載しているようです。

今回はp2.xlargeのスポットインスタンスを使ってみたいと思います。簡単に行いたい場合はオンデマンドインスタンスの方が良いです。オンデマンドインスタンスの場合、NVIDIA公式からドライバー等がセットアップされたAMI(OSのテンプレートみたいなもの)が提供されているためです。

それでもなぜスポットインスタンスを使うのかというと、価格が安いからです。以下に料金がありますが、P2インスタンスの中で一番小さいp2.xlargeで$0.9/1 時間(約100円/1時間)となります。バージニア北部リージョンの場合。ちなみに東京リージョンにはP2インスタンスはまだありません。(2017/1/31現在)

EC2 インスタンスの料金 – アマゾン ウェブ サービス (AWS)

対してスポットインスタンスはだいたい$0.1〜0.2/1時間(約10〜25円/1時間)となってます。たまに高くなっている時もありますが、安い時に使って、終了したら消してしまう機械学習には丁度いい感じがします。

f:id:pictzzz:20170131222806p:plain

今回はUbuntu14.04をOSとして選択しました。なので、以前ブログに載せた記事とほぼ同じ手順になります。

pictzzz.hatenablog.com

AWSセットアップ

P2インスタンスを使うためにはVPCを用意しておく必要があります。スポットインスタンス作成を行う道すがら必要な環境のセットアップ用リンクが用意されているのでそれを使って設定していきます。

まずAWSにログインすると以下のような画面が出るかと思います。

f:id:pictzzz:20170131225215p:plain

まずは右上のリージョンを確認します。P2インスタンスは一部リージョンにしかないため、P2インスタンスの起動できるリージョンを選択します。今回はバージニア北部を選択しました。

次にEC2のメニューへと進みます。画面のEC2か、左上のサービスからEC2を選択します。

f:id:pictzzz:20170131232004p:plain

EC2の画面の左側のメニューからスポットリクエストを選択します。

f:id:pictzzz:20170131232057p:plain

青いボタンのスポットインスタンスのリクエストを選択します。

f:id:pictzzz:20170131232215p:plain

そうするとスポットインスタンスの作成ウィザードが起動します。 ここで今回はAMIをUbuntu14.04に変更し、インスタンスタイプをp2.xlargeを選択します。

f:id:pictzzz:20170131232346p:plain

インスタンスタイプを選択する際に表示されるウィンドウの右上の価格設定履歴から過去のスポットインスタンスの価格が見れます。

f:id:pictzzz:20170131232444p:plain

ネットワークの選択でP2インスタンスは最初からあるEC2-Classicが選択できません。そのため、VPCを新しく作る必要があります。 ネットワークの右側にある新しいVPCの作成をクリックします。

f:id:pictzzz:20170131232833p:plain

クリックするとVPCの作成画面に移動します。VPCの作成をクリックします。

f:id:pictzzz:20170131232903p:plain

VPCは以下のように作りました。インスタンスを1つだけ作る場合、特にどのような設定でもOKだと思います。今回は10.0.0.0/24のネットワークにIPv6はなしとしました。

f:id:pictzzz:20170131233055p:plain

次にサブネットを作成します。VPCの画面の左側にサブネットのメニューがあるのでクリックします。

f:id:pictzzz:20170131233346p:plain

サブネットは以下のように作りました。先ほど作成したVPCに紐付けて10.0.0.0/28のネットワークに、アベイラビリティゾーン(AZ)はaとしました。どのAZを選択しても問題ありません。ただし、AZごとに需要に応じてスポットインスタンスの価格が違うので注意です。

f:id:pictzzz:20170131233440p:plain

AWSからインターネットに抜けるためにインターネットゲートウェイを作成します。サブネットの画面の左側にインターネットゲートウェイのメニューがあるのでクリックします。インターネットゲートウェイの作成をクリックします。

f:id:pictzzz:20170131234049p:plain

名前を適当に入力します。

f:id:pictzzz:20170131234120p:plain

作ったインターネットゲートウェイVPCを紐付けします。VPCにアタッチをクリックします。

f:id:pictzzz:20170131234156p:plain

紐付けるVPCを選択します。

f:id:pictzzz:20170131234210p:plain

状態がattachedになればOKです。

f:id:pictzzz:20170131234246p:plain

さらにルートテーブルも作っておきます。インターネットゲートウェイの画面の左側にルートテーブルのメニューがあるのでクリックします。先ほど作成したVPCに紐付いたルートテーブルがあるためこれにインターネット向きのルートを追加します。

f:id:pictzzz:20170131233713p:plain

ルートテーブルを選択し、下に表示される詳細のルートを選択します。その画面に表示される編集をクリックします。

f:id:pictzzz:20170131233828p:plain

送信先:0.0.0.0/0、ターゲット:先ほど作成したインターネットゲートウェイとして保存します。

f:id:pictzzz:20170131234332p:plain

ここまででEC2インスタンスを作成する環境の構築が完了です。スポットインスタンスの作成ウィザードへ戻ります。(別のウィンドウかタブで開いているはずです。

作成したVPCとサブネットを選択します。最後の最高価格はスポットインスタンスの価格が上昇しても払えると思える最大の金額になります。この金額はあくまで払おうと思っている最大値であって、この金額が請求されるわけではありません。が、スポットインスタンスの価格がこの価格を超えると、2分後にインスタンスが強制終了されます。

f:id:pictzzz:20170131234650p:plain

インスタンスにつけるボリュームを作成します。NVIDIAのドライバーやCUDAのインストールファイルが大きいので15GB以上はあった方がいいと思います。デフォルトの8GBだと確実に足りません。画像や動画の学習を行う場合、もっと容量はいると思います。もちろん、別途EBS(ディスク)を接続することもできます。

f:id:pictzzz:20170131234939p:plain

画面下部ではキーペアを選択します。ここで作成したキーを使ってインスタンスSSH接続します。キーペアを新しく作る場合は、右側の新しいキーペアの作成をクリックします。

f:id:pictzzz:20170131235854p:plain

キーペアの作成をクリックします。

f:id:pictzzz:20170201001733p:plain

キーペアの名前を適当に入力します。

f:id:pictzzz:20170201001800p:plain

作成が完了するとダウンロードされます。

f:id:pictzzz:20170201001910p:plain

スポットインスタンスの作成ウィザードへ戻ります。
一番下まで行き、確認をクリックします。その後、確認画面が出ますので、作成をクリックすると、スポットインスタンスのリクエストが作成されます。入力した金額をスポットインスタンスの価格が下回った場合、実際にインスタンスが作成されます。

画面左側のメニューからインスタンスの画面に移動します。作成されたスポットインスタンスはこの画面に表示されます。ステータスが2/2になったらアクセス可能です。

f:id:pictzzz:20170201000158p:plain

起動するまでに数分かかりますので、その間にEIP(グローバルIP)とセキュリティグループ(FWのようなもの)を作成しておきます。左側のメニューからElastic IPをクリックします。新しいアドレスの割り当てをクリックします。

f:id:pictzzz:20170201000344p:plain

スコープはVPCを選択します。

f:id:pictzzz:20170201000441p:plain

グローバルIPが割り当てられます。アクションのアドレスの関連付けをクリックします。

f:id:pictzzz:20170201000724p:plain

先ほど作成したインスタンスに紐付けます。

f:id:pictzzz:20170201001105p:plain

画面左側のメニューからセキュリティグループを選択します。作成したVPCに紐付いているセキュリティグループを選びます。下に詳細が出てくるので、インバウンドをクリックします。編集をクリックします。

f:id:pictzzz:20170201001223p:plain

SSH(22ポート)を送信元0.0.0.0(全て)で許可します。送信元が特定される場合は、ここでIPアドレスを入力して制限することをお勧めします。

f:id:pictzzz:20170201001403p:plain

ダウンロードしたキーを使ってSSH接続します。キーはホームディレクトリーの下のkeysディレクトリーに置いてあることを想定してます。

$ cd ~/keys
$ chmod 600 dnn-key.pem
$ ssh -i dnn-key.pem ubuntu@xxx.xxx.xxx.xxx

CUDAセットアップ

ここから作成したインスタンスにCUDAをセットアップします。
以下のURLからCUDAのセットアップファイルをダウンロードし、インストールします。

CUDA 8.0 Downloads | NVIDIA Developer

f:id:pictzzz:20170201002718p:plain

このファイルをダウンロードしました。

f:id:pictzzz:20170201003321p:plain

コマンドは最新のダウンロードURLを確かめてください。

wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run
mv cuda_8.0.44_linux-run cuda_8.0.44_linux.run
chmod +x cuda_8.0.44_linux.run

OSのアップデートとnouveau無効化を行います。

  • OSアップデート
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential git python-pip python-dev libxml2-dev libxslt1-dev zlib1g-dev libcurl4-openssl-dev libatlas-base-dev linux-image-extra-virtual libopencv-dev python-numpy
sudo apt-get autoremove
  • nouveau無効化
# sudo vi /etc/modprobe.d/blacklist-nouveau.conf

blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
# sudo vi /etc/modprobe.d/nouveau-kms.conf

options nouveau modeset=0
$ sudo update-initramfs -u
# sudo vi /etc/default/grub

# GRUB_CMDLINE_LINUX_DEFAULT=""  # ""の部分にtextを追加
GRUB_CMDLINE_LINUX_DEFAULT="text"
sudo reboot
$ sudo apt-get install linux-headers-`uname -r`

インストールしておかないと以下のようなエラーが出て、CUDAのインストールに失敗したのでインストールしておきます。

The driver installation is unable to locate the kernel source. Please make sure that the kernel source packages are installed and set up correctly.
If you know that the kernel source packages are installed and set up correctly, you may pass the location of the kernel source with the '--kernel-source-path' flag.

デフォルトでインストールします。ドライバーもインストールします。

./cuda_8.0.44_linux.run 

Do you accept the previously read EULA?
accept/decline/quit: accept

Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 367.48?
(y)es/(n)o/(q)uit: y

Do you want to install the OpenGL libraries?
(y)es/(n)o/(q)uit [ default is yes ]: 

Do you want to run nvidia-xconfig?
This will update the system X configuration file so that the NVIDIA X driver
is used. The pre-existing X configuration file will be backed up.
This option should not be used on systems that require a custom
X configuration, such as systems with multiple GPU vendors.
(y)es/(n)o/(q)uit [ default is no ]: 

Install the CUDA 8.0 Toolkit?
(y)es/(n)o/(q)uit: y

Enter Toolkit Location
 [ default is /usr/local/cuda-8.0 ]: 

Do you want to install a symbolic link at /usr/local/cuda?
(y)es/(n)o/(q)uit: y

Install the CUDA 8.0 Samples?
(y)es/(n)o/(q)uit: y

Enter CUDA Samples Location
 [ default is /home/ubuntu ]: 

以下のパスを環境変数に追加しておきます。

# vi .bashrc

export CUDA_PATH=/usr/local/cuda-8.0
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64
export PATH=$PATH:$CUDA_PATH/bin

export CFLAGS=-I$CUDA_PATH/include
export LDFLAGS=-L$CUDA_PATH/lib64

環境変数を追加後、以下のコマンドでGPUの情報が取得できるようになります。

$ source .bashrc
$ nvidia-smi
Tue Jan 31 13:10:52 2017       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 367.48                 Driver Version: 367.48                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 0000:00:1E.0     Off |                    0 |
| N/A   34C    P0    71W / 149W |      0MiB / 11439MiB |     99%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

f:id:pictzzz:20170201003418p:plain

こちらのURLから登録を行ってダウンロードしました。

NVIDIA cuDNN | NVIDIA Developer

ダウンロードしたファイルは以下のcuDNN v5.1 Library for Linuxです。ファイルはダウンロード後、scpでインスタンスにアップロードします。

f:id:pictzzz:20170201003547p:plain

ライブラリーディレクトリーにコピーします。

$ tar xfz cudnn-8.0-linux-x64-v5.1.tgz 
$ sudo cp cuda/include/cudnn.h $CUDA_PATH/include/
$ sudo cp cuda/lib64/* $CUDA_PATH/lib64/

Chainerセットアップ

最後にChainerをインストールします。Chainerはpipでインストールできます。今回はユーザーランドにインストールします。

pip install --user chainer -vvvv
$ pip freeze | grep chainer
chainer==1.20.0.1

最新バージョンがインストールされていることが確認できました!

セットアップは以上となります。お疲れさまでした!

Let’s enjoy deep learning life on AWS!

Kerasで2種類(クラス)への分類

前回と前々回にセットアップしたKerasを使って2種類の分類を行ってみたいと思います。

前回と前々回のセットアップ記事はこちらからどうぞ。

pictzzz.hatenablog.com

pictzzz.hatenablog.com

概要

入力に対して2種類の分類を行う用途は意外と多く、有用だと思います。 例えば、性別、年齢、居住地、母国語、といった属性データに対して、 ある製品を購入した、していないの分類や、 テレマーケティングの結果、購入してくれるか、してくれないか、明日の株価は上がるのか下がるのかといったことなどなど、 様々な用途に使えると思います。

使用データ

今回は仮想的に以下のような構造を持ったcsvから学習を行うことを考えてみます。 このデータはテレマーケティングを行ってみて、購入したかどうかの結果がデータに反映されています。

#train.csv

ID,名前,性別,居住地,年齢,預金残高,契約年数,累積通話時間,購入したか
1,太郎,男,東京,20,100000,1,3,0
2,花子,女,大阪,40,1000000,10,10,1
・
・
・

このようなデータが1万レコードほどあると想定してください。
最後の購入したかは0が購入しなかった、1が購入したとなります。

対して、テストしてみるファイルには購入したかが入っていません。 イメージとしてはこれからどの人に優先的にアプローチをかけていけば良いかを 判断したいと考えてください。

#test.csv

ID,名前,性別,居住地,年齢,預金残高,契約年数,累積通話時間
1,一郎,男,北海道,51,11300000,4,5
2,さくら,女,沖縄,43,131000000,14,12
・
・
・

使用するモデル

多層パーセプトロンMLP)とします。Kerasではplotを利用することでモデルを画像として保存することができます。

from keras.utils.visualize_util import plot

plot(model, to_file='model.png')

実際に保存されたモデルがこちらです。

f:id:pictzzz:20170126141022p:plain

Denseと書かれているレイヤーは全結合レイヤー(fully connected layer)となります。

各レイヤーのユニット数は以下のようにしてます。
53(input) -> 500 -> 1000 -> 50 -> 2(out)

レイヤーの数やユニット数はいろいろ変えてみて、試してください。

入力、出力のユニット数

出力

今回は購入した(True)か購入しなかった(False)かの判定ですので、出力のユニット数は2となります。 出力ユニットが[1, 0]の場合、購入した、[0, 1]の場合、購入しなかったと判断します。

入力

入力は入力ユニットにデータを1つ1つ入れていきます。 ユニット数が53になっているのは、one hotエンコーディングでデータを入力するためです。

例えば、性別は、データの中に男性、女性の2種類がありますが、このままの状態ですと ネットワークで扱いにくいため、one hotエンコーディングというものを行います。

One-hot - Wikipedia

これを適用すると以下のようなデータに変換できます。

男性 = 10
女性 = 01

同じように年月の月のデータがある場合は、以下のように変換できます。

"jan" =  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
"feb" =  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
"mar" =  [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
"apr" =  [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
"may" =  [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
"jun" =  [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
"jul" =  [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
"aug" =  [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
"sep" =  [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
"oct" =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
"nov" =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
"dec" =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

Kerasには自動でone hotエンコーディングを行ってくれる機能があります。 to_categoricalでone hotではないデータと分類するクラスの数(例えば月の場合は12)を指定すると、 one hotなデータを得られます。

from keras.utils import np_utils

nb_class = 12
one_hot_dataset = np_utils.to_categorical(not_one_hot_dataset, nb_classes)

その他テクニック

その他のテクニックとしては、正規化と中間値補完があります。

正規化では例えば預金残高が大きな数字になっていますのでこれを0〜1の間に収まるように、 入力データ全体の中で最大の預金残高で全ての預金残高の値を割ります。

中間値補完では例えば年齢の入力データの中に年齢が入っていない人がいる場合、 データを代表するような値(例えば、中間値)で代替することを行います。

データの前処理で用意するデータ

以上のような処理を行い、以下の5つのデータを準備します。

  • 学習用入力データ
  • 学習用教師データ
  • テスト用入力データ
  • テスト用教師データ
  • 新しい入力データ

学習用入力データと教師データ、テスト用入力データと教師データは対になっている必要があります。
学習用とテスト用のデータは同じ形式のものですが、学習で使ったデータと同じものでネットワークを評価してしまうと、 未知のデータに対する精度がわからないため、学習用データから一部を学習に使わずにテストに使う用として、 予め別に保持しておきます。 Kerasの場合は、テスト用データは別に準備しなくても学習用データの 一部を自動でテスト用データとして扱うことができます。 新しい入力データは、学習に使わず、答えが未知のデータとなります。このデータに対して、予測を行います。

モデルの作成

モデルは上に記載したように、いくつかレイヤーを重ねたものとしています。 Kerasでは簡単にモデルを変更することができます。

今回のモデルは以下のように記述します。

from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation

model = Sequential()

model.add(Dense(500, input_shape=(53,)))
model.add(Activation('sigmoid'))
model.add(Dropout(0.2))

model.add(Dense(1000))
model.add(Activation('sigmoid'))
model.add(Dropout(0.2))

model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dropout(0.2))

model.add(Dense(2))
model.add(Activation('softmax'))

活性化関数にはsigmoidとsoftmaxを使っています。 ドロップアウトには0.2を指定しています。ドロップアウトは指定された確率で各ユニットが無効になり、 ネットワークは無効になった以外のユニットだけで予測をする必要が出てきます。 これにより過学習という特定のデータに対して強く適合したネットワークになることを緩和できると言われています。

モデルを定義したらコンパイルを行います。今回は2つのユニットに出力を行うので損失関数にcategorical_crossentropyを指定します。 もし、1つのユニットに出力を行う場合は、binary_crossentropyを指定します。

最適化アルゴリズムにはadamを指定しました。 その他のアルゴリズムもKerasには定義されています。 詳しくは下記の公式URLを参照してみてください。 最適化 - Keras Documentation

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

学習

学習にあたり、過学習を防ぐ意味でも、アーリーストップを設定することができます。 アーリーストップは値が収束した時点で学習をストップするものになります。

from keras.callbacks import EarlyStopping

early_stopping = EarlyStopping(monitor='val_loss', patience=2)

Kerasの学習は以下のようにして行います。

hist = model.fit(x_train, y_train,
                 batch_size=batch_size,
                 verbose=1,
                 nb_epoch=nb_epoch,
                 validation_split=0.1,
                 callbacks=[early_stopping])

指定しているパラメーターの意味は以下のようになります。

  • x_train:学習データ
  • y_train:学習データの教師データ
  • batch_size:バッチサイズ(*)
  • verbose:ログ出力をプログレスバーで行う(0:出力なし、2:ログ出力)
  • nb_epoch:エポック数(全ての学習データに対するイテレーション数)
  • validation_split:学習データの中で検証に使うデータの割合
  • callbacks:学習中に行う処理のリスト(今回はアーリーストップを指定)

(*)バッチサイズ:複数のデータの誤差をまとめて、1回で更新を行う、ミニバッチ法の設定値になります。

評価

学習した結果の評価にはevaluateを使用します。

score = model.evaluate(x_test, y_test)

print('Test loss:', score[0])
print('Test accuracy:', score[1])

このように指定することでモデルの精度と誤差関数の値を出力することができます。

モデルの保存

学習済みのモデルの保存は以下のようにsaveを使います。

model.save('mlp_model.h5')

学習済みのモデルをロードする際には、load_modelを使います。

from keras.models import load_model

model = load_model('mlp_model.h5')
model.summary()

学習データの活用

学習したモデルに対して予測を行うにはpredictを使います。

y = model.predict(x)

print(y)

predictにはnumpy arrayで複数のデータを渡して、一度に予測することができます。

今回のモデルではpredictの出力は2つあり、[1, 0]が購入した(True)を示しているので、 y[i][0]がi番目の人が購入する確率を示すことになります。

i,y[0]
1,0.6803011298
2,0.6074721813
3,0.0003010118
4,0.0002940704
5,0.0291656982
6,0.0007526643
7,0.0005948166
8,0.0001619863

真理値で知りたい場合はroundで四捨五入を行うことで0 or 1の結果を得ることができます。

Ubuntu14.04にKeras with Tensorflow(GPU)をインストール

pictzzz.hatenablog.com

こちらの記事でMacbook ProにKerasをインストールしてみましたが、 あまりディープでないCNNでも学習が終わらず、 GPUの乗っているUbuntu14.04にKerasをインストールしてみました。

Ubuntu14.04にGPU(CUDA、cuDNN)をセットアップする方法は以下の記事に書きました。 グラボはGeForce GTX 660(2GB)です。

pictzzz.hatenablog.com

セットアップ

Tensorflow

GPUを使うためには、以下の環境変数をインストール前に登録しておく必要があります。

# ~/.bashrc

export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-0.12.1-cp27-none-linux_x86_64.whl
export CUDA_HOME=/usr/local/cuda

登録後は以下のコマンドで環境変数を読み込みます。

$ source ~/.bashrc

インストールmacにインストールした時と同様に pip コマンドでインストールします。

$ pip install tensorflow

scipyインストール

scipyはKerasをインストールすると自動で入るはずですが、 Kerasのインストールでscipyがこけているようだったので、別途インストールしました。 同様にnumpyでこける方もいるようです。

scipyのインストールは以下のコマンドで行います。

$ apt-get install python-scipy

matplotlibインストール

plot用に必要となるmatplotlibですが、こちらもmacと同様にpipでインストールします。 事前に必要となるpydotとgraphvizもインストールしておきます。

$ pip install pydot_ng
$ apt-get install graphviz
$ pip install matplotlib

Kerasインストール

最後にKerasをインストールします。

$ pip install keras

テスト

Tensorflow

以下のようにimportをして正常にインストールされているか確認します。

$ python
>>> import tensorflow as tf

これを実行してみてエラーが出なければOKです。

Keras

macの時と同様に、こちらのMNISTのサンプルプログラムを実行してみます。

keras/mnist_mlp.py at master · fchollet/keras · GitHub

ダウンロードしてtest.pyとして保存します。(名前はなんでも良いです。)

$ python test.py
Using TensorFlow backend.
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.so locally
60000 train samples
10000 test samples
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
dense_1 (Dense)                  (None, 512)           401920      dense_input_1[0][0]              
____________________________________________________________________________________________________
activation_1 (Activation)        (None, 512)           0           dense_1[0][0]                    
____________________________________________________________________________________________________
dropout_1 (Dropout)              (None, 512)           0           activation_1[0][0]               
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 512)           262656      dropout_1[0][0]                  
____________________________________________________________________________________________________
activation_2 (Activation)        (None, 512)           0           dense_2[0][0]                    
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None, 512)           0           activation_2[0][0]               
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 10)            5130        dropout_2[0][0]                  
____________________________________________________________________________________________________
activation_3 (Activation)        (None, 10)            0           dense_3[0][0]                    
====================================================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
____________________________________________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties: 
name: GeForce GTX 660
major: 3 minor: 0 memoryClockRate (GHz) 1.0975
pciBusID 0000:01:00.0
Total memory: 1.95GiB
Free memory: 1.67GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 660, pci bus id: 0000:01:00.0)
60000/60000 [==============================] - 3s - loss: 0.2434 - acc: 0.9248 - val_loss: 0.1119 - val_acc: 0.9637
Epoch 2/20
60000/60000 [==============================] - 3s - loss: 0.1015 - acc: 0.9694 - val_loss: 0.0801 - val_acc: 0.9748
Epoch 3/20
60000/60000 [==============================] - 3s - loss: 0.0746 - acc: 0.9776 - val_loss: 0.0874 - val_acc: 0.9740
Epoch 4/20
60000/60000 [==============================] - 3s - loss: 0.0581 - acc: 0.9825 - val_loss: 0.1001 - val_acc: 0.9729
Epoch 5/20
60000/60000 [==============================] - 3s - loss: 0.0510 - acc: 0.9844 - val_loss: 0.0951 - val_acc: 0.9771
Epoch 6/20
60000/60000 [==============================] - 3s - loss: 0.0442 - acc: 0.9868 - val_loss: 0.0874 - val_acc: 0.9792
Epoch 7/20
60000/60000 [==============================] - 2s - loss: 0.0366 - acc: 0.9882 - val_loss: 0.0887 - val_acc: 0.9793
Epoch 8/20
60000/60000 [==============================] - 3s - loss: 0.0341 - acc: 0.9897 - val_loss: 0.0916 - val_acc: 0.9801
Epoch 9/20
60000/60000 [==============================] - 3s - loss: 0.0327 - acc: 0.9907 - val_loss: 0.0840 - val_acc: 0.9826
Epoch 10/20
60000/60000 [==============================] - 3s - loss: 0.0288 - acc: 0.9913 - val_loss: 0.0884 - val_acc: 0.9833
Epoch 11/20
60000/60000 [==============================] - 3s - loss: 0.0258 - acc: 0.9927 - val_loss: 0.0876 - val_acc: 0.9844
Epoch 12/20
60000/60000 [==============================] - 3s - loss: 0.0247 - acc: 0.9928 - val_loss: 0.0984 - val_acc: 0.9822
Epoch 13/20
60000/60000 [==============================] - 3s - loss: 0.0244 - acc: 0.9934 - val_loss: 0.0949 - val_acc: 0.9836
Epoch 14/20
60000/60000 [==============================] - 3s - loss: 0.0222 - acc: 0.9939 - val_loss: 0.0959 - val_acc: 0.9837
Epoch 15/20
60000/60000 [==============================] - 3s - loss: 0.0210 - acc: 0.9940 - val_loss: 0.0892 - val_acc: 0.9835
Epoch 16/20
60000/60000 [==============================] - 2s - loss: 0.0192 - acc: 0.9947 - val_loss: 0.0953 - val_acc: 0.9834
Epoch 17/20
60000/60000 [==============================] - 3s - loss: 0.0191 - acc: 0.9948 - val_loss: 0.1119 - val_acc: 0.9840
Epoch 18/20
60000/60000 [==============================] - 3s - loss: 0.0216 - acc: 0.9944 - val_loss: 0.1086 - val_acc: 0.9830
Epoch 19/20
60000/60000 [==============================] - 3s - loss: 0.0179 - acc: 0.9952 - val_loss: 0.1180 - val_acc: 0.9829
Epoch 20/20
60000/60000 [==============================] - 3s - loss: 0.0200 - acc: 0.9949 - val_loss: 0.1069 - val_acc: 0.9842
Test score: 0.106886059585
Test accuracy: 0.9842

macだと20epochで200秒くらいで終わりましたが、 GPUでは60秒くらいに短縮できました。

Macbook ProにKeras with Tensorflowをセットアップ

Keras良くない?って話を聞くことが多くなってきたので、KerasをMacbook Proにインストールして試してみたいと思います。 もちろんMBPなので、GPUなしです。 KerasはTensorflowかTheanoの上で動作するニューラルネットワークライブラリだそうです。

Keras Documentation

公式に日本語のドキュメントもあり、セットアップでつまづくことはあまりないかと思います。

セットアップ

Tensorflowインストール

まずは、Tensorflowをインストールします。

Installing TensorFlow  |  TensorFlow

私のmacにはanacondaでpythonが入っているのでそのままpipでインストールします。

$ pip install tensorflow

以上でインストールは終了です。

Tensorflowの環境に入るには以下のコマンドを実行します。

$ source activate tensorflow

環境から抜ける場合は、以下のコマンドを実行します。

$ source deactivate

Kerasインストール

こちらもpipでインストールできます。

$ pip install keras

Kerasバックエンド変更

バックエンドの変更は不要になりました。デフォルトでTensorflowが動作します。

Kerasのバックエンドで動作するライブラリーを変更します。

# ~/.keras/keras.json

"backend": "tensorflow"

このように書き換えます。

その他ライブラリーインストール

これ以外にも必要なライブラリーをインストールします。

  • h5 モデルを保存する際に使います。
$ pip install h5py
  • matplotlib 学習結果などを描画する際に使います。
$ brew install graphviz
$ pip install pydot_ng
$ pip install matplotlib

このようなエラーが出る場合は、下記の記事を参照。

RuntimeError: Python is not installed as a framework

Python 3.3でmatplitlibとpylabを使おうとしたら RuntimeError: Python is not installed as a frameworkというエラーが発生したときの解決方法 - Qiita

テスト

Tensorflow

以下のようにimportをして正常にインストールされているか確認します。

$ python
>>> import tensorflow as tf

これを実行してみてエラーが出なければOKです。

Keras

こちらのMNISTのサンプルプログラムを実行してみます。

keras/mnist_mlp.py at master · fchollet/keras · GitHub

ダウンロードしてtest.pyとして保存します。(名前はなんでも良いです。)

$ python test.py
Using TensorFlow backend.
60000 train samples
10000 test samples
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
dense_1 (Dense)                  (None, 512)           401920      dense_input_1[0][0]              
____________________________________________________________________________________________________
activation_1 (Activation)        (None, 512)           0           dense_1[0][0]                    
____________________________________________________________________________________________________
dropout_1 (Dropout)              (None, 512)           0           activation_1[0][0]               
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 512)           262656      dropout_1[0][0]                  
____________________________________________________________________________________________________
activation_2 (Activation)        (None, 512)           0           dense_2[0][0]                    
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None, 512)           0           activation_2[0][0]               
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 10)            5130        dropout_2[0][0]                  
____________________________________________________________________________________________________
activation_3 (Activation)        (None, 10)            0           dense_3[0][0]                    
====================================================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
____________________________________________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 10s - loss: 0.2447 - acc: 0.9237 - val_loss: 0.1253 - val_acc: 0.9611
Epoch 2/20
60000/60000 [==============================] - 10s - loss: 0.1027 - acc: 0.9694 - val_loss: 0.0799 - val_acc: 0.9739
Epoch 3/20
60000/60000 [==============================] - 11s - loss: 0.0751 - acc: 0.9774 - val_loss: 0.0729 - val_acc: 0.9783
Epoch 4/20
60000/60000 [==============================] - 10s - loss: 0.0615 - acc: 0.9815 - val_loss: 0.0852 - val_acc: 0.9761
Epoch 5/20
60000/60000 [==============================] - 10s - loss: 0.0514 - acc: 0.9846 - val_loss: 0.0847 - val_acc: 0.9800
Epoch 6/20
60000/60000 [==============================] - 9s - loss: 0.0457 - acc: 0.9861 - val_loss: 0.0866 - val_acc: 0.9791
Epoch 7/20
60000/60000 [==============================] - 9s - loss: 0.0398 - acc: 0.9881 - val_loss: 0.0778 - val_acc: 0.9810
Epoch 8/20
60000/60000 [==============================] - 9s - loss: 0.0351 - acc: 0.9897 - val_loss: 0.0853 - val_acc: 0.9821
Epoch 9/20
60000/60000 [==============================] - 9s - loss: 0.0327 - acc: 0.9905 - val_loss: 0.0933 - val_acc: 0.9796
Epoch 10/20
60000/60000 [==============================] - 9s - loss: 0.0283 - acc: 0.9914 - val_loss: 0.0911 - val_acc: 0.9822
Epoch 11/20
60000/60000 [==============================] - 9s - loss: 0.0285 - acc: 0.9920 - val_loss: 0.1031 - val_acc: 0.9829
Epoch 12/20
60000/60000 [==============================] - 9s - loss: 0.0241 - acc: 0.9931 - val_loss: 0.0992 - val_acc: 0.9814
Epoch 13/20
60000/60000 [==============================] - 9s - loss: 0.0250 - acc: 0.9931 - val_loss: 0.1169 - val_acc: 0.9797
Epoch 14/20
60000/60000 [==============================] - 10s - loss: 0.0233 - acc: 0.9936 - val_loss: 0.1019 - val_acc: 0.9819
Epoch 15/20
60000/60000 [==============================] - 11s - loss: 0.0184 - acc: 0.9945 - val_loss: 0.0945 - val_acc: 0.9830
Epoch 16/20
60000/60000 [==============================] - 10s - loss: 0.0188 - acc: 0.9947 - val_loss: 0.1066 - val_acc: 0.9818
Epoch 17/20
60000/60000 [==============================] - 10s - loss: 0.0188 - acc: 0.9946 - val_loss: 0.1090 - val_acc: 0.9846
Epoch 18/20
60000/60000 [==============================] - 10s - loss: 0.0193 - acc: 0.9953 - val_loss: 0.1127 - val_acc: 0.9820
Epoch 19/20
60000/60000 [==============================] - 9s - loss: 0.0176 - acc: 0.9951 - val_loss: 0.1204 - val_acc: 0.9823
Epoch 20/20
60000/60000 [==============================] - 9s - loss: 0.0162 - acc: 0.9957 - val_loss: 0.1248 - val_acc: 0.9829
Test score: 0.124780163151
Test accuracy: 0.9829

MBP(core i7 @2.8GHz)だと20epochで200秒くらいで終わります。

Ubuntu14.04にChainer、CUDA8.0の環境を構築

Ubuntu14.04にChainerとCUDAの環境を構築したのでその記録を残しときます。 環境構築で手間取り2日くらいかかってしまいました。

まずWindows10でやってみましたが、途中挫折。その後、CentOS7でやってみて、また挫折。 以下は、最後にUbuntuに挑戦してみた結果です。

環境

OS構築

Ubuntuを通常通りインストールします。
文字化けが嫌なので英語環境をインストールしました。

ドライバー、ライブラリー ダウンロード

起動後、FirefoxNVIDIAの公式サイトより以下のファイルをダウンロードしておきます。

  • グラフィックボードドライバー(NVIDIA-LINUX-x86_64-375.26.run)
  • cuda toolkit(cuda_8.0.44_linux.run)
  • cuDNN(cudnn-8.0-linux-x64-v5.1.tgz)

ツールインストール

先にコンパイラーなどを入れておきます。

$ sudo apt-get install build-essential

nouveau無効化

NVIDIAのドライバーと競合するので、 デフォルトで入っているGPUドライバーを無効化します。

# sudo vi /etc/modprobe.d/blacklist-nouveau.conf

blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
# sudo vi /etc/modprobe.d/nouveau-kms.conf

options nouveau modeset=0
$ sudo update-initramfs -u

CUIでOS起動

CUIで起動するためgrubを書き換えます

# sudo vi /etc/default/grub

# GRUB_CMDLINE_LINUX_DEFAULT="splash quiet" # 削除
GRUB_CMDLINE_LINUX_DEFAULT="text" # 追加

grub更新後、再起動します。

$ sudo update-grub

GPUドライバーインストール

以下、ディレクトリー名は適宜読み替えてください。 終了後、再起動します。

$ cd Downloads
$ chmod +x ./NVIDIA-Linux-x86_64-<version>.run
$ sudo ./NVIDIA-Linux-x86_64-<version>.run
$ sudo reboot

CUDA toolkitインストール

こちらも終了後、再起動します。
インストールしていると、ドライバーのバージョンがダメですのでインストールしますか?と言われたので、ドライバーもインストールしました。

$ cd Downloads
$ chmod +x ../cuda_<version>_linux.run
$ sudo ./cuda_<version>_linux.run
$ sudo reboot

cuDNNインストール

ダウンロードしたファイルを解凍して、CUDAインストールディレクトリーにコピーします。

$ tar xvf cudnn-8.0-linux-x64-<version>.tgz
$ sudo cp cuda/include/* /usr/local/cuda-8.0/include
$ sudo cp cuda/lib64/* /usr/local/cuda-8.0/lib64

環境変数追加

環境変数を追加します。

# ~/.bashrc

export CUDA_PATH=/usr/local/cuda-8.0
export PATH=$CUDA_PATH/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_PATH/lib64:$LD_LIBRARY_PATH

export CPATH=$CUDA_PATH/include:$CPATH
export LIBRARY_PATH=$CUDA_PATH/lib64:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$CUDA_PATH/lib64:$LD_LIBRARY_PATH

export CFLAGS=-I/usr/local/cuda-8.0/include
export LDFLAGS=-L/usr/local/cuda-8.0/lib64

完了後、再読み込みします。

$ source ~/.bashrc

pipインストール

普通にapt-getでインストールします。

$ sudo apt-get install python-pip

Chainerインストール

デバッグ情報まで表示できるようにvvvvをつけます。また、キャッシュを読み込んで変な動作をしても嫌なのでno-cacheをつけておきます。

$ pip install chainer --no-cache -vvvv

エラー

Chainerのインストールで以下のエラーが出ました。

Python.hがない

No such file or directory
#include "Python.h"

とのことでした。

$ sudo apt-get install python-dev

これをインストールすると動きました。

GPUテスト

サンプルのMNISTを実行してみます。

$ sudo apt-get install git
$ cd
$ git clone htttps://github.com/pfnet/chainer
$ cd chainer/examples/mnist
$ python train_mnist.py -g 0

結果

CPUでは約15分ほどかかっていましたが、GPUでは約75秒で完了しました。速い!

その他(無関係)

コーディングなどは別のPCで行いたいのでsshをインストールして、ファイル等のやり取りをできるようにします。

$ sudo apt-get install ssh

また、Permission Deniedで怒られるのが嫌なので通常はrootで作業できるようにします。Ubuntuはrootでログインできないので、以下のようにしてrootアカウントにパスワードを設定します。

$ sudo su -
$ passwd
[root password]
[re-type root password]
$ exit
$ su
[root password]

セキュリティ上、sshの設定は別途行う必要があります。
また、通常の用途では、rootはログインしないようにしておいて、必要な場合のみ、sudoでコマンド実行する方が良いです。

ただ、今回は、オフラインでサーバーを使っていくので、利便性をとりました。

2016年 買ってよかったもの 買わなくてよかったもの

Amazonの購入履歴を見ると2016年に561件の注文がありました。 日に1件以上購入している計算になります。(ヤマトさんいつもありがとうございます。)

もちろん全てが全て届く物ではなく、Kindle電子書籍も多数含まれております。

その中で買ってよかったと思う物と、買わなくてよかった物をピックアップしてご紹介したいと思います。 個人の見解ですので、全ての人に当てはまるわけではありません。

買ってよかった物

小型ドローン

面白すぎでした!ドローン自体が初だったのですが、面白すぎて大きいドローンをすぐに買ってしまいました。この小型ドローン自体は2日で壊れましたが、価格が手頃でドローンを体験するにはいいと思います。

USBケーブル

長さの違う2本が入っていて便利です。ケーブル部分も編み込み状になっててオシャレです。iPhone版もあります。

フェイスシェーバー

顔の産毛が予想以上にスムーズに剃れます。気持ちいです。

茶筒

江東堂高橋製作所 茶筒生地缶 平缶150g

江東堂高橋製作所 茶筒生地缶 平缶150g

作りがしっかりしていてスーッと閉まるのに感動します。ルピシアのお茶50gがちょうどいい感じで入ります。

VRメガネ

コンテンツがまだまだないので、これからに期待ですが、Google公式のいろいろな場所を旅行出来るアプリなど面白いです。

ティーメーカー

HARIO (ハリオ) ワンカップティーメーカー 200ml ブラック OTM-1B

HARIO (ハリオ) ワンカップティーメーカー 200ml ブラック OTM-1B

ちょうど一杯分のお茶を簡単にいれることができます。3つ買ってしまいました。

買わなくてよかった物

ルンバ

タイムセールで安くなっててつられて買ってしまいましたが、 冬になってコタツを出すとルンバの活動できるところがなくなり、めっきり使わなくなりました。 春になったらまた再始動させます。

Wii U

スプラトゥーンを2、3日やってお蔵入り。

まとめ

大きい買い物をするのが下手な自分。

PythonでRaspberry PiのI2C通信

PythonRaspberry PiのI2C通信を行った際のメモになります。

I2Cツールインストール

sudo apt-get install i2c-tools

I2Cディバイス接続確認

sudo i2cdetect -y 1

SMBusインストール

sudo apt-get install python-smbus