• 追加された行はこの色です。
  • 削除された行はこの色です。
*はじめに [#k8d83fec]
[[Keras>https://keras.io/ja/]]はディープ・ラーニング・ライブラリーの[[TensorFlow>https://www.tensorflow.org]]を使用するためのライブラリーです。

*インストール [#g811f7e5]
ここでは、Anacondaに追加する形でインストールします。

まず、Anaconda Navigatorを起動し、Environmentsを表示します。
#ref(./anaconda.png,25%,nolink)

次に、base (root)の横の三角形をクリックし、メニューを表示します。
#ref(./environments.png,25%,nolink)

メニューから、Open Terminalを選び、ターミナルを開きます。
#ref(./open_terminal.png,25%,nolink)

ターミナルを開いたら、念の為、CondaとMatplotlibをアップデートします。
#geshi(sh){{
conda update conda
conda update matplotlib
}}

CondaとMatplotlibをアップデートしたら、Kerasをインストールします。
TensorFlowはKerasと一緒にインストールされます。
#geshi(sh){{
conda install keras
}}


*使い方 [#t08ea9ce]
**ライブラリーの読み込み [#ka508f48]

ライブラリー名は ''keras'' です。
#geshi(python){{
import keras
}}

ライブラリーを読み込んで、次のようなメッセージが出てきたら、準備はできています。
#geshi(sh){{
Using TensorFlow backend.
}}


**データの準備 [#g03df668]

まず、scikit-learnに付属しているIrisデータセットを例題として使います。
説明変数は花びらの長さ、幅、萼(がく)片の長さ、幅の4つ、目的変数はSetosaを表す0、Versicolorを表す1、Virginicaを表す2の3種類です。
#geshi(python){{
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
print(X)
print(y)
}}
#geshi(sh){{
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 ...
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
}}

説明変数が4つあることから、入力層のユニット数は4になります。
目的変数が3種類あることから、出力層のユニット数は3になります。

ただし、分類器の予測モデルでは、目的変数はOne hotベクトルにしておく必要があります。

Kerasに、One hotベクトルに変換するためのto_categoricalメソッドが用意されています。
#geshi(python){{
from keras.utils import np_utils
y = np_utils.to_categorical(y)
print(y)
}}
#geshi(sh){{
[[1. 0. 0.]
 [1. 0. 0.]
 [1. 0. 0.]
 ...
 [0. 0. 1.]
 [0. 0. 1.]
 [0. 0. 1.]]
}}



**予測モデル学習器の生成 [#k5247b2d]

Kerasを使うことで、ディープ・ラーニング・ライブラリーのTensorFlowをscikit-learnと同じように使えます。

ディープ・ラーニングというのは、ニューラル・ネットワークの中間層が2つ以上のものです。
ここでは、基本的な全結合の4層モデル(入力層、中間層2つ、出力層)を作成する例を示します。


まず、シーケンシャル・モデルの入れ物を作成します。
#geshi(python){{
from keras.models import Sequential
model = Sequential()
}}

次に、入力層と1つ目の中間層を追加します。
#geshi(python){{
from keras.layers import Dense
model.add(Dense(units=16, activation='relu', input_dim=4))
}}
''Dense'' は全結合のレイヤーです。
''units'' はこのレイヤーのユニット数、''activation'' は活性化関数(ここではランプ関数 ReLU)を表します。
''input_dim'' オプションは入力層のユニット数を表し、最初の中間層だけに指定します。
説明変数が4つなので、入力層のユニット数は4です。

続いて、2つ目の中間層を追加します。
#geshi(python){{
model.add(Dense(units=8, activation='relu'))
}}

最後に、出力層を追加します。
#geshi(python){{
model.add(Dense(units=3, activation='softmax'))
}}
分類用なので、出力層の活性化関数をソフトマックスにしています。
出力が3種類なので、出力層のユニット数は3です。
(回帰用の場合は、出力層の活性化関数を線形 activation='linear' にします。)

全てのレイヤーを追加したら、モデルをコンパイルします。
#geshi(python){{
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
}}
''loss'' は損失関数、''optimizer'' は最適化手法、''metrics'' は評価尺度を表します。
ここでは、分類用なので、損失関数はカテゴリカル・クロスエントロピー categorical_crossentropy、評価尺度は精度 accuracy にしています。
最適化手法は、最もシンプルな確率的勾配法 SGD にしています。


