Coursera Deep Learning専門講座の受講メモ (コース4 - Convolutional Neural Networks - Week 1)

この記事のまとめ:
  • CourseraのDeep Learning専門講座コース4: Convolutional Neural NetworksのWeek 1の受講メモとして、要点とよくわからなかったところを補完のために調べたことなどを備忘録としてまとめています。
  • Week 1では基本的な畳み込みニューラルネットワークを学びます。

コース4: Convolutional Neural Networksについて

このコースでは、基本的な畳み込みニューラルネットワーク (Convolutional Neural Networks: CNN)の層の実装から、層の深いディープニューラルネットワークに拡張するための技術、オブジェクト検出、転移学習を応用したニューラルスタイル変換、顔認識などについて学びます。

4週間の内容は次の通りです。

Week 1の概要

このコースのWeek 1では、下記のことついて学びます。

  • 畳み込み演算を理解する
  • プーリング演算を理解する
  • 畳み込みニューラルネットワークで使われる用語について覚える
  • 画像のマルチクラス分類のための畳み込みニューラルネットワークを実装する
畳み込みニューラルネットワーク

最近のデジタル画像のピクセル数は1000 x 1000 pxなど非常に多いです。このような高画質な画像を1ピクセルごとを入力としてディープニューラルネットワークを使って画像認識などを目的とした学習を行おうとした場合、重みの次元数が膨大になります。そこで、その次元数を減らしつつ、特徴量を抽出するためにCNNが使われます。

フィルター (Filter)

フィルターとは特徴を抽出するために使われ、元の画像とフィルターとの畳み込み処理によって特徴を抽出します。

畳み込み計算の方法は下記のページにGifアニメで説明があり、わかりやすいです。

フィルターにはさまざまな種類があります。その一部を下記に紹介します。

  • 水平エッジ検出フィルター
  • 垂直エッジ検出フィルター
  • Sobleフィルター
  • Scharrフィルター

また、フィルターは文献によってはカーネル (Kernel)と呼ばれることがあります。

Pythonプログラミングにおいて畳み込み処理は下記の関数で計算できます。

  • Python: conv_forward
  • TensorFlow: tf.nn.conv2d
パディング (Padding)

[n x n] の画像に [f x f] のフィルターを適用すると [n-f+1 x n-f+1] のサイズの画像になります。これだと画像サイズはフィルターを適用するたびにサイズが小さくなり、何度もフィルターを掛けることができません。 それを防ぐためにパディングがあります。元の画像の周縁に ピクセル分だけ0で付け足すことをパディングと言います。

また、CNNで畳み込み処理を行う際、パディングの処理をするかどうかを下記で表すことが多いです。

  • “Valid”: パディングをしない
  • “Same”: 入力イメージと同じサイズになるようにパディングをする(このとき となります。なお、 は通常、奇数を選びます)

こちらについても、パディング処理のイメージは下記のページを見た方がわかりやすいです。

ストライド (Strided convolution)

畳み込み処理は1ピクセルごとフィルターを動かしてフィルター処理をします。この状態を Stride = 1 であるといいます。つまり、 Stride = 2 の場合には、フィルターを2ピクセルごとに動かして畳み込み処理を行います。このとき、行列のサイズは、 となります。

こちらについても、ストライドのイメージは下記のページを見た方がわかりやすいです。

相互相関と畳み込み

これまで見てきた畳み込み処理は、線形代数で一般的に使われる畳み込み積分の処理とは異なります。これまで見てきた畳み込み処理は、一般的には相互相関とみなされます。ただし、機械学習の文献では畳み込み処理といわれます。この点については注意が必要です。

RGB画像の畳み込み処理

これまでの画像データはグレースケールを想定していましたが、RGP画像にフィルターを適用する場合を考えます。 RGB画像は、1つのピクセルに対して、RGBの情報を持つため、画像の次元は、[n x n x 3]となり、3Dのデータになります。それぞれの次元は、高さ (Height)、幅 (Width)、チャネル (Channel)といいます。

ここにフィルターを適用したい場合、[f x f x 3]の3次元のフィルターを用意します。得られる結果は[n-f+1 x n-f+1]の2次元になります。

RGBで構成される場合には、それぞれの色元素に対してフィルターを適用することとなります。

なお、3次元目の表現として、"深さ (Depth)"といわずに"チャネル"という理由は、深さはニューラルネットワーク一般として他の意味で使われることがあるためです。

複数の異なるフィルターの利用

入力に対して、複数のフィルターを適用することも可能です。この場合、各フィルター出力が出力のチャネルとして並んでいくイメージになります。

畳み込みニューラルネットワークの表現

層目のニューラルネットワークに対して次のように表現ができます。

ハイパーパラメーター

  • フィルターサイズ:
  • パディング:
  • ストライド:
  • フィルター数:

パラメーターの次元

  • 各フィルター :
  • 活性化関数 :
  • 重み:
  • バイアス:
  • 入力:
  • 出力:

出力サイズ

  • 高さ:
  • 幅:
プーリング (Pooling)

プーリングには最大プーリング、平均プーリングとがあり、多くの場合は最大プーリングが使われます。

