It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

Kerasの環境をMacに構築する

最近、今更ながら機械学習の勉強をしてみようと思い、色々調べていました。
僕は行列計算などの高校数学もほとんどわからないのですが、最近はPythonでのエコシステムがかなり充実してきているようで、頑張れば簡単なもの位は作れるようになるかなと思い、1から勉強しようと思っています。

まずは、Macに環境構築するところから始めます。 機械学習のライブラリとしては、Google製のTensorFlowが有名(僕が知らないだけですが..)ですが、色々みていると、ChainerKerasというのが最近の人気のようです。

Chainerは、日本製とのことで日本語の資料が充実しているらしいのですが、今回はKerasを使ってみます。 理由は、GoogleのTensorFlowをバックエンドに使えるということもあり、今後も成熟が期待できそうだからです。

環境構築の方法は、TensorFlowの公式ページなど色々みてみましたが、Dockerを使ったクリーンな環境構築なども推奨されているようです。

ですが、僕自身Dockerの知識がそこまで豊富でないため、Docker周りのトラブルが出ても面倒なのでとりあえず普通にMacにインストールしてみたいと思います。

Pythonのバージョン管理ツールをインストー

brew install pyenv
brew install pyenv-virtualenv
  • まずはPythonのインストールから行います
  • homebrewを使ってインストールします

パスを通す&初期設定

PYENV_ROOT=~/.pyenv
export PATH=$PATH:$PYENV_ROOT/bin
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
  • .bashrc.zshrcにpyenvのパスを通します

Pythonのバージョンインストー

pyenv install anaconda3-4.3.1

virtualenvで環境を作る

conda create -n keras python=3.6.1 anaconda

※ 追記 一番はじめは以下のようにpyenv-virtualenvで環境を作っていましたが、コンソールを切り替えた時などに上手く環境が切り替えられずcondaコマンドを使った方法に変更しました

pyenv virtualenv anaconda3-4.3.1 keras

ローカル環境用のディレクトリを作成する

mkdir keras
cd keras
  • keras用の作業環境を作成するためディレクトリを切ります

ローカル環境を切り替える

pyenv local anaconda3-4.3.1/envs/keras
  • keras用の環境設定をローカル環境として設定します

Tenserflowをインストー

pip install tensorflow

kerasをインストー

pip install keras

その他必要なモジュール

pip install h5py
  • 学習後の結果を保存するためのファイル(h5形式)を扱うライブラリ

設定ファイル

mkdir ~/.keras
echo '{"epsilon": 1e-07, "floatx": "float32", "backend": "tensorflow"}' >> ~/.keras/keras.json
  • backendをtensorflowにするための設定ファイルを作成します。
    • ※ tensorflowがインストールされている状態だとデフォルトでtenserflowになっているようなので必要ないかも

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

動作確認

試しにsampleソースを動かしてみます。

kerasでは、幾つかのサンプルソースが提供されています。

その中でも機械学習チュートリアルでもよく出てくるMNISTという手書き数字を認識するためのサンプルを動かしてみました。

https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py

'''Trains a simple deep NN on the MNIST dataset.
Gets to 98.40% test accuracy after 20 epochs
(there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a K520 GPU.
'''

from __future__ import print_function

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop


batch_size = 128
num_classes = 10
epochs = 20

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

model.summary()

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

history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

このソースを実行します

python mnist_mlp.py

以下が結果です。

