SEワンタンの独学備忘録

IT関連の独学した内容や資格試験に対する取り組みの備忘録

【機械学習】入門⑰ Windows上でKerasライブラリを使用する


前回まではニューラルネットワークモデルを自力で実装してきましたが、今回はKerasライブラリを使用して前回と同じ問題に挑んでいきます。

Keras

Kerasとは

Kerasは、Pythonで書かれたオープンソースニューラルネットワークライブラリである。MXNet(英語版)、Deeplearning4j、TensorFlow、CNTK、Theano(英語版)の上部で動作することができる[1][2]。ディープニューラルネットワークを用いた迅速な実験を可能にするよう設計され、最小限、モジュール式、拡張可能であることに重点が置かれている

引用元:Keras - Wikipedia


KerasTensorFlow上で動作するニューラルネットワークライブラリとなります。
TensorFlow自体はGoogleが開発したライブラリですが、Kerasはこれをバックグラウンドで動かしています。

Kerasインストール前提

私の環境にインストールしたときの手順を示します。
環境は以下の通りです。環境が違うとうまく動作しない可能性もあるので注意してください。

ホストマシン:Windows10
conda version : 4.8.2
python version : 3.7.6

今回は以下のバージョンをインストールします。環境や使用の目的によってはバージョンを変えてください。
kerastensorflowのバージョン関係もあるようです。私の環境ではすぐに動かせたのは以下の組み合わせでした。

keras:2.2.0
tensorflow:2.4.3

なお前提としてはWindowsにAnacondaがインストールされていることを前提としています。

www.wantanblog.com

Kerasインストール手順

anaconda powershellを起動します。

f:id:wantanBlog:20200622011953p:plain

・tensorflowのインストール

anaconda powershellから以下のコマンドを実行します。必要に応じてバージョンを変更してください。

pip install tensorflow==2.2.0

・Kerasのインストール

同じく以下のコマンドを実行します。

pip install keras==2.4.3


動作確認

プログラム上で実行できるかを確認します。
ここではJupyter Notebookを使用しますが、他の方法でもOKです。

以下のコマンドを実行します。

import keras
print(keras.__version__)

・出力結果

2.4.3

バージョン情報が出力されればOKです。

f:id:wantanBlog:20200704181320p:plain

KerasによるPython実装

以下の記事で手動実装したものをKerasにより実装します。

www.wantanblog.com

モジュールインポートとデータの作成

Kerasライブラリを使用するためのインポートとデータの作成を行います。
データの作成については以前と同じものです。

・実装例

# データの作成とモジュールのインポート
import numpy as npy
import matplotlib.pyplot as plt
import time
npy.random.seed(1)
import keras.optimizers
from keras.models import Sequential
from keras.layers.core import Dense, Activation
%matplotlib inline

outfile=npy.load('neural_data.npz')
X_train=outfile['X_train']
T_train=outfile['T_train']
X_test=outfile['X_test']
T_test=outfile['T_test']
X_range0=outfile['X_range0']
X_range1=outfile['X_range1']

# データの表示
def Show_data(x,t):
    wk,n=t.shape
    c=[[0,0,0],[.5,.5,.5],[1,1,1]]
    for i in range(n):
        plt.plot(x[t[:,i]==1,0],x[t[:,i]==1,1],linestyle='none',marker='o',markeredgecolor='black',color=c[i],alpha=0.8)
    plt.grid(True)

plt.figure(1,figsize=(8,3.7))
plt.subplot(1,2,1)
Show_data(X_train,T_train)
plt.xlim(X_range0)
plt.ylim(X_range1)
plt.title('Training Data')
plt.subplot(1,2,2)
Show_data(X_test,T_test)
plt.xlim(X_range0)
plt.ylim(X_range1)
plt.title('Test Data')

plt.show()

f:id:wantanBlog:20200704182342p:plain

Keras関連のライブラリを以下の行でインポートしています。

import keras.optimizers
from keras.models import Sequential
from keras.layers.core import Dense, Activation
モデルの作成

Kerasではネットワークモデルとしてモデルを作成して使用していきます。

・実装例

# モデル作成
npy.random.seed(1) #1
model=Sequential() #2
model.add(Dense(2,input_dim=2,activation='sigmoid',kernel_initializer='uniform')) #3
model.add(Dense(3,activation='softmax',kernel_initializer='uniform')) #3
sgd=keras.optimizers.SGD(lr=0.25,momentum=0.0,decay=0.0,nesterov=False) #4
model.compile(optimizer=sgd,loss='categorical_crossentropy',metrics=['accuracy']) #4

# 学習
startTime=time.time()
history=model.fit(X_train, T_train, epochs=1000, batch_size=100,verbose=0,validation_data=(X_test,T_test)) #5

# モデル評価
score=model.evaluate(X_test, T_test, verbose=0) #6
print('cross entropy{0:.2f}, accuracy{1:.2f}'.format(score[0],score[1]))
calculation_time=time.time()-startTime
print("Calculation time:{0:.3f}sec".format(calculation_time))

・出力結果

cross entropy0.26, accuracy0.87
Calculation time:20.946sec

