- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 機械学習/Pythonでデータ分析する次の一歩(ディープ・ラーニング、Keras編) へ行く。
はじめに †
Kerasはディープ・ラーニング・ライブラリーのTensorFlowを使用するためのライブラリーです。
インストール †
ここでは、Anacondaに追加する形でインストールします。
まず、Anaconda Navigatorを起動し、Environmentsを表示します。
次に、base (root)の横の三角形をクリックし、メニューを表示します。
メニューから、Open Terminalを選び、ターミナルを開きます。
ターミナルを開いたら、念の為、CondaとMatplotlibをアップデートします。
conda update conda conda update matplotlib
CondaとMatplotlibをアップデートしたら、Kerasをインストールします。 TensorFlowはKerasと一緒にインストールされます。
conda install keras
使い方 †
ライブラリーの読み込み †
ライブラリー名は keras です。
import keras
ライブラリーを読み込んで、次のようなメッセージが出てきたら、準備はできています。
Using TensorFlow backend.
予測モデル学習器の生成 †
Kerasを使うことで、ディープ・ラーニング・ライブラリーのTensorFlowをScikit-learnと同じように使えます。
ディープ・ラーニングというのは、ニューラル・ネットワークの中間層が2つ以上のものです。 ここでは、基本的な全結合の4層モデル(入力層、中間層2つ、出力層)を作成する例を示します。
ここで、Scikit-learnに付属しているIrisデータセットを例題として使います。 説明変数は花びらの長さ、幅、萼(がく)片の長さ、幅の4つ、目的変数はSetosaを表す0、Versicolorを表す1、Virginicaを表す2の3種類です。
まず、シーケンシャル・モデルの入れ物を作成します。
print(keras.__version__)
次に、入力層と1つ目の中間層を追加します。
from sklearn import datasets iris = datasets.load_iris() X = iris.data y = iris.target print(X) print(y)
Dense は全結合のレイヤーです。 units はこのレイヤーのユニット数、activation は活性化関数(ここではランプ関数 ReLU)を表します。 input_dim オプションは、最初の中間層だけに指定し、入力層のユニット数を表します。 説明変数が4つなので、入力層のユニット数は4です。
続いて、2つ目の中間層を追加します。
[[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]
最後に、出力層を追加します。
from keras.utils import np_utils y = np_utils.to_categorical(y) print(y)
分類用なので、出力層の活性化関数をソフトマックス Softmax にしています。 出力が3種類なので、出力層のユニット数は3です。
全てのレイヤーを追加したら、モデルをコンパイルします。
[[1. 0. 0.] [1. 0. 0.] [1. 0. 0.] ... [0. 0. 1.] [0. 0. 1.] [0. 0. 1.]]
loss は損失関数、optimizer は最適化手法、metrics は評価尺度を表します。 ここでは、分類用なので、損失関数はカテゴリカル・クロスエントロピー categorical_crossentropy、評価尺度は精度 accuracy にしています。 最適化手法は、最もシンプルな確率的勾配法 SGD にしています。
ニューラル・ネットワークの学習 †
まず、データを準備します。
Scikit-learnに付属しているIrisデータセットの目的変数は、[0, ..., 1, ..., 2, ...] という1次元ベクトルになっていますが、Kerasに付属している np_utils を用いて、これを [[1, 0, 0], ..., [0, 1, 0], ..., [0, 0, 1], ...] というOne hotベクトルに変換します。
from tensorflow.keras.models import Sequential model = Sequential()
Scikit-learnと同じように、fitメソッドで学習します。
from tensorflow.keras.layers import Dense model.add(Dense(units=16, activation='relu', input_dim=4))
epochs は事例全体に対して何回繰り返し学習するか、batch_size は重みの更新をいくつの事例ごとに行うかを表します。 Irisデータセットには事例が150個含まれているので、ここでは150事例ごとに10回重みを更新しています。 (batch_size=1 にすると、1事例ごとに、1,500回重みを更新します。)
model.add(Dense(units=8, activation='relu'))
学習した予測モデルの評価 †
Scikit-learnと同じように、evaluateメソッドで評価します。
model.add(Dense(units=3, activation='softmax'))
ここでは、訓練データを用いて予測モデルを評価していますが、本来は、訓練データとは別に検証データを用意して評価します。
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
損失が0.053、精度が0.973でした。
学習した予測モデルによる予測 †
Scikit-learnと同じように、predictメソッドで予測します。
model.fit(X, y, epochs=1000, batch_size=150)
出力ユニットごとの値が出てくるので、行ごとにargmaxメソッドで最大値を持つ引数を求めます。
Train on 150 samples Epoch 1/1000 150/150 [==============================] - 1s 8ms/sample - loss: 2.0354 - accuracy: 0.3333 Epoch 2/1000 150/150 [==============================] - 0s 42us/sample - loss: 1.8037 - accuracy: 0.3333 Epoch 3/1000 150/150 [==============================] - 0s 74us/sample - loss: 1.6263 - accuracy: 0.3333 Epoch 4/1000 150/150 [==============================] - 0s 64us/sample - loss: 1.4876 - accuracy: 0.3333 Epoch 5/1000 150/150 [==============================] - 0s 54us/sample - loss: 1.3778 - accuracy: 0.3333 ... Epoch 998/1000 150/150 [==============================] - 0s 43us/sample - loss: 0.1798 - accuracy: 0.9733 Epoch 999/1000 150/150 [==============================] - 0s 49us/sample - loss: 0.1794 - accuracy: 0.9733 Epoch 1000/1000 150/150 [==============================] - 0s 39us/sample - loss: 0.1791 - accuracy: 0.9733
畳み込みディープ・ニューラル・ネットワーク (CDNN) による画像分類 †
手書き文字認識のMNISTデータセットを用いて、畳み込みディープ・ニューラル・ネットワークを使って画像分類をやってみます。
まずはデータセットをダウンロドします。
score = model.evaluate(X, y, batch_size=150) print(model.metrics_names) print(score)
150/1 [==========... ...=====] - 0s 1ms/sample - loss: 0.1787 - accuracy: 0.9733 ['loss', 'accuracy'] [0.17870810627937317, 0.97333336]
訓練データには縦横28ピクセルのモノクロ画像が6万枚入っています。
model.predict(X)
array([[9.30257916e-01, 3.53016481e-02, 3.44404392e-02], [9.22631919e-01, 3.99531014e-02, 3.74150351e-02], [9.21679020e-01, 4.05398346e-02, 3.77811491e-02], ... [1.05547340e-04, 8.70669410e-02, 9.12827492e-01], [1.82199045e-04, 1.80615202e-01, 8.19202602e-01]], dtype=float32)
この記事はまだ書きかけです。