Faltning för hand
Kunna utföra en 2D-faltning för hand och förklara kantdetektering med filter.
Förkunskaper
- CBilder som matriserkrävs
Intuition
En faltning är att skjuta ett litet rutnät av tal — en kärna — över bilden och för varje position räkna ut en viktad summa.
Bild (5×5) Kärna (3×3)
0 0 0 0 0 -1 0 1
0 10 10 10 0 -1 0 1 ← reagerar på lodräta kanter
0 10 10 10 0 -1 0 1
0 10 10 10 0
0 0 0 0 0
Lägg kärnan över det övre vänstra 3×3-området, multiplicera element för element, summera. Flytta ett steg åt höger. Upprepa.
Uträkning för position (0,0) — området är
0 0 0
0 10 10
0 10 10
Summa = (−1·0 + 0·0 + 1·0) + (−1·0 + 0·10 + 1·10) + (−1·0 + 0·10 + 1·10) = 20
Ett positivt värde betyder «mörkt till vänster, ljust till höger» — en kant. Det är hela idén: en liten talmatris blir en kantdetektor.
Formellt
Formeln (egentligen korskorrelation, som är vad alla ramverk kallar «convolution»):
Utdatans storlek:
där är padding och är steglängd (stride).
| 5 | 3 | 0 | 1 | 3 |
| 5 | 3 | 1 | 1 | 5 (oförändrad) |
| 28 | 3 | 1 | 2 | 14 (halverad) |
| 32 | 5 | 2 | 1 | 32 |
padding = (k−1)/2 med stride = 1 bevarar storleken — därför är udda kärnstorlekar standard.
Klassiska kärnor:
| Kärna | Matris | Gör |
|---|---|---|
| Identitet | 0 0 0 / 0 1 0 / 0 0 0 | inget |
| Sobel lodrät | -1 0 1 / -2 0 2 / -1 0 1 | lodräta kanter |
| Sobel vågrät | -1 -2 -1 / 0 0 0 / 1 2 1 | vågräta kanter |
| Oskärpa | 1/9 · allt ettor | jämnar ut |
| Skärpa | 0 -1 0 / -1 5 -1 / 0 -1 0 | förstärker detaljer |
| Laplace | 0 1 0 / 1 -4 1 / 0 1 0 | kanter åt alla håll |
Två egenskaper som gör faltning så effektiv i nätverk:
- Parameterdelning. Samma nio tal används över hela bilden. Ett fullt kopplat lager mellan två 28×28-bilder skulle behöva 614 656 vikter; en 3×3-kärna behöver 9.
- Lokalitet. Varje utdatavärde beror bara på ett litet område — vilket stämmer med hur bilder faktiskt fungerar.
Den stora skillnaden i ett CNN: kärnorna är inte handskrivna. De lärs in. Och det märkliga är att de första lagren i ett tränat nät nästan alltid lär sig något som liknar Sobel-filter — kantdetektorer, helt av sig själva.
Kod
import numpy as np
def falta(bild, karna, padding=0, steg=1):
if padding:
bild = np.pad(bild, padding)
k = karna.shape[0]
H = (bild.shape[0] - k) // steg + 1
B = (bild.shape[1] - k) // steg + 1
ut = np.zeros((H, B))
for i in range(H):
for j in range(B):
omrade = bild[i*steg:i*steg+k, j*steg:j*steg+k]
ut[i, j] = float((omrade * karna).sum())
return ut
bild = np.zeros((5, 5)); bild[1:4, 1:4] = 10
lodrat = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
print(falta(bild, lodrat))
# [[ 20. 0. -20.]
# [ 30. 0. -30.]
# [ 20. 0. -20.]]
# ↑ positivt vid vänsterkanten, negativt vid högerkanten, noll i mitten
# Storleksformeln
for H, k, p, s in [(5, 3, 0, 1), (5, 3, 1, 1), (28, 3, 1, 2), (32, 5, 2, 1)]:
print(f"H={H} k={k} p={p} s={s} → {(H + 2*p - k)//s + 1}")
# H=5 k=3 p=0 s=1 → 3
# H=5 k=3 p=1 s=1 → 5 ← padding bevarar storleken
# H=28 k=3 p=1 s=2 → 14 ← stride halverar
# H=32 k=5 p=2 s=1 → 32
# Parameterdelning — därför fungerar CNN
print(28*28 * 28*28, "vikter i ett fullt kopplat lager") # 614656
print(3*3, "vikter i en 3×3-kärna") # 9
Behärskning innebär
- Räknar ut en faltning för hand
- Förklarar vad olika kärnor gör
- Räknar ut utdatans storlek
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- Dive into Deep Learning (CC BY-SA 4.0) — CC BY-SA 4.0
- CS Unplugged (CC BY-SA 4.0) — CC BY-SA 4.0
- Wikipedia — Kernel (image processing) (CC BY-SA 4.0) — CC BY-SA 4.0