今回のキモにもなるので、少し内容を見ていきます。

「#1」はKeras内部で使用される乱数を初期化しています。
初期化していないと実行するたびに異なる結果が得られる場合があるそうですが、そこまで気にしなくてよいと思います。

npy.random.seed(1) #1

「#2」はオブジェクトとしてのモデルを宣言しています。
Sequentialというのがネットワークモデルのタイプで、一般的なレイヤーが横に続いてモデルのイメージ??

model=Sequential() #2

「#3」ではモデルに中間層、出力層という感じでレイヤーを追加しています。
Denseというのが各ニューロンから次の層のニューロンに出力される全結合のニューロンモデルのイメージ。
初見だと何が何だかわからないですが、層のニューロンの数やその層で使用する活性化関数を指定しているのがわかる。

model.add(Dense(2,input_dim=2,activation='sigmoid',kernel_initializer='uniform')) #3
model.add(Dense(3,activation='softmax',kernel_initializer='uniform')) #3

「#4」は3までで、ネットワークを定義したので、学習方法を定義しています。
sgdは「確率的勾配降下法」を表してその中の設定値はそれぞれ以下の通りです。

・lr: 0以上の浮動小数点数.学習率.
・momentum: 0以上の浮動小数点数.モーメンタム.
・decay: 0以上の浮動小数点数.各更新の学習率減衰.
・nesterov: 真理値. Nesterov momentumを適用するかどうか.

引用元:最適化 - Keras Documentation

その後コンパイル(モデルに適用)を行います。
コンパイル時に目的関数(クロスエントロピー誤差)を指定します。
metrics=['accuracy']は正答率の計算要否で多くの場合には'accuracy'を設定するもの

sgd=keras.optimizers.SGD(lr=0.25,momentum=0.0,decay=0.0,nesterov=False) #4
model.compile(optimizer=sgd,loss='categorical_crossentropy',metrics=['accuracy']) #4

丸暗記はしないまでも調べて設定できるようにはならないといけないのか。大変そう。

「#5」では学習(フィッティング)を行っています。
各値は以下の通りです。

batch_size: 整数またはNone.勾配更新毎のサンプル数を示す整数.
epochs: 整数.訓練データ配列の反復回数を示す整数.
verbose: 整数.0,1,2のいずれか.進行状況の表示モード.0 = 表示なし

引用元:Modelクラス (functional API) - Keras Documentation

history=model.fit(X_train, T_train, epochs=1000, batch_size=100,verbose=0,validation_data=(X_test,T_test)) #5

「#6」ではモデルの評価を行い、損失値と評価値を返却します。
戻り値の0番目が交差エントロピー誤差、1番目がテストデータの正解率となります。

score=model.evaluate(X_test, T_test, verbose=0) #6
結果の出力

こちらはモデルから出力を行っているだけなのでざっくりと。

・実装例

# 結果のグラフ表示
plt.figure(1,figsize=(12,3))
plt.subplots_adjust(wspace=0.5)

# 学習状況の表示
plt.subplot(1,3,1)
plt.plot(history.history['loss'],'black',label='training')
plt.plot(history.history['val_loss'],'cornflowerblue',label='test')
plt.legend()

# 精度の表示
plt.subplot(1,3,2)
plt.plot(history.history['accuracy'],'black',label='training')
plt.plot(history.history['val_accuracy'],'cornflowerblue',label='test')
plt.legend()

# 境界線の表示
plt.subplot(1,3,3)
Show_data(X_test, T_test)
xn=60
x0=npy.linspace(X_range0[0],X_range0[1],xn)
x1=npy.linspace(X_range1[0],X_range1[1],xn)
xx0,xx1=npy.meshgrid(x0,x1)
x=npy.c_[npy.reshape(xx0,xn*xn,order="F"),npy.reshape(xx1,xn*xn,order="F")]
y=model.predict(x)
K=3
for ic in range(K):
    f=y[:,ic]
    f=f.reshape(xn,xn)
    f=f.T
    cont=plt.contour(xx0,xx1,f,levels=[0.5,0.7],colors=['cornflowerblue','black'])
    cont.clabel(fmt='%.1f',fontsize=9)
    plt.xlim(X_range0)
    plt.ylim(X_range1)
plt.show()

・出力結果

f:id:wantanBlog:20200705003354p:plain

一番左は交差エントロピー誤差の遷移、つまりは学習状況を表しています。
また、正答率の遷移を表示することによって、どのくらいのテストデータの分類を行えているかという精度が表現できます。
一番右はグラフ上の分類基準である決定境界を表示しています。

これらの結果から独自実装の場合とほぼ同様の結果を得られることがわかりました。
これまでの中身をゴリゴリ実装していくものとは違ってかなりシンプルな実装になりました。

よくもわるくも簡単な問題であれば理論をすっ飛ばして答えを出せるライブラリはやはり強力の一言です。

この後しばらくはこのKerasを使用していきたいと思います。

ーーーーーーーー
・今回のソース
python_dev/keras_prod1.ipynb at master · wantanblog/python_dev · GitHub