CNNはニューラルネットワークと同様、複数のレイヤを組み合わせて作成する。CNNでは新たに「Convolutionレイヤ(畳み込み層)」と「Poolingレイヤ(プーリング層)」が登場する。
これまで出てきたニューラルネットワークは隣接する層の全てのニューロン間を結合する全結合(fully-connected)であり、Affineレイヤと言う名前で実装してきた。例として全結合のニューラルネットワークでは「Affineレイヤ→活性化関数ReLUレイヤ」の組み合わせを1層として複数層で構築し、出力層にはSoftmaxレイヤを用いていた。
CNNでは「Convolutionレイヤ→ReLU→(Poolingレイヤ。省略される場合あり)」を1層として構築する。また、出力に近い層ではこれまでの「Affine→ReLU」が、出力層には「Affine→Softmax」が用いられることが一般的には多い。
全結合層では隣接する層のニューロンがすべて連結されており、出力数は任意に定めることができる。問題点としてはデータの形状が無視されてしまうことである。入力データが画像の際には縦・横・チャンネル方向の3次元形状だが、全結合層へ入力する際には一列の配列(1次元)にする必要がある。そのため空間的な近さなどの本質的な近さを無視して扱うので情報を活かす事ができていない。
畳み込み層(Convolutionレイヤ)は形状を維持する。画像のデータを3次元として扱い、次の層にデータ出力することができる。CNNでは畳み込み層の入出力データを「特徴マップ(feature map)」と言う場合がある。更に、畳み込み層の入力データを「入力特徴マップ(input feature map)」、出力データを「出力特徴マップ(output feature map)」と言う。
畳み込み層で行う処理は「畳み込み演算」である。畳み込み演算は入力データに対してフィルターを適用する。
入力データが縦・横方向の形状を持つデータに対して、フィルターも同様に縦・横方向の次元を持たせる。例として、入力サイズが4×4、フィルターサイズが3×3、出力サイズが2×2などのようになる。文献によっては「フィルター」という単語は「カーネル」とも言われる。
畳み込み演算は入力データに対してフィルターのウィンドウを一定の間隔でスライドさせながら適用する。それぞれの場所でフィルターの要素と入力の要素を乗算し、その和を求める(この計算を積和演算と呼ぶ)。結果を出力の対応する場所へ格納するプロセスをすべての場所で行なう子男tで畳み込み演算の出力を得ることが出来る。
CNNにおける重みパラメータはフィルターのパラメータにあたる。また、バイアスはフィルター適用後のデータに対して加算する、一つの固定値(いずれの要素に対しても)である。
フィルターを適用する位置の感覚を「ストライド(stride)」と言う。ストライドを2とするとフィルターを適用する窓の間隔が2要素毎になる。
ストライドを大きくすると出力サイズが小さくなるが、パディングを用いると出力サイズは大きくなる。出力サイズの計算を考えてみる。 入力サイズを$(H,W)$、フィルターサイズを$(FH,FW)$、出力サイズを$(OH,OW)$、パディングを$P$、ストライドを$S$とする。出力サイズは以下式で求められる。
$$ OH = \frac{H + 2P - FH}{S} + 1 \\ OH = \frac{W + 2P - FW}{S} + 1 $$(例)入力サイズ:(4,4)、パディング:1、ストライド:1、フィルターサイズ:(3,3) $$ OH = \frac{4+2・1-3}{1} + 1 = 4\\ OH = \frac{4+2・1-3}{1} + 1 = 4 $$
3次元の畳み込み演算はデータやフィルターを直方体のブロックで考える事ができる。多次元配列として表す時は(channel, height, width)の順に並べて書く。フィルターの場合フィルターの高さをFH(Filter Height)、横幅をFW(Filter Width)と記載する。
フィルターが一つの時には出力データはチャンネル数1つの特徴マップになる。チャンネル方向にも複数持たせるためには、複数のフィルター(重み)を用いる。フィルターの重みデータは4次元データとして(output_channel, input_channel, height, width)の順に書く。 また、バイアスは1チャンネル毎に1つ持つため形状は(FN, 1, 1)である。
Convolutionクラスで用いるim2colの引数は以下を設定。
Convolutionクラスは以下処理を実装する
Poolingレイヤも同じくim2colを使って入力データを展開するが、チャンネル方向には独立である点が異なる。
ネットワークの構成は「Convolution-ReLU-Pooling-Affine-ReLU-Affine-Softmax」とする。
今まで行ったMNISTのCNNにおける学習では1層目の重みの形状は(30,1,5,5)(サイズが5×5、チャンネルが1のフィルターが30個)である。フィルターは1チャンネルのグレー画像として可視化出来ると言うことを意味する。 (サンプルコードch07/visualize_filter.py)
学習前のフィルターはランダムに初期化されているため白黒の濃淡に規則性は無いが、学習後は規則性のある画像になっている。白から黒へグラデーションを伴って変化するフィルターや塊のある領域(「ブロブ(blob)」)を持つフィルターなど学習によって更新されていることが分かる。
規則性のあるフィルターは何を見てるのかというと、エッジやブロブなどを見ている。畳み込み層のフィルターはエッジやブロブなどのプリミティブな情報を抽出することが分かる。
1層目の畳み込み層ではエッジやブロブなどの低レベルな情報が抽出される。何層も重ねたCNNにおいて各層でどのような情報が抽出されるのかというと、層が深くなるに従って抽出される情報(強く反応するニューロン)はより抽象化されていく。
一般物体認識(車や犬など)を行なう8層のCNNであるAlexNetは畳み込み層とプーリング層が何層も重なり、最後に全結合層を用いて結果が出力される。最初の層は単純なエッジに反応し、続いてテクスチャ、より複雑な物体のパーツへと反応するように変化している。
In [ ]:
In [ ]:
In [ ]: