見出し画像

PyTorch深層学習⑬畳み込み層:理論編

前回は、単純な画像分類を畳み込み層を使わずに実装しました。今回は、画像から特徴量を抽出するのが得意な畳み込み層について解説します。

畳み込み層では、画像を平坦化することなくピクセル同士の位置関係を意識した画像処理を行います。そのため、畳み込み層の仕組みを理解するには画像データの構造についての知識が必要となります。といってもそんなに難しいことではありません。また、画像データ構造についてはこちらでも詳しく解説しています。

まずは、畳み込みカーネルの仕組みの解説から始めます。


畳み込みカーネル

畳み込みニューラルネットワーク(Convolutional Neural Network、CNN)において、入力データ(画像など)に対して特定の操作を行うために畳み込みカーネル(Convolutional Kernel。以下、カーネルと略)を使います。カーネルを使った計算では重み行列を使用します。

行列と言うと縦横に並べられた数値を使って複雑な計算を行うイメージがありますが、これといって難しい計算を行なっているわけではありません。簡単な掛け算と足し算のみで計算しています。

カーネルは、画像の各部分に適用され、その部分の情報を抽出する役割を果たします。よって、通常は小さな行列(例えば3x3や5x5)で、その各要素は学習可能な重みを持っています。

畳み込みカーネル

これらのカーネルは、画像全体に適用され、それぞれの位置での出力を生成します。これにより、元の画像から特徴マップ(Feature Map)が生成されます。また、このような計算を行う層を畳み込み層と呼びます。

次に、畳み込みによる計算の方法を解説します。

畳み込みの計算

では、特徴マップを生成するために行われる畳み込みの計算の具体例を見ていきましょう。例えば、次のような画像があるとします。

MNISTからの手書き数字画像

画像データは8ビットの整数型であることが多く、0から255までの離散値(とびとびの値)をとるのですが、これをまず、正規化や標準化によってより連続的な値に変換します。なお、画像データの正規化や標準化についてはこちらでも解説しています。

そうすることで値の変化が急激になりすぎないようにしています。入力値がとびとびだと勾配も大きく変化するため学習が難しくなるので勾配降下法を使うディープラーニングでは正規化・標準化は重要な処理です。

このように前処理がなされた画像データの各部分に対してカーネルを使った計算を行います。まず、カーネルの重みを各ピクセルに掛け合わせてから足し合わせます。そして最後にバイアスを加算します。まとめて言うと、ある正方形の領域のピクセル値を入力とした線形の計算をしていることになります。

畳み込みカーネルによる画像処理

計算式として書くと以下になります。

$$
\begin{aligned}
&\begin{bmatrix}
v_{11} & v_{12} & v_{13} \\
v_{21} & v_{22} & v_{23} \\
v_{31} & v_{32} & v_{33}
\end{bmatrix}
\odot
\begin{bmatrix}
w_{11} & w_{12} & w_{13} \\
w_{21} & w_{22} & w_{23} \\
w_{31} & w_{32} & w_{33}
\end{bmatrix} + b \\
 \\
&\ \quad= v_{11} w_{11} + v_{12} w_{12} + v_{13} w_{13} \, + \\
&\ \quad\ \quad v_{21} w_{21} + v_{22} w_{22} + v_{23} w_{23} \, + \\
&\ \quad\ \quad v_{31} w_{31} + v_{32} w_{32} + v_{33} w_{33} + b
\end{aligned}
$$

画像上の各領域のピクセル値を入力とした線形の計算をすることで位置に依存した特徴量やパターンを抽出することができるので、画像データを入力とする深層学習では畳み込みがよく使われます。

なお、抽出される特徴はカーネルのパターンによって変わってきます。

単純な例を使います。まず、画像データが0と1だけで、カーネルが下図の3x3の行列だとします。このカーネルは水平の直線を検知することを目的としています。

水平な直線を検知するカーネル(バイアスは省略)

赤い部分に対して畳み込みの計算を行うと以下になります。バイアスは0として省略します。

$$
\begin{aligned}
& 0 \times (-1) + 0 \times (-1) + 0 \times (-1)  + \\
& 1 \times \quad 1 \ + 1 \times \quad \ 1  + 1 \times \quad  \ 1   + \\
& 0 \times (-1) + 0 \times (-1) + 0 \times (-1) \\
& = 3
\end{aligned}
$$

結果は3となり、水平の直線に反応したのがわかります。

このカーネルを左上角に適用すると、以下になります。

$$
\begin{aligned}
& 0 \times (-1) + 0 \times (-1) + 0 \times (-1)  + \\
& 0 \times \quad 1   +  0 \times \quad \ 1  + 1 \times \quad  \ 1   + \\
& 0 \times (-1) + 0 \times (-1) + 1 \times (-1) \\
& = 0
\end{aligned}
$$

この場合は、水平の直線は検知されませんでした。

このカーネルによる値が大きい場所には水平の直線のパターンが現れていることになります。カーネルを画像上のあらゆる位置で計算すればどのあたりに水平の直線のパターンがあるのかが特徴量として表現できます。なお、畳み込みカーネルに関してはこちらでも詳しく解説しています。

ただし、カーネルの重みのパターンは扱うデータや訓練によって決まってくるので、より実践的な状況では必ずしも上記のように単純なものではなくなります。

以上をまとめると、畳み込みによる処理を施した部分からはその部分を代表する一つの数値が出力されます。それがどのような特徴を表しているのかはカーネルの重みによって決まります。また、カーネルの重みは学習によって更新されるので、ネットワークの最適化(損失値を最小化)を行うに従ってその値が決まっていきます。

このような最適化が可能なのは、畳み込みカーネルにおける計算(掛け算と足し算)が計算グラフに含まれることで誤差逆伝播法と勾配降下法によって重みを調節をすることできるからです。なお、計算グラフに含める計算は損失関数に関しての偏微分が計算できる必要がありますが、そのような計算は多岐にわたるので、ニューラルネットワークが学習する枠組みの自由度の高さを示しています。

RGB画像の場合

RGB画像の場合は、各ピクセルに3つの値があります。このことを3つのチャンネルがあると表現します。よって、RGB画像から特徴量を抽出する時は、3つのチャンネルからの情報を使うことになります。

この場合、畳み込みカーネルはどのような構造をしているのでしょうか。

実は、そんなに難しいことはなくて、各チャンネルに対して別々の重み行列を使って計算を行います。

例えば、3x3のカーネルをRGB画像に適用すると、RGBの各チャンネルに対して別々に3x3の重みの行列があります。よって、各チャンネルからピクセルごとの色の濃さの値に対して重み行列の値を掛け合わせてから足し合わせます。こうして計算したチャンネルごとの値をすべて足し合わせてから最後にバイアスを加えます。

$$
\begin{aligned}
&\begin{bmatrix}
v^r_{11} & v^r_{12} & v^r_{13} \\
v^r_{21} & v^r_{22} & v^r_{23} \\
v^r_{31} & v^r_{32} & v^r_{33}
\end{bmatrix}
\odot
\begin{bmatrix}
w^r_{11} & w^r_{12} & w^r_{13} \\
w^r_{21} & w^r_{22} & w^r_{23} \\
w^r_{31} & w^r_{32} & w^r_{33}
\end{bmatrix} + \\
 \\
&\begin{bmatrix}
v^g_{11} & v^g_{12} & v^g_{13} \\
v^g_{21} & v^g_{22} & v^g_{23} \\
v^g_{31} & v^g_{32} & v^g_{33}
\end{bmatrix}
\odot
\begin{bmatrix}
w^g_{11} & w^g_{12} & w^g_{13} \\
w^g_{21} & w^g_{22} & w^g_{23} \\
w^g_{31} & w^g_{32} & w^g_{33}
\end{bmatrix} + \\
 \\
&\begin{bmatrix}
v^b_{11} & v^b_{12} & v^b_{13} \\
v^b_{21} & v^b_{22} & v^b_{23} \\
v^b_{31} & v^b_{32} & v^b_{33}
\end{bmatrix}
\odot
\begin{bmatrix}
w^b_{11} & w^b_{12} & w^b_{13} \\
w^b_{21} & w^b_{22} & w^b_{23} \\
w^b_{31} & w^b_{32} & w^b_{33}
\end{bmatrix} + b \\
\end{aligned}
$$

ここで$${r, g, b}$$の文字はRGBの各チャンネルを意味します。それぞれのチャンネルに異なるデータとカーネルの重みがあることを明示するためです。

よって、RGB画像を入力として3x3のカーネルを適用する場合、カーネルが3つの3x3の重み行列になるので、合わせてカーネルの重みの構造は3x3x3の3次元テンソルであると考えます。また、バイアスの値も一つ必要です。つまり、3x3x3の重みの値と一つのバイアスの値が必要となります。

これも3x3x3という画像データの領域の値を入力値として線形の計算を使っていることに他なりません。

