TensorFlow には Keras という高レベル API が統合されており、ニューラルネットワークの構築から訓練までを簡潔に記述できる。Keras の中でもっとも基本的なモデル構築方法が Sequential API だ。層を上から順に積み重ねるだけでモデルが完成するため、はじめてニューラルネットワークを組む場面に適している。
Sequential モデルとは
Sequential モデルは、層(レイヤー)を一直線に積み上げる構造を持つ。入力が最初の層に入り、各層を順番に通過して最終的な出力に到達する。分岐や合流のない単純な構造であれば、これだけで十分に対応できる。
入力データ
隠れ層(Dense など)
活性化関数(ReLU など)
出力層(softmax / sigmoid)
この直線的な流れが Sequential の名前の由来になっている。
最小構成のコード
手書き数字の分類(MNIST)を題材に、もっとも基本的な Sequential モデルを組んでみる。
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# データの読み込みと前処理
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(-1, 784).astype("float32") / 255.0
x_test = x_test.reshape(-1, 784).astype("float32") / 255.0
# Sequential モデルの構築
model = keras.Sequential([
layers.Dense(128, activation="relu", input_shape=(784,)),
layers.Dense(64, activation="relu"),
layers.Dense(10, activation="softmax"),
])
# コンパイル
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
# 訓練
model.fit(x_train, y_train, epochs=5, batch_size=32, validation_split=0.1)
# 評価
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"テスト精度: {test_acc:.4f}")
28×28 ピクセルの画像を 784 次元のベクトルに平坦化し、2 つの隠れ層を経て 10 クラスの確率分布を出力する。コード量はわずかだが、これだけで 97% 前後の精度が出る。
各パーツの役割
モデル構築からは少し離れて、compile と fit に渡している要素を整理しておく。
全結合層。前の層のすべてのニューロンと接続される、もっとも基本的な層。第 1 引数はユニット数(ニューロンの数)を指定する。
層の出力に非線形性を加える関数。relu は負の値を 0 にし、正の値はそのまま通す。出力層の softmax は各クラスの確率を返す。
損失を最小化するためにパラメータを更新する手法。adam は学習率を自動調整してくれるため、最初の選択肢として広く使われている。
モデルの予測と正解のズレを数値化する関数。sparse_categorical_crossentropy は、ラベルが整数(0〜9)で与えられる多クラス分類に使う。
model.summary() で構造を確認する
構築したモデルの全体像は summary メソッドで確認できる。
model.summary()
実行すると、各層の名前、出力の形状、パラメータ数が表示される。たとえば最初の Dense 層は入力 784 × ユニット 128 + バイアス 128 で、パラメータ数は 100,480 になる。意図した構造になっているかどうかを訓練前に必ず確認しておきたい。
add メソッドによる層の追加
リストで一括指定する以外に、add メソッドで 1 層ずつ追加する書き方もある。
モデル全体の見通しがよく、短いモデルに向いている。
条件分岐で層を切り替えたい場合や、ループで層を繰り返し追加する場合に便利。
add を使う場合のコードは次のようになる。
model = keras.Sequential()
model.add(layers.Dense(128, activation="relu", input_shape=(784,)))
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
どちらの書き方でも生成されるモデルはまったく同じものになる。好みやプロジェクトの方針に合わせて選べばよい。
Dropout で過学習を抑える
訓練データに対しては精度が高いのに、テストデータでは精度が落ちる現象を過学習と呼ぶ。Sequential モデルでも Dropout 層を挟むだけで簡単に対策できる。
model = keras.Sequential([
layers.Dense(128, activation="relu", input_shape=(784,)),
layers.Dropout(0.3),
layers.Dense(64, activation="relu"),
layers.Dropout(0.3),
layers.Dense(10, activation="softmax"),
])
Dropout は訓練時にニューロンの一部をランダムに無効化する。0.3 を指定すると 30% のニューロンが毎回ランダムに落とされるため、特定のニューロンへの依存を防ぎ、汎化性能の向上が期待できる。推論時には Dropout は自動的に無効になるので、特別な切り替えは不要だ。
Sequential の限界
Sequential API は強力だが、すべてのモデルに対応できるわけではない。
| 構造 | Sequential で対応可能か |
|---|---|
| 層が一直線 | 対応可能 |
| 途中で分岐する | 対応不可 |
| 複数の入力がある | 対応不可 |
| 層の出力を再利用する | 対応不可 |
分岐や複数入力が必要になった場合は Functional API を使うことになる。ただし、画像分類や回帰、テキスト分類など多くの基本的なタスクでは Sequential で十分に対応できるため、まずはこの API でモデル構築に慣れておくのがよいだろう。
まとめのクイズ
Sequential モデルで layers.Dense(64, activation="relu") と書いたとき、64 は何を意味するか?
- 入力データの次元数
- その層のニューロン(ユニット)の数
- バッチサイズ
- エポック数