**ニューラル・ネットワークの学習 [#zbb3432f]

scikit-learnと同じように、fitメソッドで学習します。
#geshi(python){{
model.fit(X, y, epochs=10, batch_size=150)
}}
#geshi(sh){{
Epoch 1/10
150/150 [==============================] - 0s 35us/step - loss: 0.0539 - acc: 0.9733
Epoch 2/10
150/150 [==============================] - 0s 39us/step - loss: 0.0539 - acc: 0.9733
Epoch 3/10
150/150 [==============================] - 0s 38us/step - loss: 0.0539 - acc: 0.9733
Epoch 4/10
150/150 [==============================] - 0s 74us/step - loss: 0.0538 - acc: 0.9733
Epoch 5/10
150/150 [==============================] - 0s 23us/step - loss: 0.0538 - acc: 0.9733
Epoch 6/10
150/150 [==============================] - 0s 82us/step - loss: 0.0537 - acc: 0.9733
Epoch 7/10
150/150 [==============================] - 0s 39us/step - loss: 0.0537 - acc: 0.9733
Epoch 8/10
150/150 [==============================] - 0s 57us/step - loss: 0.0536 - acc: 0.9733
Epoch 9/10
150/150 [==============================] - 0s 46us/step - loss: 0.0536 - acc: 0.9733
Epoch 10/10
150/150 [==============================] - 0s 121us/step - loss: 0.0536 - acc: 0.9733
}}
''epochs'' は事例全体に対して何回繰り返し学習するか、''batch_size'' は重みの更新をいくつの事例ごとに行うかを表します。
Irisデータセットには事例が150個含まれているので、ここでは150事例ごとに10回重みを更新しています。
(batch_size=1 にすると、1事例ごとに、1,500回重みを更新します。)


**学習した予測モデルの評価 [#i083e7c6]

scikit-learnと同じように、evaluateメソッドで評価します。
#geshi(python){{
score = model.evaluate(X, y, batch_size=150)
print(model.metrics_names)
print(score)
}}
#geshi(sh){{
150/150 [==============================] - 0s 14us/step
['loss', 'acc']
[0.053536947816610336, 0.9733333587646484]
}}
ここでは、訓練データを用いて予測モデルを評価していますが、本来は、訓練データとは別に検証データを用意して評価します。

損失が0.053、精度が0.973でした。


**学習した予測モデルによる予測 [#y5a30f2b]

scikit-learnと同じように、predictメソッドで予測します。

出力層はユニットごとに値を出力する、つまり出力は150行3列の行列になるので、argmaxメソッドで行ごとに最大値を持つインデックス番号を求めます。
#geshi(python){{
import numpy as np
p = np.argmax(model.predict(X), axis=1)
print(p)
}}
#geshi(sh){{
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1
 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
}}


*畳み込みディープ・ニューラル・ネットワーク (CDNN) による画像分類 [#fba6b065]

手書き文字認識のMNISTデータセットを用いて、畳み込みディープ・ニューラル・ネットワークを使って画像分類をやってみます。

まずはデータセットをダウンロドします。
#geshi(python){{
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
}}
#geshi(sh){{
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 136s 12us/step
}}

訓練データには縦横28ピクセルのモノクロ画像が6万枚入っています。
#geshi(python){{
print(X_train.shape)
print(y_train)
}}
#geshi(sh){{
(60000, 28, 28)
[5 0 4 ... 5 6 8]
}}

一般的な画像データはRGBなど複数のチャンネルを持っていますが、MNISTデータセットはモノクロ画像なので1チャンネルしかありません。
そのため、MNISTデータセットでは1つの画像が1つの行列だけで表現されています。
複数のチャンネルを持つ一般的な画像データは3階テンソルによって表されるため、MNISTデータセットを6万個の画像データ(3階テンソル)からなる4階テンソルに変形しておく必要があります。

そこで、訓練データを (画像枚数, 横ピクセル数, 縦ピクセル数, チャンネル数) という形に変形します。
#geshi(python){{
X_train = X_train.reshape(60000, 28, 28, 1)
}}

Irisデータセットと同じように、目的変数をOne hotベクトルに変換します。
#geshi(python){{
from keras.utils import np_utils
y_train = np_utils.to_categorical(y_train)
print(y_train)
}}
#geshi(sh){{
[[0. 0. 0. ... 0. 0. 0.]
 [1. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 1. 0.]]
}}

データの準備ができたので、次はモデルを作成します。
#geshi(python){{
from keras.models import Sequential
model = Sequential()
}}

最初の畳み込み層を追加します。
#geshi(python){{
from keras.layers import Conv2D
model.add(Conv2D(units=32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
}}
''Conv2D'' は2次元の畳み込み層です。
''units'' は畳み込み層のユニット数、''kernel_size'' は畳み込みカーネルのサイズです。
''input_shape'' は入力の形 (横ピクセル数, 縦ピクセル数, チャンネル数) で、最初の畳み込み層にだけ指定します。