前回までの単純な画像分類では全てのピクセルデータを平坦化して線形の計算を行なっていました。それは画像全体の特徴量を抽出する処理になります。これに対して、畳み込みでは画像データから局所的な特徴を取り出している点で異なります。

局所的な特徴を画像の至る所から抽出することで全体の特徴を掴むのが畳み込みのやり方です。

特徴マップの生成

チャンネルの数がどうであれ、カーネルによる処理を画像全体に施していくと、画像上の各場所からの特徴量が2次元のデータとして生成されます。これを特徴マップと呼びます。

通常、複数のカーネルを使ってさまざまな特徴量を抽出するので特徴マップも複数の2次元データになります。つまりは、特徴マップは3次元データになります。

特徴マップの生成

つまり、畳み込み層による画像処理は3次元データから3次元データを生み出していることになります。ここで、グレースケールの画像も一つのチャンネルがあるので3次元データになると考えます。また、RGB画像はそもそも3次元データになっています。

なお、畳み込み層について議論するときは、3次元と呼ぶよりも、2次元の位置にある各ピクセルに対して複数のチャンネルがあるという捉え方をする方が多いです。どちらも同じことですが、位置と特徴量を区別して考える方が自然ではあります。

例えば、ある畳み込み層を使って、RGB画像の3つのチャンネルから5つのチャンネルを生成することを考えます。出力である特徴マップのチャンネル数の分だけ重み行列とバイアスの組み合わせが必要となります。入力画像のチャンネルごとに2x2の重み行列を使うとすると、3つのチャンネルに対して3x2x2の重みと一つのバイアスを使って特徴マップのチャンネルの一つを生成できます。5つのチャンネルを生成するので、全体として5つの3x2x2の重みと5つのバイアスを使います。よって、このカーネルの重みは5x3x2x2で4次元テンソルとなります。また、バイアスは長さが5の1次元テンソル(ベクトル)です。

なお、特徴マップのチャンネル数が多いほどより多くのパターンを検知することができる可能性が高くなるので、入力画像が1つや3つのチャンネルしか持たないのに対し、畳み込み層の出力では何百ものチャンネルを生成することも珍しくありません。より複雑な入力画像では、より多くのパターンを抽出する必要がある場合が多いです。

さて、畳み込み層を使って画像データから特徴量を抽出する時は、画像データを1回処理するだけで終わることは稀です。なぜなら、複数の畳み込み層を積み重ねて、さらに高度な特徴量を抽出することが可能であり、問題の複雑さに合わせて畳み込み層の数も増やすことが必要だからです。

複数の畳み込み層

ここまで、モノクロ画像やRGB画像など画像データを入力とする前提で話を進めてきました。しかし、畳み込み層がやっていることを単純化して言うと、3次元テンソルを別の3次元テンソルに変換しているのであって、その入力が画像データである必要はありません。

例えば、RGB画像ならば赤、緑、青の各色の濃さの値が各チャンネルに配置されています。これをRGB画像の色の特徴を表す特徴マップだとすると、畳み込みが行なっているのは、画像の色の特徴マップから何らかのパターンを検知して別の特徴マップへと変換していると捉えることができます。つまり、特徴マップから特徴マップへの変換です。

そうして出来た特徴マップは3次元テンソルなので、さらに別の畳み込み層を使ってより高次のパターンを見出すことが可能です。

直感的に例えると、一番目の畳み込み層が、点や線などの低次のパターンを検出したとします。次の畳み込み層はそれらのパターンを組み合わせて、目や鼻や口のパターンを認識できたとするならば、その次の畳み込み層では顔の特徴や動物の種類などを検知することができるようになるかもしれません(訓練データセットの中身や学習がうまく行くなどの条件によります)。

一般に、畳み込み層を複数使うことでより抽象的な特徴を抽出することができるので、最終的に抽出された特徴量を線形層への入力として使えば、複雑な画像認識も可能となります。つまり、最終的な特徴マップは、ネットワークが画像を「理解」し、特定のタスク(例えば画像分類や物体検出)を実行するのに役立つ情報を提供します。

次回予告

今回は畳み込み層の仕組みについて解説しました。畳み込み層を取り入れた畳み込みニューラルネットワークでは、畳み込み層以外にも最大値プーリング(MaxPooling)などを組み合わせる必要があります。これについては後ほどの記事で解説していく予定です。

次回は、PyTorchで畳み込み層を実際に使ってみます。畳み込み層を使う際に幾つかのパラメータの指定が必要となるので、その辺りを重点的に解説する予定です。

お楽しみに!

(続く)


いいなと思ったら応援しよう!