Konvolution og filtre: Registrering af kanter og mønstre
De lærende anvender en håndlavet kantdetekteringskerne på et billede, lader derefter nn.Conv2d lære filtre automatisk og undersøger deres vægte efter træningen.
Konvolution og filtre: Registrering af kanter og mønstre er en gratis Machine Learning Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Machine Learning Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Machine Learning Academy-kurset indeholder 4 lektioner i alt.
Hvad er en convolution-operation?
Convolution er en matematisk operation, der lader en lille matrix kaldet et filter (eller kernel) glide hen over et input (f.eks. et billede) og beregner et prikprodukt element for element ved hver position. Resultatet er et feature map, der fremhæver, hvor det mønster, som filteret repræsenterer, forekommer i inputtet. Inden for billedbehandling registrerer forskellige filtre forskellige egenskaber: kanter, hjørner, teksturer eller koncepter på højere niveau, når de stables i flere lag.
import torch
# Manual 2D convolution (single filter)
image = torch.tensor([
[1., 0., 1., 0.],
[0., 1., 0., 1.],
[1., 0., 1., 0.],
[0., 1., 0., 1.]
]).unsqueeze(0).unsqueeze(0) # shape: (1,1,4,4)
# Vertical edge detector filter
filter_ = torch.tensor([[[-1., 1., -1.],
[-1., 1., -1.],
[-1., 1., -1.]]]).unsqueeze(0) # (1,1,3,3)
import torch.nn.functional as F
feature_map = F.conv2d(image, filter_, padding=0)
print(feature_map.shape) # (1, 1, 2, 2)Filtre og kantdetektering
Klassisk billedbehandling bruger håndlavede filtre: Sobel-filteret registrerer vandrette eller lodrette kanter, Laplacian-filteret registrerer alle kanter, og Gaussian-filteret slører (udjævner) billeder. I deep learning bliver disse filtre lært fra data i stedet for at blive lavet manuelt. Den centrale indsigt ved CNN'er er, at netværket automatisk finder ud af, hvilke filtre der er nyttige til opgaven, ved at minimere træningstabet.
import torch
import torch.nn.functional as F
# Sobel horizontal edge detector
sobel_h = torch.tensor([[
[-1., -2., -1.],
[ 0., 0., 0.],
[ 1., 2., 1.]
]]).unsqueeze(0) # shape (1, 1, 3, 3)
# Create a simple gradient image (brightness increases left->right)
image = torch.arange(16.).reshape(1, 1, 4, 4)
feature_map = F.conv2d(image, sobel_h, padding=1)
print('Edge response shape:', feature_map.shape)
print('Edge values:', feature_map.squeeze())nn.Conv2d: Parametre forklaret
nn.Conv2d(in_channels, out_channels, kernel_size) er det centrale CNN-lag. in_channels er antallet af inputkanaler (3 for RGB-billeder), out_channels er antallet af filtre, der skal læres, og kernel_size er den rumlige størrelse af hvert filter (3 betyder 3x3). Hvert filter producerer én outputkanal, så 64 filtre producerer et feature map med 64 kanaler. Det samlede antal parametre i ét Conv2d-lag er out_channels * in_channels * kernel_h * kernel_w + out_channels (bias).
import torch
import torch.nn as nn
# 3-channel (RGB) input -> 64 feature maps, 3x3 filters
conv = nn.Conv2d(
in_channels=3,
out_channels=64,
kernel_size=3,
padding=1, # 'same' padding: output same size as input
stride=1 # move filter by 1 pixel at a time
)
print('Filter shape:', conv.weight.shape) # (64, 3, 3, 3)
# 64 filters, each 3x3 applied to 3 channels
params = 64 * 3 * 3 * 3 + 64 # weights + bias
print('Parameters:', params) # 1792Padding og stride
Padding tilføjer nuller rundt om inputtets kant før convolution. padding=1 med et 3x3-filter bevarer inputtets rumlige dimensioner (same-padding). Uden padding reducerer hver convolution bredden og højden med kernel_size - 1. Stride styrer, hvor mange pixels filteret flytter sig ved hvert trin. stride=2 halverer outputdimensionerne og fungerer som en let pooling-operation. Convolutioner med stride 2 bruges ofte i moderne CNN'er i stedet for eksplicit pooling.
import torch
import torch.nn as nn
# Output size formula: floor((W - K + 2P) / S) + 1
# W=input, K=kernel, P=padding, S=stride
x = torch.randn(1, 3, 32, 32) # single 32x32 RGB image
conv_same = nn.Conv2d(3, 16, 3, padding=1, stride=1)
print(conv_same(x).shape) # (1, 16, 32, 32) -- same size
conv_down = nn.Conv2d(3, 16, 3, padding=1, stride=2)
print(conv_down(x).shape) # (1, 16, 16, 16) -- halved
conv_no_pad = nn.Conv2d(3, 16, 3, padding=0, stride=1)
print(conv_no_pad(x).shape) # (1, 16, 30, 30) -- reducedFlere kanaler: input og output
Et farvebillede har 3 kanaler (R, G, B). Hvert filter i et Conv2d-lag har en dybde, der svarer til in_channels — det arbejder på alle inputkanaler samtidig og producerer én enkelt outputværdi pr. rumlig position. Med 64 filtre får du 64 outputkanaler. Det næste convolution-lag tager derefter disse 64 kanaler som input. Denne stabling af kanaler gør det muligt for netværket gradvist at opbygge mere abstrakte repræsentationer, fra farvekanter på lavt niveau til objektdel på højt niveau.
import torch
import torch.nn as nn
# Layer 1: RGB (3ch) -> 32 feature maps
conv1 = nn.Conv2d(3, 32, 3, padding=1)
# Layer 2: 32 feature maps -> 64 feature maps
conv2 = nn.Conv2d(32, 64, 3, padding=1)
x = torch.randn(4, 3, 28, 28) # batch of 4 MNIST-like images
out1 = torch.relu(conv1(x))
print('After conv1:', out1.shape) # (4, 32, 28, 28)
out2 = torch.relu(conv2(out1))
print('After conv2:', out2.shape) # (4, 64, 28, 28)Parametereffektivitet: deling af vægte
En vigtig fordel ved convolutioner er deling af vægte: Det samme filter anvendes ved alle rumlige positioner. Et 3x3-filter over et billede på 256x256 involverer 9 parametre uanset billedets størrelse, mens et fuldt forbundet lag ville kræve millioner af parametre. Det gør CNN'er langt mere parametereffektive end MLP'er til billeddata og giver dem translationsækvivarians — en forskudt version af et mønster i inputtet producerer et tilsvarende forskudt feature map.
# Parameter comparison: Conv vs FC for 256x256 images
image_size = 256 * 256
# Convolution: 3x3 filter, 1 input channel, 1 output channel
conv_params = 3 * 3 * 1 + 1 # 10 parameters
# Fully connected: every input pixel connects to every output
fc_params = image_size * image_size # 4 billion params!
print(f'Conv params: {conv_params}')
print(f'FC params: {fc_params:,}')
print(f'Ratio: {fc_params / conv_params:.1e}x fewer parameters for convolution')Hvad lærer filtre i CNN'er?
Visualisering af lærte filtre afslører et hierarki af lærte egenskaber. Filtre i det første lag registrerer typisk orienterede kanter, farvegradienter og teksturer — omtrent som håndlavede Sobel-filtre. Filtre i mellemlag registrerer kombinationer: kurver, hjørner og teksturer. Filtre i dybe lag reagerer på objektdel (øjne, hjul og fjer). Denne hierarkiske indlæring af egenskaber er grunden til, at dybe CNN'er klarer sig markant bedre end overfladiske modeller på opgaver inden for billedgenkendelse.
import torch
import torch.nn as nn
# Visualise first-layer filter weight ranges
conv1 = nn.Conv2d(3, 64, 3, padding=1)
print('Filter weights shape:', conv1.weight.shape)
# (64, 3, 3, 3) -- 64 filters, each 3x3 for 3 RGB channels
# One filter: 3-channel 3x3 spatial pattern
filter_0 = conv1.weight[0] # shape: (3, 3, 3)
print('Filter 0 (R channel):')
print(filter_0[0].detach()) # 3x3 pattern for Red channel
# After training, this would show edge-like patternsReceptivt felt: Hvad hver neuron ser
En neurons receptive field i et CNN er det område af det oprindelige inputbillede, der bidrager til dens aktivering. Ét 3x3-convolution-lag har et receptivt felt på 3x3. To stablede 3x3-lag giver et receptivt felt på 5x5. Tre giver 7x7. Det er mere parametereffektivt at stable mange små filtre end at bruge ét stort filter, samtidig med at man opnår det samme receptive field. Det er grunden til, at moderne CNN'er næsten udelukkende bruger 3x3-filtre — inspireret af VGGNets opdagelse.
# Receptive field grows with depth
# Each 3x3 conv adds 2 to each side of the receptive field
def receptive_field(n_layers, kernel_size=3):
rf = 1
for _ in range(n_layers):
rf += (kernel_size - 1)
return rf
for n in [1, 2, 3, 5, 10, 20]:
rf = receptive_field(n)
print(f'{n} layers of 3x3: receptive field = {rf}x{rf}')
# 1 -> 3, 2 -> 5, 3 -> 7, 5 -> 11, 10 -> 21, 20 -> 41Opbygning af en simpel CNN-blok
Den standardiserede CNN-blok følger mønstret: Conv2d -> BatchNorm2d -> ReLU -> (valgfri pooling). Denne trio gentages flere gange med et stigende antal kanaler, så de rumlige dimensioner gradvist reduceres, mens antallet af featurekanaler øges. Den rumlige reduktion komprimerer positionsoplysninger, mens kanaludvidelsen opfanger mere abstrakte egenskaber. Dette mønster er grundlaget for ResNet, VGG, EfficientNet og de fleste andre arkitekturer.
import torch
import torch.nn as nn
def conv_block(in_ch, out_ch):
return nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
model = nn.Sequential(
conv_block(3, 32), # 3 -> 32 channels
nn.MaxPool2d(2), # halve spatial size
conv_block(32, 64), # 32 -> 64 channels
nn.MaxPool2d(2),
conv_block(64, 128), # 64 -> 128 channels
)
x = torch.randn(4, 3, 32, 32)
print(model(x).shape) # (4, 128, 8, 8)Visualisering af filteraktiveringer
Efter træningen kan du visualisere featurekort (filteraktiveringer) for et bestemt inputbillede og se, hvad hvert filter har registreret. Lyse områder i et featurekort viser, hvor det tilsvarende filtermønster blev registreret. Det er nyttigt til fejlfinding (kontrol af, at de tidlige lag har lært kantdetektorer) og til fortolkning (visning af, hvilke områder i et billede der aktiverede en detektor for "hundepels" eller "hjul" i senere lag).
import torch
import torch.nn as nn
# Extract feature maps after the first conv layer
conv1 = nn.Conv2d(3, 8, 3, padding=1)
relu = nn.ReLU()
x = torch.randn(1, 3, 16, 16) # single image
feature_maps = relu(conv1(x)) # shape: (1, 8, 16, 16)
print('Number of feature maps:', feature_maps.shape[1]) # 8
print('Feature map size:', feature_maps.shape[2:]) # 16x16
# Plot with matplotlib:
# import matplotlib.pyplot as plt
# fig, axes = plt.subplots(1, 8)
# for i, ax in enumerate(axes):
# ax.imshow(feature_maps[0, i].detach(), cmap='gray')1x1-konvolutioner: Kanalmiksning
1x1-konvolutioner anvender en lineær kombination på tværs af kanaler ved hver rumlig position uden nogen rumlig miksning. De bruges til billigt at reducere eller udvide antallet af kanaler (som i Inception- og MobileNet-flaskehalsdesign). En 1x1-konvolution fra 256 til 64 kanaler reducerer beregningerne i den efterfølgende 3x3-konvolution med 16 gange. De introducerer også ikke-linearitet (via aktivering) mellem trinnene med kanalmiksning, hvilket øger modellens kapacitet med en minimal omkostning i antal parametre.
import torch
import torch.nn as nn
# Bottleneck block: expand -> 3x3 conv -> compress
bottleneck = nn.Sequential(
nn.Conv2d(256, 64, 1), # 1x1: channel reduction
nn.ReLU(),
nn.Conv2d(64, 64, 3, padding=1), # 3x3: spatial mixing
nn.ReLU(),
nn.Conv2d(64, 256, 1), # 1x1: channel expansion
nn.ReLU()
)
x = torch.randn(4, 256, 14, 14)
out = bottleneck(x)
print(out.shape) # (4, 256, 14, 14) -- same shape as inputHurtigt tjek
Test din forståelse af begreberne inden for Machine Learning with Python fra denne lektion.
Opsummering af lektionen
I denne lektion lærte du: konvolution flytter et filter hen over inputtet og beregner prikprodukter for at producere et featurekort, der fremhæver, hvor filtermønsteret forekommer; parametrene i nn.Conv2d (in_channels, out_channels, kernel_size, padding, stride) styrer filterbanken; og vægt-deling gør konvolutioner markant mere parametereffektive end fuldt forbundne lag til rumlige data. Nu skal vi se på poolinglag til rumlig nedsampling og translationsinvarians.
Lær Python med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Konvolution og filtre: Registrering af kanter og mønstre” gratis?
Ja — hele teksten til “Konvolution og filtre: Registrering af kanter og mønstre” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Machine Learning Academy-kurset, skal du opgradere til CoddyKit PRO. Machine Learning Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Konvolution og filtre: Registrering af kanter og mønstre”?
De lærende anvender en håndlavet kantdetekteringskerne på et billede, lader derefter nn.Conv2d lære filtre automatisk og undersøger deres vægte efter træningen. Du øver dig i Machine Learning Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Machine Learning Academy?
Der kræves ingen tidligere erfaring. Machine Learning Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Konvolution og filtre: Registrering af kanter og mønstre”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Machine Learning Academy-lektion?
Ja. Alle Machine Learning Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Konvolution og filtre: Registrering af kanter og mønstre
- Poolinglag: Rumlig nedsampling og invarians
- Opbygning og træning af en CNN på CIFAR-10
- Dataforøgelse: Transformationer for robusthed