小さな窓をずらしてパターンを探す
畳み込み(たたみこみ)は、小さなフィルタを並んだデータの上でずらしながら、場所ごとにかけ算して足す計算です。画像を見分けるネットワークは、この計算で線や角などのパターンを見つけます。
貸出台数の表でも使えます。台数が急に増えた日は、隣の日との差を見れば見つかります。その「差を取る窓」が、いちばん簡単なフィルタです。
このレッスンのゴール
メモ
畳み込みがパターンを見つける仕組みを、手計算で説明できる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 畳み込み | フィルタをずらしながら、かけ算して足す計算 | |
| フィルタ | 探したいパターンを表す、小さな重みの並び | -1、1 |
| 特徴マップ | フィルタを当てた場所ごとの結果 | |
| ストライド | フィルタを1回にずらす幅 | |
| プーリング | 特徴マップを小さくまとめること | |
| 最大プーリング | 範囲ごとに、いちばん大きい値を残すこと |
学生が入力するセルは、このプレビューでは空白です。
フィルタをずらして場所ごとに計算する
畳み込みでは、フィルタと呼ぶ小さな重みの並びを、データの上でずらします。各位置で、重なった値とフィルタの重みをかけて、足します。
結果を並べたものが特徴マップです。ニューラルネットワークの畳み込みでは、フィルタをひっくり返さず、そのまま使います。
例: 貸出台数にフィルタ -1、1 を当てる
| 位置 | 重なる2日 | 計算 | 結果 |
|---|---|---|---|
| 1 | 120、125 | 120×(-1) + 125×1 | 5 |
| 2 | 125、130 | 125×(-1) + 130×1 | 5 |
| 3 | 130、310 | 130×(-1) + 310×1 | 180 |
| 4 | 310、320 | 310×(-1) + 320×1 | 10 |
| 5 | 320、315 | 320×(-1) + 315×1 | -5 |
| 6 | 315、130 | 315×(-1) + 130×1 | -185 |
学生が入力するセルは、このプレビューでは空白です。
結果の大きな値がパターンの場所
フィルタ -1、1 は、右の日から左の日を引くので、隣の日との差になります。3番目の 180 は、台数が急に増えた場所です。6番目の -185 は、急に減った場所です。
次のコマンドは、表の3番目と6番目を計算します。フィルタの重みを変えると、探すパターンが変わります。
3番目と6番目の計算を確かめる
docker exec jupyter python3 -c "print(130 * -1 + 310 * 1, 315 * -1 + 130 * 1)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
畳み込みを Python で
hires = [120, 125, 130, 310, 320, 315, 130]
filt = [-1, 1]
result = []
for start in range(len(hires) - len(filt) + 1):
total = 0
for k in range(len(filt)):
total = total + hires[start + k] * filt[k]
result.append(total)
print(result)
# filt を [1, 1, 1] に変えて、もう一度実行します。
# 結果の長さはいくつになりますか。
画像は数の格子で、フィルタも格子になる
画像は、明るさを表す数の格子です。2次元のフィルタを格子の上でずらし、場所ごとにかけ算して足します。
例の4×4の画像は、左が暗く(0)、右が明るい(1)です。フィルタは [-1, 1] を2行重ねたもので、左の列を引き、右の列を足します。左右が同じなら0、右だけ明るければ2になります。
例: 縦の境目を探す 2×2 のフィルタ
| 画像の行 | 値 | 特徴マップの行 |
|---|---|---|
| 1行目 | 0 0 1 1 | 0 2 0 |
| 2行目 | 0 0 1 1 | 0 2 0 |
| 3行目 | 0 0 1 1 | 0 2 0 |
| 4行目 | 0 0 1 1 | なし |
学生が入力するセルは、このプレビューでは空白です。
同じフィルタを使い回すから重みが少ない
畳み込みは、画像のどの場所でも同じフィルタの重みを使います。3×3 のフィルタなら重みは9個で、画像が大きくなっても増えません。
28×28 の画像の全部の点を1つのニューロンに結ぶと、重みは784個です。次のコマンドが、この2つの数を計算します。
重みの数を比べる
docker exec jupyter python3 -c "print(28 * 28, 3 * 3)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
プーリングは結果を小さくまとめる
プーリングは、特徴マップを小さくまとめます。最大プーリングは、2つずつの範囲で、いちばん大きい値を残します。
[5, 5, 180, 10, -5, -185] を2つずつに分けると、最大は 5、180、-5 です。パターンの位置が少しずれても、強い反応が残ります。
よくある間違い
注意
畳み込みは、場所ごとに別の重みを使うと考えがちです。実際は、すべての場所で同じフィルタの重みを使います。だから、線が画像のどこにあっても、同じフィルタが見つけます。重み自体は、学習で決まります。