AWSのEC2 P2スポットインスタンスにCUDA8.0とChainerをセットアップ
AWSでP2インスタンスがリリースされました!(結構前になりますが。。。)
今までの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時間)となってます。たまに高くなっている時もありますが、安い時に使って、終了したら消してしまう機械学習には丁度いい感じがします。
今回はUbuntu14.04をOSとして選択しました。なので、以前ブログに載せた記事とほぼ同じ手順になります。
AWSセットアップ
P2インスタンスを使うためにはVPCを用意しておく必要があります。スポットインスタンス作成を行う道すがら必要な環境のセットアップ用リンクが用意されているのでそれを使って設定していきます。
まずAWSにログインすると以下のような画面が出るかと思います。
まずは右上のリージョンを確認します。P2インスタンスは一部リージョンにしかないため、P2インスタンスの起動できるリージョンを選択します。今回はバージニア北部を選択しました。
次にEC2のメニューへと進みます。画面のEC2か、左上のサービスからEC2を選択します。
EC2の画面の左側のメニューからスポットリクエストを選択します。
青いボタンのスポットインスタンスのリクエストを選択します。
そうするとスポットインスタンスの作成ウィザードが起動します。 ここで今回はAMIをUbuntu14.04に変更し、インスタンスタイプをp2.xlargeを選択します。
インスタンスタイプを選択する際に表示されるウィンドウの右上の価格設定履歴から過去のスポットインスタンスの価格が見れます。
ネットワークの選択でP2インスタンスは最初からあるEC2-Classicが選択できません。そのため、VPCを新しく作る必要があります。 ネットワークの右側にある新しいVPCの作成をクリックします。
クリックするとVPCの作成画面に移動します。VPCの作成をクリックします。
VPCは以下のように作りました。インスタンスを1つだけ作る場合、特にどのような設定でもOKだと思います。今回は10.0.0.0/24のネットワークにIPv6はなしとしました。
次にサブネットを作成します。VPCの画面の左側にサブネットのメニューがあるのでクリックします。
サブネットは以下のように作りました。先ほど作成したVPCに紐付けて10.0.0.0/28のネットワークに、アベイラビリティゾーン(AZ)はaとしました。どのAZを選択しても問題ありません。ただし、AZごとに需要に応じてスポットインスタンスの価格が違うので注意です。
AWSからインターネットに抜けるためにインターネットゲートウェイを作成します。サブネットの画面の左側にインターネットゲートウェイのメニューがあるのでクリックします。インターネットゲートウェイの作成をクリックします。
名前を適当に入力します。
作ったインターネットゲートウェイとVPCを紐付けします。VPCにアタッチをクリックします。
紐付けるVPCを選択します。
状態がattachedになればOKです。
さらにルートテーブルも作っておきます。インターネットゲートウェイの画面の左側にルートテーブルのメニューがあるのでクリックします。先ほど作成したVPCに紐付いたルートテーブルがあるためこれにインターネット向きのルートを追加します。
ルートテーブルを選択し、下に表示される詳細のルートを選択します。その画面に表示される編集をクリックします。
送信先:0.0.0.0/0、ターゲット:先ほど作成したインターネットゲートウェイとして保存します。
ここまででEC2インスタンスを作成する環境の構築が完了です。スポットインスタンスの作成ウィザードへ戻ります。(別のウィンドウかタブで開いているはずです。
作成したVPCとサブネットを選択します。最後の最高価格はスポットインスタンスの価格が上昇しても払えると思える最大の金額になります。この金額はあくまで払おうと思っている最大値であって、この金額が請求されるわけではありません。が、スポットインスタンスの価格がこの価格を超えると、2分後にインスタンスが強制終了されます。
インスタンスにつけるボリュームを作成します。NVIDIAのドライバーやCUDAのインストールファイルが大きいので15GB以上はあった方がいいと思います。デフォルトの8GBだと確実に足りません。画像や動画の学習を行う場合、もっと容量はいると思います。もちろん、別途EBS(ディスク)を接続することもできます。
画面下部ではキーペアを選択します。ここで作成したキーを使ってインスタンスにSSH接続します。キーペアを新しく作る場合は、右側の新しいキーペアの作成をクリックします。
キーペアの作成をクリックします。
キーペアの名前を適当に入力します。
作成が完了するとダウンロードされます。
スポットインスタンスの作成ウィザードへ戻ります。
一番下まで行き、確認をクリックします。その後、確認画面が出ますので、作成をクリックすると、スポットインスタンスのリクエストが作成されます。入力した金額をスポットインスタンスの価格が下回った場合、実際にインスタンスが作成されます。
画面左側のメニューからインスタンスの画面に移動します。作成されたスポットインスタンスはこの画面に表示されます。ステータスが2/2になったらアクセス可能です。
起動するまでに数分かかりますので、その間にEIP(グローバルIP)とセキュリティグループ(FWのようなもの)を作成しておきます。左側のメニューからElastic IPをクリックします。新しいアドレスの割り当てをクリックします。
スコープはVPCを選択します。
グローバルIPが割り当てられます。アクションのアドレスの関連付けをクリックします。
先ほど作成したインスタンスに紐付けます。
画面左側のメニューからセキュリティグループを選択します。作成したVPCに紐付いているセキュリティグループを選びます。下に詳細が出てくるので、インバウンドをクリックします。編集をクリックします。
SSH(22ポート)を送信元0.0.0.0(全て)で許可します。送信元が特定される場合は、ここでIPアドレスを入力して制限することをお勧めします。
ダウンロードしたキーを使って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
このファイルをダウンロードしました。
コマンドは最新のダウンロード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
- CUDAインストール
$ 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 | +-----------------------------------------------------------------------------+
- cuDNNインストール
こちらのURLから登録を行ってダウンロードしました。
NVIDIA cuDNN | NVIDIA Developer
ダウンロードしたファイルは以下のcuDNN v5.1 Library for Linuxです。ファイルはダウンロード後、scpでインスタンスにアップロードします。
ライブラリーディレクトリーにコピーします。
$ 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種類の分類を行ってみたいと思います。
前回と前々回のセットアップ記事はこちらからどうぞ。
概要
入力に対して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')
実際に保存されたモデルがこちらです。
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エンコーディングというものを行います。
これを適用すると以下のようなデータに変換できます。
男性 = 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)をインストール
こちらの記事でMacbook ProにKerasをインストールしてみましたが、 あまりディープでないCNNでも学習が終わらず、 GPUの乗っているUbuntu14.04にKerasをインストールしてみました。
Ubuntu14.04にGPU(CUDA、cuDNN)をセットアップする方法は以下の記事に書きました。 グラボはGeForce GTX 660(2GB)です。
セットアップ
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
Macbook ProにKeras with Tensorflowをセットアップ
Keras良くない?って話を聞くことが多くなってきたので、KerasをMacbook Proにインストールして試してみたいと思います。 もちろんMBPなので、GPUなしです。 KerasはTensorflowかTheanoの上で動作するニューラルネットワークライブラリだそうです。
公式に日本語のドキュメントもあり、セットアップでつまづくことはあまりないかと思います。
セットアップ
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
テスト
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構築
- ドライバー、ライブラリー ダウンロード
- ツールインストール
- nouveau無効化
- CUIでOS起動
- GPUドライバーインストール
- CUDA toolkitインストール
- cuDNNインストール
- 環境変数追加
- pipインストール
- Chainerインストール
- エラー
- GPUテスト
- 結果
- その他(無関係)
環境
OS構築
Ubuntuを通常通りインストールします。
文字化けが嫌なので英語環境をインストールしました。
ドライバー、ライブラリー ダウンロード
起動後、FirefoxでNVIDIAの公式サイトより以下のファイルをダウンロードしておきます。
- グラフィックボードドライバー(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起動
# 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ケーブル
cheero Fabric braided USB Cable with micro USB 2本セット 50cm + 100cm
- 出版社/メーカー: cheero
- メディア: エレクトロニクス
- この商品を含むブログを見る
長さの違う2本が入っていて便利です。ケーブル部分も編み込み状になっててオシャレです。iPhone版もあります。
フェイスシェーバー
パナソニック フェイスシェーバー フェリエ 白 ES-WF60-W
- 出版社/メーカー: パナソニック(Panasonic)
- 発売日: 2014/04/21
- メディア: ホーム&キッチン
- この商品を含むブログを見る
顔の産毛が予想以上にスムーズに剃れます。気持ちいです。
茶筒
- 出版社/メーカー: 江東堂高橋製作所
- メディア: ホーム&キッチン
- この商品を含むブログを見る
作りがしっかりしていてスーッと閉まるのに感動します。ルピシアのお茶50gがちょうどいい感じで入ります。
VRメガネ
Hqing VRメガネ 3D スマホ ゲーム 映画 ビデオ ゴーグル 超3D映像効果 仮想現実 頭部装着 4?6インチのAndroidやIOSスマホ適用 G-VR002 (黒 二代)
- 出版社/メーカー: 【Hqing】
- メディア: エレクトロニクス
- この商品を含むブログを見る
コンテンツがまだまだないので、これからに期待ですが、Google公式のいろいろな場所を旅行出来るアプリなど面白いです。
ティーメーカー
HARIO (ハリオ) ワンカップティーメーカー 200ml ブラック OTM-1B
- 出版社/メーカー: ハリオ
- メディア: ホーム&キッチン
- 購入: 16人 クリック: 84回
- この商品を含むブログ (16件) を見る
ちょうど一杯分のお茶を簡単にいれることができます。3つ買ってしまいました。
買わなくてよかった物
ルンバ
iRobot Roomba 自動掃除機ルンバ870 ピューターグレー 870 【日本仕様正規品】
- 出版社/メーカー: iRobot (アイロボット)
- メディア: その他
- この商品を含むブログを見る
タイムセールで安くなっててつられて買ってしまいましたが、 冬になってコタツを出すとルンバの活動できるところがなくなり、めっきり使わなくなりました。 春になったらまた再始動させます。
Wii U
- 出版社/メーカー: 任天堂
- 発売日: 2015/09/10
- メディア: Video Game
- この商品を含むブログ (12件) を見る
スプラトゥーンを2、3日やってお蔵入り。
まとめ
大きい買い物をするのが下手な自分。
PythonでRaspberry PiのI2C通信
PythonでRaspberry PiのI2C通信を行った際のメモになります。
I2Cツールインストール
sudo apt-get install i2c-tools
I2Cディバイス接続確認
sudo i2cdetect -y 1
SMBusインストール
sudo apt-get install python-smbus