Hoppa till innehållet
AI-grafen
D· AI-utvecklaredatorseende· ca 45 min· grundläggande — ändras sällan· verifierad 2026-09-20

Faltning för hand

Kunna utföra en 2D-faltning för hand och förklara kantdetektering med filter.

Förkunskaper

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»):

yij=∑u=0k−1∑v=0k−1xi+u, j+v⋅wuvy_{ij} = \sum_{u=0}^{k-1}\sum_{v=0}^{k-1} x_{i+u,\,j+v} \cdot w_{uv}

Utdatans storlek:

Hut=⌊Hin+2p−ks⌋+1H_{ut} = \left\lfloor\frac{H_{in} + 2p - k}{s}\right\rfloor + 1

där pp är padding och ss är steglängd (stride).

HinH_{in}kkppssHutH_{ut}
53013
53115 (oförändrad)
2831214 (halverad)
3252132

padding = (k−1)/2 med stride = 1 bevarar storleken — därför är udda kärnstorlekar standard.

Klassiska kärnor:

KärnaMatrisGör
Identitet0 0 0 / 0 1 0 / 0 0 0inget
Sobel lodrät-1 0 1 / -2 0 2 / -1 0 1lodräta kanter
Sobel vågrät-1 -2 -1 / 0 0 0 / 1 2 1vågräta kanter
Oskärpa1/9 · allt ettorjämnar ut
Skärpa0 -1 0 / -1 5 -1 / 0 -1 0förstärker detaljer
Laplace0 1 0 / 1 -4 1 / 0 1 0kanter åt alla håll

Två egenskaper som gör faltning så effektiv i nätverk:

  1. 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.
  2. 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

Alla källor och licenser