テクノロジー
2024年11月15日Kerasとは
Keras は元々はTheano、TensorFLowなど複数のフレームワークを扱いやすくする ラッパー として登場したライブラリでしたが、後にTensorFLowの 高レベルAPI として使われるようになりました。
目次
著者プロフィール
ゴール
Kerasとは
ロジスティック回帰の実装
複数の記述方法
Sequentialモデル
Sequentialモデルのもうひとつの書き方
複数層の場合
Functional API
複数層の場合
ラッパーとしてのKeras
著者プロフィール
IT分野における教育の先駆者として、多くのエンジニアを育成するプログラミングスクールの運営、Web開発やAI研修を行なっています。幅広いレベルの受講生に対して実践的なスキルを提供。生徒の成長を第一に考え、効果的で魅力的な教育プログラムの設計に情熱を注いでいます。
ゴール
- Kerasの基本的な仕組みを知る
Kerasとは
Keras は元々はTheano、TensorFLowなど複数のフレームワークを扱いやすくする ラッパー として登場したライブラリでしたが、後にTensorFLowの 高レベルAPI として使われるようになりました。
TensorFLowに含まれる形のKerasであるtf.kerasを主に使っていきます。
《ラッパーとは》
ラッパーはもともとのプログラムの機能を利用して、より使いやすいものを提供します。TensorFlowはニューラルネットワークに必要な計算を効率的に行う機能を提供しますが、初期のころはモデルを構築して学習を行うとなると手間がかかる部分もありました。そのため、TensorFlowをラップして、扱いやすくするKerasが登場しました。
《高レベルAPIとは》
大きな単位で機能を簡単に扱えるように作られたものが高レベルAPIです。対義語として、細かい単位で機能をいじれるが、扱いがその分大変な低レベルAPIがあります。
TensorFlow自体でもニューラルネットワークのモデル構築や学習を行いやすくするために、高レベルAPIの充実が進められています。tf.Kerasはそのひとつです。
ロジスティック回帰の実装
TensorFLow入門2と同様にロジスティック回帰によるANDゲートを作成してみます。
はじめにANDゲートのデータを用意します。
import numpy as np
# ANDゲートの学習データを用意
x_train = np.array([[0,0],[0,1],[1,0],[1,1]])
y_train = np.array([[0],[0],[0],[1]])
複数の記述方法
Kerasでは簡素にニューラルネットワークが記述できます。その書き方にはSequentialモデルとFunctional APIの2種類があります。それぞれを見ていきます。
Sequentialモデル
Sequentialクラスを使用した記述方法です。
tf.keras.models.Sequential | TensorFlow
層のインスタンスをSequentialクラスのコンストラクタにリストで渡すことでモデルを定義します。層のクラスについては以下のページにまとまっています。
Module: tf.keras.layers | TensorFlow
ロジスティック回帰を作るために、全結合層のクラス、tf.keras.layers.Denseを使います。引数に出力のユニット数、活性化関数、入力のユニット数を入れます。
import tensorflow as tf
model = tf.keras.Sequential([tf.keras.layers.Dense(1, activation = tf.nn.sigmoid, input_shape=(2,))])
Denseクラスは引数で重みの初期化方法、バイアスの有無などの指定も可能です。
tf.keras.layers.Dense | TensorFlow
作成したモデルの構造はsummaryメソッドで確認することができます。層ごとの出力のshapeとパラメータ数が併記されます。
model.summary()
構造が記述できたら、モデルをコンパイルします。コンパイル時に損失関数と最適化手法、評価関数を指定します。損失関数は名前をstringで指定します。ここでは2値分類のため、binary_crossentropy
となります。多値分類の場合はcategorical_crossentropy
、回帰の場合はmean_squared_error
のようになります。
model.compile(loss='binary_crossentropy',
optimizer=tf.train.AdamOptimizer(learning_rate=0.01),
metrics=['accuracy'])
そして学習を行います。scikit-learn同様にfitメソッドを使う設計になっています。verboseは学習過程の可視化方法のパラメータで、デフォルトの1ではバッチごとに更新されるプログレスバーが表示されます。verboseが0の場合は表示を行わず、2の場合はエポック毎の表示になります。
history = model.fit(x_train, y_train,
batch_size=1,
epochs=1000,
verbose=1)
今は用意していませんが、検証用データがある場合は、引数validation_dataに与えることで、エポック毎の検証も可能です。
history = model.fit(x_train, y_train,
batch_size=1,
epochs=1000,
verbose=1,
validation_data=(x_train, y_train))
推定もscikit-learn同様にpredictメソッドを使います。
y_pred_proba = model.predict(x_train)[:, 0]
# 確率を0, 1に変換
y_pred = np.where(y_pred_proba >0.5, 1, 0)
print("y_pred_proba", y_pred_proba)
print("y_pred", y_pred)
結果がいらず、評価のみ行う場合はevaluateメソッドも便利です。
score = model.evaluate(x_train, y_train, verbose=0)
print('Train loss:', score[0])
print('Train accuracy:', score[1])
Sequentialモデルのもうひとつの書き方
Sequentialモデルでは、コンストラクタで層のクラスを渡さず、addメソッドを使って記述する方法もよく使われます。
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(1, activation = tf.nn.sigmoid, input_shape=(2,)))
複数層の場合
ロジスティック回帰ではなく、2層のニューラルネットワークの場合は以下のように記述できます。2層目以降はinput_shapeを与える必要がありません。tf.kerasが自動的に計算するためです。
model = tf.keras.Sequential([
tf.keras.layers.Dense(10, activation = tf.nn.relu, input_shape=(2,)),
tf.keras.layers.Dense(1, activation = tf.nn.sigmoid)])
addメソッドを使えば次のようになります。
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10, activation = tf.nn.relu, input_shape=(2,)))
model.add(tf.keras.layers.Dense(1, activation = tf.nn.sigmoid))
Functional API
Functional APIを使えばより自由度の高いモデル構築が行えます。Sequentialクラスの代わりにModelクラスを使用します。
tf.keras.models.Model | TensorFlow
入力から出力までの流れを記述していき、最後にModelクラスに入力層と出力層のインスタンスを渡します。
input_data = tf.keras.layers.Input(shape=(2,)) # 入力層
output = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)(input_data) # 出力層
model = tf.keras.Model(inputs=input_data, outputs=output)
モデル構造の記述以降はSequentialモデルと全く同じです。
model.summary()
model.compile(loss='binary_crossentropy',
optimizer=tf.train.AdamOptimizer(learning_rate=0.01),
metrics=['accuracy'])
history = model.fit(x_train, y_train,
batch_size=1,
epochs=1000,
verbose=1)
複数層の場合
4層のニューラルネットワークは以下のように記述できます。
input_data = tf.keras.layers.Input(shape=(2,))
x = tf.keras.layers.Dense(10, activation=tf.nn.relu)(input_data)
x = tf.keras.layers.Dense(10, activation=tf.nn.relu)(x)
x = tf.keras.layers.Dense(10, activation=tf.nn.relu)(x)
output = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)(x)
model = tf.keras.Model(inputs=input_data, outputs=output)
この記述方法では枝分かれを表現することもできます。以下は3層目で2つに枝分かれし、次の層で結合している例です。
tf.keras.layers.concatenate | TensorFlow
input_data = tf.keras.layers.Input(shape=(2,))
x = tf.keras.layers.Dense(10, activation=tf.nn.relu)(input_data)
x = tf.keras.layers.Dense(10, activation=tf.nn.relu)(x)
y1 = tf.keras.layers.Dense(10, activation=tf.nn.relu)(x)
y2 = tf.keras.layers.Dense(10, activation=tf.nn.relu)(x)
z = tf.keras.layers.concatenate([y1, y2])
output = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)(z)
model = tf.keras.Model(inputs=input_data, outputs=output)
ラッパーとしてのKeras
ラッパーとしてのKerasもデフォルトでTensorFlowをバックエンドとして使用しているため、基本的な使い方は同じです。
ドキュメントが日本語でも公開されているため、tf.kerasを利用する上で参考にすることができます。例えば2つの記述方法については以下のページです。
Sequentialモデルのガイド - Keras Documentation
Functional APIのガイド - Keras Documentation
compileメソッドで指定できる損失関数もまとまっています。
Sequentialモデルは以下のように書けます。ロジスティック回帰の例です。
以下のコードのほとんどは上で紹介したtf.kerasと実質的に同じですが、例えば活性化関数を全結合層とは別のクラスとして渡しています。また、最適化手法の部分はtf.train.AdamOptimizer
からkeras.optimizers.Adam
に変わっています。tf.kerasではTensorFlow自体の最適化手法クラスを呼んでいるのに対し、KerasではKeras独自の最適化手法クラスを使用するためです。ラッパーとしてのKerasのコードも見る機会が多いですから若干の違いに慣れておくと良いでしょう。
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam
model = Sequential()
model.add(Dense(1, input_shape=(2,)))
model.add(Activation('sigmoid'))
model.summary()
model.compile(loss='binary_crossentropy',
optimizer=Adam(lr=0.01),
metrics=['accuracy'])
history = model.fit(x_train, y_train,
batch_size=1,
epochs=1000,
verbose=1)