【Deep Learning with Python】畳み込みニューラルネット(CNN)の説明

前回は、畳み込みニューラルネットワーク (Convolution Neural Network; CNN) のサンプルコードを動作させてみた。もはやググればいくらでも説明が見つかるので特に説明の必要もないかと思ったけど、ここではCNNの構成要素についての説明を簡単にまとめる。

畳み込み

「畳み込み」という処理は、画像処理で言えばおおむね「フィルタリング」に当たる。画像上の一部分を切り出し、これを1つの特徴量として圧縮 (=畳み込み) する。畳み込みの操作は、切り出した小領域と「フィルタ」を演算 (内積) することで行なわれ、このフィルタの形状によって画像の「特徴量抽出」ができる。

f:id:liaoyuan:20180327234210p:plain

この図5.3 は3x3のフィルタをMNIST画像サンプルに適応してみた例。右下がりの斜めの線に強く反応しているようだ。CNNではフィルタの形状(畳み込み係数)自体も学習できるので、さまざまなフィルタが作られ、画像の特徴量を抽出できる、ということらしい。

パディング

f:id:liaoyuan:20180327234334p:plain

たとえば、上図の例のように5x5ピクセルの画像から3x3の小領域を切り出した場合、合計で9つの小領域しか作れない。この場合、作成される特徴量マップは3x3に縮小されてしまう。これを防ぐために、元の5x5の画像の周囲に1x1のダミーのピクセルを追加(=パディング)し、出力される特徴量マップが元画像と同じ5x5のサイズとなるようにする処理を行なう。

f:id:liaoyuan:20180327234434p:plain

素人考えだと、次のプーリング層でどうせサイズが縮小されるのだから、特徴量マップが縮小されてもあまり気にしなくても良いんじゃないか… と思ってしまうけど、たぶん画像の隅にある情報を取りこぼさないためのものなんじゃないかと思う。

KerasのConv2Dレイヤーでは、引数"padding" を指定するとパディングをするかどうかを選択できる。なお、デフォルトではパディング処理を行なわない。

マックスプーリング

先のCNNのサンプルでは、畳み込みの処理を行なった後、マックスプーリング層で特徴量マップを半分のサイズにダウンスケールした。このプーリングの処理が必要な理由は次の2点である。

  • 畳み込みを繰り返すと、特徴量の空間的な階層性を学習させることが困難になる
  • ダウンスケールしないと、次元数が大きくなりすぎるため過学習が起こりやすくなる

本書では書かれていないけど、画像の平行移動・回転に対するロバストネスを向上させるためという説明もされることも多いみたい。

プーリング層では、特徴量マップからある一部分の領域を切り出し、そのうちの最大値を取り出すマックスプーリングが使われることが多い。ただし、プーリングの処理はマックスプーリングに限らない。切り出した小領域の平均値を取るアベレージプーリングという処理もある。ただし、マックスプーリングは他のプーリング処理よりもうまく働くことが多い。端的に言えば、特徴量は特徴量マップ上の異なるタイル上にあるパターンの空間的配置によって表される傾向があるためである。

コード

KerasでのCNNのモデル作成方法は以下のコードの通り。(このコード自体は前回の再掲)

from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))