はじめに
この記事は、株式会社スピードリンクジャパン Advent Calendar 2024 の8日目の記事です。
こんにちは!
今回は、AI研究の歴史を振り返る上で欠かせないYann LeCunらによる1998年の名著、「Gradient-Based Learning Applied to Document Recognition」をご紹介します。
タイトルだけ見ると「Gradient-Based(勾配ベース)」「Document Recognition(文書認識)」といった専門的な用語が並び、「え、何これ…」「何だかすごそうだけど、いきなり難しそう…」と一瞬ひるんでしまうかもしれません。
しかし、この論文は「画像中の文字認識」をニューラルネットワークで行う手法が整理・体系化されたものとして知られています。
本稿では、論文内で扱われている手書き文字認識(0~9の手書き数字)、ドキュメント処理、畳み込みニューラルネットワーク(CNN)による特徴抽出と分類、そしてその最適化手法としての勾配降下法について整理していきます。
背景と問題設定:文書認識タスク
この論文が取り組む問題は「文書認識」です。文書認識とは、スキャン画像などから文字情報を自動的に抽出し、文字列として認識する処理です。特に論文で詳しく扱われているのは、手書き文字認識、例えば0~9までの数字を画像中から読み取る問題です。
なぜこのタスクが難しいかというと、手書き文字には個々人の筆跡や書き方のばらつきがあり、単純なテンプレートマッチングでは対応しきれません。また、印刷文字であっても、異なるフォントやスキャン品質の劣化、拡大・縮小、歪みなどが発生します。これらを「自動的に、かつ汎用的に」処理するためには、特徴量抽出や前処理がとても重要でした。
従来はこの特徴抽出を人手で定義していましたが、この論文は、勾配ベースの学習手法とCNNを組み合わせることで、特徴抽出から分類までを一貫して学習可能なフレームワークを提示しています。
「Gradient-Based Learning」の意味:勾配に基づく最適化
タイトルにある「Gradient-Based Learning」は、ニューラルネットワークのパラメータを、損失関数に対する勾配(微分)を用いて更新していく手法を意味します。要するに、現在では標準的な「誤差逆伝播(Backpropagation)」と「勾配降下法(Gradient Descent)」を中核としてモデルを訓練する手法です。
この仕組みは、以下のステップで機能します。
- 入力画像からCNNを通して出力(認識結果)を得る
- 出力と正解ラベルから損失(誤差)を計算する
- 損失をネットワークパラメータ(畳み込みフィルタ、全結合層の重みなど)に関する勾配へと伝播し、微小な更新を行う
- この更新を繰り返して、ネットワークが正しい出力を出す方向へ重みを調整する
これにより、従来は人手で設定していた特徴を、ネットワーク自体が「学習」し、最終的に数字や文字を高精度で認識できるようになります。
CNN(Convolutional Neural Network)の基本構造と役割
この論文で用いられたモデルは、後に「LeNet」として知られるアーキテクチャに繋がります。CNNは、画像の空間的構造を活用するニューラルネットワークであり、以下のような特徴を備えます。
- 畳み込み層(Convolutional Layer):画像に小さなフィルタ(カーネル)を適用することで、局所的なパターン(エッジや曲線など)を抽出します。フィルタのパラメータは学習対象であり、勾配降下法によって最適化されます。
- サブサンプリングまたはプーリング層(Pooling Layer):畳み込み層で得られた特徴マップの空間的解像度を下げ、冗長性を減らします。これにより、多少の位置ずれに対しても強力な表現を獲得できます。
- 全結合層(Fully Connected Layer):複数の畳み込み・プーリング層を通じて抽出された特徴を用いて、クラス(数字の0~9など)を判定します。ここでも勾配に基づいて学習が行われ、文字分類能力が向上します。
論文では、手書き数字認識用のデータセットが使われ、CNNはこれらの画像を直接入力として扱います。
ピクセル値をそのまま入力し、フィルタを自動的に学習して特徴を抽出し、最終的にクラスを予測する、という流れが確立されています。
学習手法と訓練プロセス
論文のポイントは、勾配降下法を用いた学習プロセスです。要点として以下が含まれます。
- 損失関数:モデルの出力(分類スコア)と正解ラベルを比較し、数値的な誤差を定義します。この誤差が小さくなるようにパラメータを更新します。クロスエントロピーなどの分類タスク向けの損失が用いられます。
- 勾配計算と逆伝播:損失関数をモデルパラメータで微分して勾配を計算し、畳み込み層のフィルタ、全結合層の重みとバイアスなど、すべてのパラメータを更新します。これにより、次のイテレーションでは誤差が減る方向にパラメータが動きます。
- バッチ処理:トレーニングは複数のサンプル(画像)を少数ずつ(バッチ)まとめて勾配計算を行いながら進めます。
- 初期化と正則化:勾配ベースの学習を安定的に進めるためには、重みの初期化や過学習を防ぐ工夫が必要です。
実験設定と評価指標
論文では、手書き数字認識タスクなどで得られた結果が報告されています。データセットとして有名なのが、0~9手書き数字(MNIST)。このデータセットでモデルがどれほどの正解率(あるいはエラー率)を達成できるかが指標になります。
実験では、モデルの構造(畳み込み層の数、フィルタ数、プーリング層の設定、全結合層のニューロン数)、学習率(勾配降下法でパラメータを更新する際のステップ幅)、エポック数(データセットを何周するか)など、様々なハイパーパラメータが検討され、最も良い結果が得られる構成が報告されています。
また、認識精度だけでなく、誤認識が起きるパターンや、異なる手書きスタイルに対するモデルの強さも分析されています。これにより、CNNを用いた勾配ベース学習が、単なる特徴量ベースの手法よりも強力な認識性能を示すことが確認されています。
LeNet-5の訓練誤差とテスト誤差。
60,000パターンの訓練セット(歪みなし)を通過した回数の関数としてのLeNet-5の訓練誤差とテスト誤差。平均訓練誤差は訓練が進むにつれてその都度測定される。このため、訓練誤差がテスト誤差より大きく見える。トレーニングセットを10-12回通過すると収束に達する。
LeNet-5の訓練誤差とテスト誤差。このグラフは、より大きな訓練セットがLeNet-5の性能を向上させることを示唆している。テストパターンは歪んでいない。
様々な分類手法のテストセットでのエラー率(%)。
[deslant] は、分類器が傾斜除去されたデータベース バージョンでトレーニングおよびテストされたことを示します。
[dist] は,訓練セットが人為的に歪められた例で補強されたことを示す。
[16 16]は,システムが16 16ピクセルの画像を使用したことを示す.誤差の不確かさは約0.1%である。
拒否性能: 一部のシステムで誤差率を0.5%に達するために拒否しなければならないテストパターンの割合。
サイズが正規化された画像から始めて、単一の文字を認識するために必要な積和演算の回数。
各手法のメモリ要件(変数の数で測定)。ほとんどの手法では、十分な性能を得るために1変数あたり1バイトしか必要としません。
理論的側面:なぜ勾配ベースの学習が有効なのか
- 表現学習:従来は特徴量を人手で設計する必要があったが、CNNを使い勾配ベースでフィルタを最適化することで、画像中の有用なパターン抽出が自動化される。
- 多段階抽象化:畳み込みとプーリング層を通して、低レベルなエッジ情報から始まり、徐々に文字のパーツ、さらには数字全体のパターンへと抽象化する階層構造が獲得できる。
- 微分可能な構造:CNNの各演算(畳み込み、プーリング、全結合)は微分可能であり、損失関数からトップダウンで勾配計算が可能。この一貫した微分可能性がエンドツーエンド学習を保証する。
これらの理由から、純粋なパターン認識タスクとしての手書き文字認識において、勾配降下法とCNNが優れた結果を生み出すと論じられています。
Kaggleで実際に動かしてみる
さて、論文で紹介された手書き数字認識は、現代ではKaggle上で簡単に試せます。ここではKaggleの「Digit Recognizer」コンペを用い、TensorFlow/KerasによるCNN実装の一例を示します。
# Part 1 - Data Preprocessing
# 必要なライブラリをインポート
import numpy as np
import pandas as pd
import tensorflow as tf
# データの読み込み
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
# トレーニングデータの前処理
X_train = train.drop('label', axis=1).values.reshape(-1, 28, 28, 1) / 255.0
y_train = train['label'].values
# テストデータの前処理
X_test = test.values.reshape(-1, 28, 28, 1) / 255.0
# Part 2 - Building the CNN
# CNNの初期化
cnn = tf.keras.models.Sequential()
# Step 1 - Convolution
cnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu', input_shape=[28, 28, 1]))
# Step 2 - Pooling
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))
# 2層目の畳み込み層
cnn.add(tf.keras.layers.Conv2D(filters=64, kernel_size=3, activation='relu'))
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))
# Step 3 - Flattening
cnn.add(tf.keras.layers.Flatten())
# Step 4 - Full Connection
cnn.add(tf.keras.layers.Dense(units=64, activation='relu'))
# Step 5 - Output Layer
cnn.add(tf.keras.layers.Dense(units=10, activation='softmax'))
# Part 3 - Training the CNN
# モデルのコンパイル
cnn.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# モデルの訓練
cnn.fit(X_train, y_train, epochs=10, validation_split=0.1, verbose=2)
# Part 4 - Making Predictions
# テストデータに対する予測
predictions = cnn.predict(X_test)
predicted_classes = np.argmax(predictions, axis=1)
検証精度が 99% に到達しています。
まとめ
本稿では、「Gradient-Based Learning Applied to Document Recognition」論文の内部で扱われている概念・手法を、タイトルの示す「勾配ベース学習」「文書認識」というキーワードを軸に整理しました。
- 文書認識(特に手書き文字認識)をニューラルネットワーク(CNN)でモデル化し、特定の特徴量設計なしで学習可能なフレームワークを提示。
- 畳み込み層、プーリング層、全結合層からなるネットワーク構造が導入され、画像から直接パターンを抽出する流れを確立。
- 誤差逆伝播と勾配降下法によるエンドツーエンド学習手法が重要なカギとなり、ネットワークが自動的に最適なフィルタ(特徴)を獲得。
- 実験によって多様な手書き数字を認識できることが示され、様々なパラメータチューニングや正則化手法が性能向上に役立つことが確認。