Kerasを利用したディープラーニングの手順をまとめてみた

f:id:branu_techblog:20220128151808p:plain

はじめに

初めまして、Branu開発部 アプリエンジニアの薩間です。

現在、弊社がサービスを提供している建設業界では、大手ゼネコンなどを中心にAI分野に関しての投資が進められていますが、 今後も機械学習ディープラーニングの技術進化と共に、AIによる業務改善や品質向上など、建設現場への利用が益々期待されてます。

弊社としても、その一旦を担うためデータデザイン推進室という組織を立ち上げ、ナレッジを身に付けて応用している状況です。

そこで今回はPythonのKerasを使用した簡単なディープラーニングの実装手順についてまとめてみたので、解説していきます。

MNISTの手書き文字認識を題材とし、学習の種類としては「教師あり学習の分類問題」となります。

ディープラーニングの手順

ディープラーニングでは以下の手順でディープニューラルネットーワーク(以下"モデル"と表記)を作成し、実データから予測を行います。

  1. データを用意する
  2. データを整形する
  3. モデルを構築する
  4. モデルに学習させる
  5. モデルを評価する

それでは実装を行ってみましょう。

使用するモジュール

  • mnist ... データセットを用意するために使用
  • to_categorical ... ラベルをone_hot表現にするために使用
  • Sequential, Dense ... モデルを構築するために使用
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
[f:id:branu_techblog:20220128151808p:plain]

データを用意する

モデルに学習させるためのデータを用意します。 Kerasに付属しているmnistから、手書き文字のデータセットを読み込み使用します。 keras.datasets.mnistのload_data()を呼び出すことで、データを読み込むことができます。

# データを用意する
# x_train ... 学習用の入力データ
# y_train ... 学習用の出力データ
# x_test ... 検証用の入力データ
# y_test ... 検証用の出力データ
(x_train, y_train), (x_test, y_test) = mnist.load_data()

↓データの一部

f:id:branu_techblog:20220128152519p:plain

データを整形する

用意したデータをモデルが学習できる形に整形していきます。 「教師あり学習の分類問題」を行うため、

  • 入力データ ... ベクトル
  • 出力データ ... one_hot表現

に整形します。

入力データの整形 reshape()を呼び出し、画像(=二次元配列)をベクトル(=一次元配列)に変換します。

x_train = x_train.reshape(-1, 784)
x_test = x_test.reshape(-1, 784)

出力データの整形 keras.utilsのto_categorical()を使用します。

y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

モデルを構築する

ここまででデータの準備はできたので、モデルの構築を行います。 Sequentialでモデルを入れる箱を用意し、その中にDense(全結合層)を重ねていくようにして、モデルを構築していきます。

# モデルを構築するための箱を用意する
model = Sequential()

最近の分類問題では

  • 入力層、隠れ層の活性化関数 ... ReLU
  • 出力層の活性化関数 ... softmax関数
  • 損失関数 ... 交差エントロピー誤差
  • 最適化アルゴリズム ... adam
  • 評価関数 ... 正解率

が使用されることが多いので、これらを使用してモデルを構築していきます。

入力層

用意したデータを入力していくため、input_shapeに入力データのベクトル長を指定します。

model.add(Dense(units=500, input_shape=(784,), activation='relu'))

隠れ層1

model.add(Dense(units=250, activation='relu'))

隠れ層2

model.add(Dense(units=100, activation='relu'))

出力層

softmax関数を使用した分類問題を行うため、出力層のニューロン数は正解値の種類と同じ数を指定します。

model.add(Dense(units=10, activation='softmax'))

損失関数、最適化アルゴリズム、評価関数の指定

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

モデルに学習させる

モデルの構築が完了したら、Sequentialのfit()を呼び出し学習を行います。 学習は下記のフローで行われます。

  1. 学習データをバッチサイズに分割し、入力層に入力する
  2. 出力層から出力値を取り出す
  3. 損失関数で出力値と正解値の誤差を求める
  4. 最適化アルゴリズムでバイアスと重みを調整し、モデルを最適化する
  5. 1 ~ 4 の流れを、学習データが全て読み終わるまで繰り返す
  6. 1 ~ 5の流れを、エポック数分繰り返す

今回は

  • バッチサイズ ... 1,000
  • エポック数 ... 10

を指定します。