Using TensorFlow backend.
60000 train samples
10000 test samples
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 512)               401920
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
2017-06-22 12:47:14.203012: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed
up CPU computations.
2017-06-22 12:47:14.203031: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up
CPU computations.
2017-06-22 12:47:14.203037: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
2017-06-22 12:47:14.203042: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up
CPU computations.
60000/60000 [==============================] - 8s - loss: 0.2422 - acc: 0.9254 - val_loss: 0.1386 - val_acc: 0.9573
Epoch 2/20
60000/60000 [==============================] - 6s - loss: 0.1014 - acc: 0.9699 - val_loss: 0.0768 - val_acc: 0.9771
Epoch 3/20
60000/60000 [==============================] - 6s - loss: 0.0753 - acc: 0.9771 - val_loss: 0.0798 - val_acc: 0.9758
Epoch 4/20
60000/60000 [==============================] - 6s - loss: 0.0615 - acc: 0.9815 - val_loss: 0.0732 - val_acc: 0.980
Epoch 5/20
60000/60000 [==============================] - 6s - loss: 0.0495 - acc: 0.9850 - val_loss: 0.0902 - val_acc: 0.9783
Epoch 6/20
60000/60000 [==============================] - 6s - loss: 0.0443 - acc: 0.9866 - val_loss: 0.0860 - val_acc: 0.9797
Epoch 7/20
60000/60000 [==============================] - 6s - loss: 0.0380 - acc: 0.9883 - val_loss: 0.0719 - val_acc: 0.9834
Epoch 8/20
60000/60000 [==============================] - 7s - loss: 0.0351 - acc: 0.9900 - val_loss: 0.0869 - val_acc: 0.9822
Epoch 9/20
60000/60000 [==============================] - 8s - loss: 0.0327 - acc: 0.9906 - val_loss: 0.0764 - val_acc: 0.9827
Epoch 10/20
60000/60000 [==============================] - 7s - loss: 0.0308 - acc: 0.9911 - val_loss: 0.0786 - val_acc: 0.9836
Epoch 11/20
60000/60000 [==============================] - 9s - loss: 0.0285 - acc: 0.9918 - val_loss: 0.0814 - val_acc: 0.9835
Epoch 12/20
60000/60000 [==============================] - 7s - loss: 0.0248 - acc: 0.9930 - val_loss: 0.0928 - val_acc: 0.9824
Epoch 13/20
60000/60000 [==============================] - 7s - loss: 0.0259 - acc: 0.9927 - val_loss: 0.1057 - val_acc: 0.9823
Epoch 14/20
60000/60000 [==============================] - 7s - loss: 0.0231 - acc: 0.9933 - val_loss: 0.1030 - val_acc: 0.9820
Epoch 15/20
60000/60000 [==============================] - 7s - loss: 0.0232 - acc: 0.9939 - val_loss: 0.1116 - val_acc: 0.9815
Epoch 16/20
60000/60000 [==============================] - 7s - loss: 0.0204 - acc: 0.9947 - val_loss: 0.1055 - val_acc: 0.9829
Epoch 17/20
60000/60000 [==============================] - 6s - loss: 0.0217 - acc: 0.9947 - val_loss: 0.1281 - val_acc: 0.9821
Epoch 18/20
60000/60000 [==============================] - 7s - loss: 0.0197 - acc: 0.9950 - val_loss: 0.1176 - val_acc: 0.9839
Epoch 19/20
60000/60000 [==============================] - 7s - loss: 0.0229 - acc: 0.9942 - val_loss: 0.1120 - val_acc: 0.9831
Epoch 20/20
60000/60000 [==============================] - 7s - loss: 0.0228 - acc: 0.9944 - val_loss: 0.1078 - val_acc: 0.9834
Test loss: 0.107835494385
Test accuracy: 0.9834

と動いているようです。

The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up
CPU computations.

あたりの警告は、ソースからコンパイルしていないTenserFlowの場合CPUの拡張オプションが使えないのでスピードアップができないみたいなことみたいです。

とりあえず、よくわかってませんが動く環境をつくるところまでは成功しました。

ここから徐々に機械学習への理解を深めていきたいと思います。

参考

Installing TensorFlow on Mac OS X  |  TensorFlow

pyenvとanacondaを共存させる時のactivate衝突問題の回避策3種類 - Qiita

Python: Keras/TensorFlow の学習を CPU の拡張命令で高速化する (Mac OS X) - CUBE SUGAR CONTAINER