続いて、2層目の畳み込み層を追加します。
#geshi(python){{
model.add(Conv2D(units=64, kernel_size=(3, 3), activation='relu'))
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
}}

この後に、プーリング層を追加します。
#geshi(python){{
from keras.layers import MaxPooling2D
model.add(MaxPooling2D(pool_size=(2, 2)))
}}
''MaxPooling2D'' は2次元のMaxプーリング層です。
''pooling_size'' はプーリングのサイズを表します。

ここで、ドロップアウトします。
#geshi(python){{
from keras.layers import Dropout
model.add(Dropout(rate=0.25))
}}
''Dropout''はドロップアウトを表現しています。
レイヤーと同じように追加されていますが、レイヤーではありません。
''rate'' はドロップする割合を表します。

次に、特徴を1次元にします。
#geshi(python){{
from keras.layers import Flatten
model.add(Flatten())
}}

1次元にしたユニットから全結合した中間層を加え、ドロップアウトします。
#geshi(python){{
from keras.layers import Dense
model.add(Dense(units=128, activation='relu'))
model.add(Dropout(rate=0.5))
}}

最後に、出力層を追加します。
#geshi(python){{
model.add(Dense(units=10, activation='softmax'))
}}
10クラス分類問題なので出力層のユニット数は10、活性化関数はソフトマックスです。

全てのレイヤーを追加したら、コンパイルします。
#geshi(python){{
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])
}}
損失はカテゴリカル・エントロピー、最適化アルゴリズムはAdaDelta、評価尺度は精度を指定します。

コンパイルしたら、学習します。
#geshi(python){{
model.fit(X_train, y_train, epochs=12, batch_size=128)
}}
#geshi(sh){{
Epoch 1/12
60000/60000 [==============================] - 139s 2ms/step - loss: 2.4267 - acc: 0.7931
Epoch 2/12
60000/60000 [==============================] - 133s 2ms/step - loss: 0.1273 - acc: 0.9639
Epoch 3/12
60000/60000 [==============================] - 129s 2ms/step - loss: 0.0933 - acc: 0.9730
Epoch 4/12
60000/60000 [==============================] - 128s 2ms/step - loss: 0.0744 - acc: 0.9784
Epoch 5/12
60000/60000 [==============================] - 145s 2ms/step - loss: 0.0629 - acc: 0.9811
Epoch 6/12
60000/60000 [==============================] - 138s 2ms/step - loss: 0.0535 - acc: 0.9848
Epoch 7/12
60000/60000 [==============================] - 133s 2ms/step - loss: 0.0490 - acc: 0.9855
Epoch 8/12
60000/60000 [==============================] - 133s 2ms/step - loss: 0.0436 - acc: 0.9868
Epoch 9/12
60000/60000 [==============================] - 146s 2ms/step - loss: 0.0407 - acc: 0.9882
Epoch 10/12
60000/60000 [==============================] - 132s 2ms/step - loss: 0.0356 - acc: 0.9893
Epoch 11/12
60000/60000 [==============================] - 134s 2ms/step - loss: 0.0340 - acc: 0.9897
Epoch 12/12
60000/60000 [==============================] - 139s 2ms/step - loss: 0.0311 - acc: 0.9907
}}

学習したら、評価します。

まず、テスト・データの形を確認します。
#geshi(python){{
print(X_test.shape)
}}
#geshi(sh){{
(10000, 28, 28)
}}

訓練データと同じように、説明変数と目的変数を変形し、評価します。
#geshi(python){{
X_test = X_test.reshape(10000, 28, 28, 1)
y_test = np_utils.to_categorical(y_test)
model.evaluate(X_test, y_test)
}}
#geshi(sh){{
10000/10000 [==============================] - 10s 979us/step
[0.04123013794525614, 0.9888]
}}
損失は0.041、精度は0.989でした。

出力は10,000行10列の行列になるので、Irisデータセットのときと同じように、argmaxメソッドを使って行ごとに最大値のインデックス番号を求めます。
#geshi(python){{
p = np.argmax(model.predict(X_test), axis=1)
print(p)
}}
#geshi(sh){{
[7 2 1 ... 4 5 6]
}}



*参考文献 [#c2bfe832]
-[[SequentialモデルでKerasを始めてみよう, Keras Documentation>https://keras.io/ja/getting-started/sequential-model-guide/]]
-[[Mnist cnn, Keras Documentation>https://keras.io/examples/mnist_cnn/]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS