Fast AI 2018 Lesson 3

講義資料

  • 講義動画 

Deep Learning For Coders—36 hours of lessons for free

  • 対応ノート(Kernel)

fast.ai lesson 2 | Kaggle

学んだこと

CNNの仕組み

CNNは以下の畳み込み層とプーリング層の組み合わせと、それらの出力を結合する全結合層からなる。全結合層では畳み込み層とプーリング層の組み合わせによる出力画像を入力として受け取り、入力画像と同じサイズの重み行列を掛け合わせる。

畳み込み層

入力画像に対し、filterと呼ばれる入力画像よりも小さな行列を適用し、新たに画像を生成する層。

  • 入力: Kチャネルの画像(サイズはn*n)

  • フィルタ: m種類のK次元のh*hの行列

  • 出力: mチャネルの画像

フィルタは以下のように、画像の一部分に対して適用する。計算が終わったら列を1つずらして、再びフィルタの適用を行う。この時、ずらす列は必ずしも1でなくてもよいが、講義では1で説明していた。このパラメータをstride(ストライド)という。

以下で(入力: 1チャネルの画像 2828,フィルタ: 2種類の33行列, 出力: 2チャネルの画像)での計算の例をとりあげる。

f:id:daikonclover:20181231145744p:plain
左から順に入力、フィルタ、出力を表す。ここでは出力画像の[0,0]部分の計算を示している

f:id:daikonclover:20181231145903p:plain
計算対象を1列ずらし、出力画像[0, 1]の行列計算を行う

このように計算を続けていくことで、右図のような出力画像ができあがる。 もう1種類のフィルタに対しても同様の計算を行い、最終的に以下のような2チャネルの画像が出力となる。

f:id:daikonclover:20181231150151p:plain
左から順に1チャネルの入力画像、2種類のフィルタ、2チャネルの出力画像

また、出力時には活性化関数としてReLU(Rectified Linear Units)が使われる。 これは、正の値に対しては恒等関数と同じ働きをし、負の値を0にして返す関数である。実装は以下のような単純なものである。

def relu(x)
  return max(0, x)

プーリング層 

畳み込み層の後に置かれる。画像を入力として受け取り、それを要約した画像を出力する。

畳み込みと同様に画像内の小さなブロックを計算対象にとり、それらの中の代表値を出力とする。代表値の計算方法は、平均値など様々な方法が考えられるが、最大値を代表値とすることが多い。これはMAXプーリングと呼ばれる。

f:id:daikonclover:20181231151713p:plain
入力画像中のn*n(n=2)ブロックを1つの値に要約
畳み込み層と同様に、ストライドの値を決定する必要がある。上記の例では2となっている。

プーリング層の利点として、

  • 代表値を用いるため、 学習時の画像の特徴の位置と推論時の画像の特徴の位置が多少ずれていても判別可能になる
  • 計算量が減る 

などが挙げられる。

衛生画像を題材とした多ラベル分類器の構築

画像を入力として受け取り、その画像のラベルを複数出力するようなネットワークを構築する。

例) 入力: ある衛星画像 → 出力: ラベル[晴れ、川、森林]

fast aiのライブラリは、訓練データに正解の情報がラベル付けされていると、自動的に多ラベル分類器としてモデリングしてくれるため、前回の犬猫の分類器とほぼ同じ方法を用いることができるが、パラメータにわずかな違いがある。

FineTuningにやや不向きなデータセットでの学習方法

前回と同様、FineTuningでモデルを構築していくことになるが、ベースとなる学習済みモデルが学習時に使った画像と今回の学習データである衛生画像は少しかけ離れており、低レイヤー層の再利用性は犬と猫の分類の時ほど高くはない。

しかし、それでもある程度は再利用が可能のようで、Differential Learning Rateの縮小率を前回の10倍ではなく、3倍として、低レイヤー層の学習率を高めにとり再学習することで十分動くモデルが作れるようである。

以下は講義内で用いられたコード。構成は犬と猫の分類器と同じ。

# 全結合層を学習
lr = 0.2
learn.fit(lr, 3, cycle_len=1, cycle_mult=2)

# 全結合層以外の固定を解除し、学習
lrs = np.array([lr/9, lr/3, lr]) # 低レイヤーの学習率も高め
learn.unfreeze()
learn.fit(lrs, 3, cycle_len=1, cycle_mult=2)

大幅に学習しなおす必要がある低レイヤーを固定して、全結合層のみ事前に学習する理由として、やらないよりマシ(Better than nothing)、程度のことであった(多少は再利用性があるため)。これをすることで2回目の学習をやや効率的に行うことができる。

全結合層での活性化関数について

犬と猫の分類器と今回のモデルで大きく異なる点は、全結合層の活性化関数である。犬と猫の分類器のような出力が1つのラベルの分類器ではソフトマックス関数を用いられる。

ソフトマックス関数の性質

  • 実数値を入力とし、[0, 1]の範囲の値を出力する
  • 全てのラベルについての出力を足し合わせると1になる

全ての出力を足し合わせると1になる、という制約上、複数の値が大きな値を取りづらくなり、1つのラベルを分類する際には都合がよい関数となっている。

一方、似たような関数にシグモイド関数がある。

シグモイド関数の性質

  • 実数値を入力とし、[0, 1]の範囲の値を出力する

こちらは、ソフトマックス関数と異なり合計が1になるという制約はついていない。そのため、複数のラベルに対しても大きい値を出力することができ、多ラベル分類には都合がよい。

f:id:daikonclover:20181231163058p:plain
softmaxでは1つのラベルのみ大きい値を取っているが、sigmoidでは複数の値が大きい値を取ることができる

以上のように今回のケースではシグモイド関数を出力層の活性化関数とする必要があるが、最初に述べたように訓練データが多ラベルを持っている場合、fast aiのライブラリは自動的に適切な活性化関数を選択してくれているため、クライアント側では特に何かする必要はない。