最大プーリングではフィルター領域に対して、最大の値を選択する手法のことです。ハイパーパラメーターとして、フィルターサイズ とストライド を選択します。また、 チャネルの入力に対しては、 チャネルの出力となり、畳み込みとは違ってフィルター自体が チャネルとならないことに注意します。

最大プーリングには特徴量を抽出する効果や、計算コストを下げる効果があるが、なぜうまく働くのかは厳密にはわかってないそうです。

こちらも下記のサイトが画像でイメージしやすいです。

なお、平均プーリングでは想像の通り、平均値を選択します。

プーリング処理は見ての通り逆伝搬計算の際、計算対象となるパラメーターがありません。

ニューラルネットワークの構築方法のプラクティス

CNNは非常に層も深く、ハイパーパラメーターも多くなりがちです。そんなときに直感的にどのようなニューラルネットワークを構築すればよいかわかりにくいものです。そういった場合には、ハイパーパラメーターの調整には自分で一から探すのではなく、文献を見てどんなパラメーターを使っているかを参照したほうがよいです。

次に畳み込みニューラルネットワークの一般的なパターンを示します。

一般的には1つ以上の畳み込み層と1層のプーリング層があり、また1つ以上の畳み込み層と1層のプーリング層、という組み合わせがいくつか続き、全結合層が何層かあり、リグレッションかソフトマックスがあるというパターンです。

また、畳み込み層とプーリング層においては層を重ねるごとに 高さ と幅 は小さくなっていくが、チャネル数 は大きくなっていくのが一般的です。

このような手法が一般的に用いられますので、参考にしつつチャレンジしてみてください。

畳み込みを使う理由

冒頭で述べましたがイメージサイズは比較的大きいため、全結合で学習するとパラメーター数は全結合に対する重みと各ニューロンに対するバイアスであるため、 と、非常に多くなります。一方で、畳み込みの場合、パラメーター数は、フィルターの各素子の重みとバイアスがチャネル数だけ必要なので と非常に少ないです。

つまり、フィルターのパラメーターをひとつのイメージの中で共有しているということになります。一つ一つのフィルターは特徴検出器であり、特徴検出器をイメージの中で共有できるため、パラメーターを減らせることになります。

また、フィルターを使うことによって、出力の各素子はフィルター領域のみに影響され、それ以外の領域からは影響されません。つまり、疎な結合状態といえます。

これらの畳み込みの特徴によって過学習を起こしにくくしています。

また、畳み込みが有効な理由として、画像に対しては移動不変性があるためでもあります。

Program Assignmentで使用するPython表現
パディング

行列のパディングを行う関数です。引数は下記の通りです。

numpy.pad(array, pad_width, mode, **kwargs)

定数をパディングする場合の例は下記の通りです。

>>> import numpy as np
>>> mat = [[[1,2],[3,4]],[[5,6],[7,8]]]
>>> np.pad(mat, ((0,0),(1,1),(2,2)), 'constant', constant_values=((0,1),(2,3),(4,5)))
array([[[4, 4, 2, 2, 5, 5],
        [4, 4, 1, 2, 5, 5],
        [4, 4, 3, 4, 5, 5],
        [4, 4, 3, 3, 5, 5]],
 
       [[4, 4, 2, 2, 5, 5],
        [4, 4, 5, 6, 5, 5],
        [4, 4, 7, 8, 5, 5],
        [4, 4, 3, 3, 5, 5]]])
畳み込み層
tf.nn.conv2d(X, W1, strides = [1,s,s,1], padding = 'SAME')
  • X: 入力
  • W1: フィルター
  • strides: 各次元でのストライド量。インプットの次元がそれぞれ(訓練セット数 m, 入力画像の高さ n_H_prev, 入力画像の幅 n_W_prev, 入力画像のチャネル n_C_prev)のときに、ストライドは高さと幅の次元に対して行うため、strides = [1,s,s,1]となります。
  • padding: 画像の高さと幅を維持する場合にはSAME、フィルターやストライドに応じて小さくなることを許容する場合にはVALIDを使います。

公式ドキュメント: https://www.tensorflow.org/api_docs/python/tf/nn/conv2d

プーリング層
tf.nn.max_pool(A, ksize = [1,f,f,1], strides = [1,s,s,1], padding = 'SAME')
  • A: 入力
  • ksize: 各次元に対するウィンドウサイズ。

公式ドキュメント: https://www.tensorflow.org/api_docs/python/tf/nn/max_pool

行列のベクトル化
tf.contrib.layers.flatten(P)

公式ドキュメント: https://www.tensorflow.org/api_docs/python/tf/contrib/layers/flatten

全結合層
tf.contrib.layers.fully_connected(F, num_outputs)
  • F: ベクトル化した入力
  • num_outputs: 出力
  • activation_fn: 活性化関数。デフォルトはReLU関数なので、線形結合したい場合は、Noneを指定します。

公式ドキュメント: https://www.tensorflow.org/api_docs/python/tf/contrib/layers/fully_connected


今回は以上です。 最後まで読んでいただき、ありがとうございます。
CourseraのDeep Learning専門講座の他のコースの受講メモ

コメント

このブログの人気の投稿

LinuxでのnVidia GPUのオーバークロック・電力チューニング方法