model.fit(x_train, y_train, batch_size=1000, epochs=10, verbose=1, validation_data=(x_test, y_test))

モデルを評価する

学習が完了したら、Sequentialのevaluate()を呼び出し、モデルの評価を行います。 戻り値は配列で返され、index = 0の要素には損失関数の結果、index = 1の要素には評価関数の結果が格納されています。

test_loss, test_accuracy = model.evaluate(x_test, y_test, verbose=0)
print('損失:', test_loss)
print('評価:', test_accuracy)

コード全文

# モジュールをインポート
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# データを用意する
# x_train ... 学習用の入力データ
# y_train ... 学習用の出力データ
# x_test ... 検証用の入力データ
# y_test ... 検証用の出力データ
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 入力データをベクトルに変換する
x_train = x_train.reshape(-1, 784)
x_test = x_test.reshape(-1, 784)

# 出力データをone_hot表現に変形する
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# モデルを構築する
model = Sequential()

# 入力層
# ニューロン数 500, 活性化関数 ReLU
model.add(Dense(units=500, input_shape=(784,), activation='relu'))

# 隠れ層1
# ニューロン数 250, 活性化関数 ReLU
model.add(Dense(units=250, activation='relu'))

# 隠れ層2
# ニューロン数 100, 活性化関数 ReLU
model.add(Dense(units=100, activation='relu'))

# 出力層
# ニューロン数 10, 活性化関数 softmax関数
model.add(Dense(units=10, activation='softmax'))

# loss ... 損失関数
# optimizer ... 最適化アルゴリズム
# metrics ... 評価関数
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# モデルに学習させる
model.fit(x_train, y_train, batch_size=1000, epochs=10, verbose=1, validation_data=(x_test, y_test))

# モデルを評価する
test_loss, test_accuracy = model.evaluate(x_test, y_test, verbose=0)
print('損失:', test_loss)
print('評価:', test_accuracy)

実行結果

Epoch 1/10
60/60 [==============================] - 3s 45ms/step - loss: 8.7526 - accuracy: 0.7749 - val_loss: 0.9120 - val_accuracy: 0.9063
Epoch 2/10
60/60 [==============================] - 3s 42ms/step - loss: 0.6593 - accuracy: 0.9175 - val_loss: 0.5987 - val_accuracy: 0.9201
Epoch 3/10
60/60 [==============================] - 3s 43ms/step - loss: 0.3794 - accuracy: 0.9383 - val_loss: 0.4386 - val_accuracy: 0.9377
Epoch 4/10
60/60 [==============================] - 3s 43ms/step - loss: 0.2463 - accuracy: 0.9538 - val_loss: 0.3939 - val_accuracy: 0.9422
Epoch 5/10
60/60 [==============================] - 3s 43ms/step - loss: 0.1747 - accuracy: 0.9638 - val_loss: 0.3604 - val_accuracy: 0.9451
Epoch 6/10
60/60 [==============================] - 3s 42ms/step - loss: 0.1209 - accuracy: 0.9723 - val_loss: 0.3428 - val_accuracy: 0.9460
Epoch 7/10
60/60 [==============================] - 3s 42ms/step - loss: 0.0909 - accuracy: 0.9774 - val_loss: 0.3142 - val_accuracy: 0.9517
Epoch 8/10
60/60 [==============================] - 3s 42ms/step - loss: 0.0615 - accuracy: 0.9834 - val_loss: 0.2951 - val_accuracy: 0.9539
Epoch 9/10
60/60 [==============================] - 3s 43ms/step - loss: 0.0529 - accuracy: 0.9845 - val_loss: 0.3102 - val_accuracy: 0.9509
Epoch 10/10
60/60 [==============================] - 3s 42ms/step - loss: 0.0422 - accuracy: 0.9872 - val_loss: 0.2989 - val_accuracy: 0.9535
損失: 0.29886746406555176
評価: 0.953499972820282

まとめ

今回はPythonのKerasを使用した簡単なディープラーニングの実装手順について解説していきました。 Kerasには他にもいろいろなデータセットが用意されているので、興味を持った方はぜひ他の問題についてもチャレンジしてみてください!

Branuではデータデザイン推進室で一緒に働くメンバーを募集しています。

建設業界に関する豊富なデータを活用し、業界全体のアップデートにチャレンジしてみたいという方は、ぜひご応募ください!

www.wantedly.com