Pierwsze kroki z Lokalnym AI

Zbuduj własne, prywatne AI. Zobacz kompleksowe zestawienie poradników – od instalacji pierwszej aplikacji po zaawansowanych agentów. Sprawdź poradnik

Architektura i mechanika konwolucyjnych sieci neuronowych (CNN)

anatomia
Streszczenie AI

Konwolucyjne sieci neuronowe (CNN) wykorzystują zasady lokalnej łączności, współdzielenia wag i translacyjnej ekwiwariantności, co pozwala zachować strukturę danych i znacznie redukować liczbę parametrów w porównaniu z warstwami gęstymi. 1‑D i 2‑D sploty, w implementacjach głębokiego uczenia często interpretowane jako korelacje, są sterowane paddingiem, stride’em i dilacją, a ich złożoność i liczba parametrów można precyzyjnie obliczyć przy podanych wzorach; przejście do depthwise‑separable konwolucji redukuje operacje mnożenia do 8‑9‑krotkiego, a warstwy residualne z BatchNorm/ ReLU uzyskują stabilny przepływ gradientów w popularnych frameworkach. Dzięki temu architektury takie jak MobileNet, DeepLab czy UNet realizują wydajne segmentacje obrazów oraz analiza szeregów czasowych na platformach wbudowanych, zachowując deterministyczny profil pamięciowy i pełne wsparcie akceleratorów sprzętowych.

Spis treści:
Ostatnia aktualizacja: 14 września, 2026

Konwolucyjne sieci neuronowe (ang. Convolutional Neural Networks, CNN) stanowią fundament współczesnego przetwarzania sygnałów jedno- i wielowymiarowych w widzeniu komputerowym oraz analizie szeregów czasowych. Ich konstrukcja opiera się na trzech kluczowych zasadach: lokalnej łączności (ang. local connectivity), współdzieleniu wag (ang. weight sharing) oraz ekwiwariantności względem translacji (ang. translation equivariance). W przeciwieństwie do gęstych warstw liniowych (ang. fully-connected), w których każdy neuron wejściowy łączy się z każdym neuronem wyjściowym, operacja splotu pozwala zachować topologię danych przy drastycznym ograniczeniu liczby swobodnych parametrów.

Matematyczne podstawy operacji konwolucji (1D i 2D)

W ścisłym sensie matematycznym ciągła konwolucja (splot) dwóch funkcji f i g zdefiniowana jest jako całka:

(f * g)(t) = \int_{-\infty}^{\infty} f(\tau) g(t – \tau) \, d\tau

W dyskretnych implementacjach stosowanych w uczeniu głębokim biblioteki obliczeniowe (np. cuDNN, PyTorch, TensorFlow) realizują w rzeczywistości operację wzajemnej korelacji (ang. cross-correlation), rezygnując z lustrzanego odbicia jądra (ang. kernel flipping). Różnica ta nie ma wpływu na proces optymalizacji, ponieważ wagi jądra są parametrami uczonymi gradientowo podczas propagacji wstecznej.

W przypadku dyskretnym 1D (stosowanym m.in. w sygnałach audio, analizie EKG lub modelowaniu sekwencji tekstowych) sygnał wejściowy x \in \mathbb{R}^L splotowany z filtrem w \in \mathbb{R}^K daje wyjście y \in \mathbb{R}^{L’}:

y[i] = (x * w)[i] = \sum_{k=0}^{K-1} x[i+k] \cdot w[k]

Dla tensora dwuwymiarowego (2D) z wieloma kanałami wejściowymi, gdzie wejście ma postać X \in \mathbb{R}^{C_{\text{in}} \times H \times W}, a zestaw wag dla c_{\text{out}}-tego filtra stanowi jądro W_{c_{\text{out}}} \in \mathbb{R}^{C_{\text{in}} \times K_h \times K_w} wraz z obciążeniem b_{c_{\text{out}}} \in \mathbb{R}, pojedynczy punkt na mapie cech Y \in \mathbb{R}^{C_{\text{out}} \times H_{\text{out}} \times W_{\text{out}}} wyraża się wzorem:

Y[c_{\text{out}}, i, j] = b_{c_{\text{out}}} + \sum_{c_{\text{in}}=0}^{C_{\text{in}}-1} \sum_{m=0}^{K_h-1} \sum_{n=0}^{K_w-1} X[c_{\text{in}}, i+m, j+n] \cdot W[c_{\text{out}}, c_{\text{in}}, m, n]

Wymiary wyjściowe mapy cech zależą bezpośrednio od parametrów siatki dyskretyzacji: paddingu (P), kroku (S), rozmiaru jądra (K) oraz dylatacji (D).

Parametry sterujące: Padding, Stride i Dilated Convolution

Kontrola przestrzennej propagacji sygnału przez warstwy splotowe wymaga precyzyjnego doboru hiperparametrów:

  • Padding (P): Dopełnienie brzegów tensora dodatkowymi wartościami (najczęściej zerami, ang. zero-padding). Chroni ono przed przedwczesną utratą rozdzielczości przestrzennej na brzegach oraz zapobiega ucinaniu informacji brzeżnych. Wyróżnia się konfigurację valid (brak paddingu, P = 0) oraz same (dobór paddingu P = \lfloor K/2 \rfloor przy kroku S = 1, co zachowuje wyjściowe wymiary równe wejściowym).
  • Stride (S): Krok przesunięcia jądra wzdłuż osi przestrzennych. Ustawienie S > 1 powoduje próbkowanie w dół (ang. strided downsampling), zastępując tradycyjne warstwy poolingowe bez wprowadzania nieparametrycznych operacji redukcji.
  • Dilated (Atrous) Convolution (D): Splot z odstępami (dziurami) pomiędzy wagami filtra. Rozszerza pole recepcyjne (ang. receptive field) warstwy bez zwiększania liczby parametrów i bez utraty gęstej rozdzielczości przestrzennej. Efektywny rozmiar filtra K_{\text{eff}} wynosi K_{\text{eff}} = K + (K – 1)(D – 1). Znalazł kluczowe zastosowanie m.in. w architekturach DeepLab w zadaniach segmentacji semantycznej oraz w modelach sekwencyjnych WaveNet.

Ogólny wzór na przestrzenny wymiar wyjściowy dla danej osi ma postać:

H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P – D(K – 1) – 1}{S} \right\rfloor + 1

Warstwy składowe sieci splotowych

Stabilny przepływ gradientu i budowa nieliniowej reprezentacji wymagają zestawienia warstw splotowych z mechanizmami redukcji wymiarowości i normalizacji aktywacji.

  • Warstwa konwolucyjna (Conv): Wyodrębnia lokalne reprezentacje cech poprzez zestaw uczonych filtrów reagujących na krawędzie, gradienty barwne, a w głębszych warstwach – na całe struktury semantyczne.
  • Warstwy próbkowania (Pooling): Warstwy bezparametryczne, których celem jest redukcja wymiarów przestrzennych map cech, co ogranicza złożoność obliczeniową kolejnych bloków oraz zapewnia częściową niezmienniczość względem drobnych przesunięć. Najpowszechniejszy jest Max Pooling (wybór wartości maksymalnej w lokalnym oknie, zachowujący dominujące aktywacje) oraz Average Pooling (obliczanie średniej arytmetycznej, często stosowane globalnie jako Global Average Pooling na końcu sieci przed klasyfikatorem).
  • Batch Normalization (BatchNorm): Technika normalizacji aktywacji wewnątrz mini-batcha wprowadzona przez Ioffe i Szegedy’ego. Dla tensora aktywacji 2D o kształcie (N, C, H, W) statystyki średniej \mu_c i wariancji \sigma_c^2 obliczane są osobno dla każdego kanału wzdłuż wymiarów (N, H, W). Warstwa wprowadza dwa uczone parametry dla każdego kanału: skalowanie \gamma i przesunięcie \beta. Drastycznie przyspiesza to zbieżność procesu optymalizacji, redukuje wrażliwość na inicjalizację wag oraz pełni rolę lekkiego regularyzatora.

Ewolucja architektur: od LeNet do nowoczesnych motywów blokowych

Rozwój sieci konwolucyjnych przeszedł drogę od prostych sekwencji warstw do zaawansowanych topologii wykorzystujących rezydualność i separację wymiarów.

Architektura
Rok
Kluczowe cechy konstrukcyjne
Wielkość filtrów
Rola / Ograniczenia
LeNet-5 1998 Płytka sieć sekwencyjna (Conv-AvgPool-Conv-AvgPool-FC), aktywacje Sigmoid/Tanh 5×5 Prekursor klasyfikacji cyfr (MNIST); mała skalowalność do obrazów naturalnych
AlexNet 2012 Aktywacja ReLU, Local Response Normalization, Dropout, użycie 2x GPU 11×11, 5×5, 3×3 Przełom ImageNet; duży narzut pamięciowy ze względu na potężne warstwy FC
VGG (16/19) 2014 Jednolita topologia: stosy małych filtrów, podwajanie kanałów po poolingu 3×3 Faktoryzacja pola recepcyjnego (dwa filtry 3×3 dają zasięg 5×5 przy mniejszej liczbie wag); wysoki koszt obliczeniowy
ResNet 2015 Połączenia skrótowe (ang. skip connections, F(x) + x), eliminacja zanikającego gradientu 3×3, 1×1 (Bottleneck) Umożliwiła stabilne uczenie sieci o głębokości 50, 101, a nawet 152+ warstw
MobileNet (v1-v3) 2017+ Sploty rozdzielne głębokościowo (Depthwise Separable Convolutions), odwrócone bloki rezydualne 3×3 DW, 1×1 PW Projektowana pod urządzenia wbudowane/mobilne; radykalny spadek FLOPs
ConvNeXt 2022 Modernizacja klasycznego CNN z inspiracji Vision Transformers (ViT): jądra 7×7, LayerNorm, aktywacja GELU 7×7 Depthwise Przywrócenie konkurencyjności czystych modeli CNN względem architektur transformerowych

Kluczową innowacją współczesnych sieci jest zastąpienie standardowego splotu 2D jego wariantem Depthwise Separable Convolution. Składa się on z dwóch etapów: splotu depthwise (pojedynczy filtr 2D aplikowany niezależnie dla każdego kanału wejściowego) oraz splotu pointwise (standardowy splot 1×1 agregujący informacje wzdłuż osi kanałów). Zabieg ten redukuje złożoność obliczeniową z K^2 \cdot C_{\text{in}} \cdot C_{\text{out}} do K^2 \cdot C_{\text{in}} + C_{\text{in}} \cdot C_{\text{out}}, co przy standardowym jądrze 3×3 oznacza około 8-krotne do 9-krotne zmniejszenie liczby operacji mnożenia i akumulacji.

Analiza wymiarów tensorów i złożoność obliczeniowa

W warstwie o parametrach: jądro K_h \times K_w, kanały wejściowe C_{\text{in}}, kanały wyjściowe C_{\text{out}} oraz rozmiar wyjścia H_{\text{out}} \times W_{\text{out}}, parametryzacja i koszt obliczeń kształtują się następująco:

  • Liczba uczonych parametrów:
\text{Params} = (K_h \cdot K_w \cdot C_{\text{in}} + 1) \cdot C_{\text{out}}

(gdzie +1 to wyraz wolny / bias na każdy kanał wyjściowy)

  • Złożoność obliczeniowa (FLOPs / MACs): Liczba operacji mnożenia z akumulacją (Multiply-Accumulate Operations, MACs) dla pojedynczego przejścia w przód wynosi:
    \text{MACs} \approx H_{\text{out}} \cdot W_{\text{out}} \cdot C_{\text{out}} \cdot (K_h \cdot K_w \cdot C_{\text{in}})
  • Liczba operacji zmiennoprzecinkowych (FLOPs) wynosi w przybliżeniu 2 \times \text{MACs}, z uwzględnieniem operacji dodawania i mnożenia. Oznacza to, że koszt obliczeniowy rośnie liniowo wraz z polem powierzchni wyjściowej mapy cech oraz kwadratowo względem szerokości kanałów przy symetrycznym skalowaniu C_{\text{in}} = C_{\text{out}}.

    Praktyczna implementacja: PyTorch vs. TensorFlow

    Poniżej przedstawiono porównanie implementacji modularnego bloku splotowego obejmującego splot 2D, normalizację wsadową, nieliniowość ReLU oraz rezydualne połączenie skrótowe w dwóch wiodących środowiskach uczenia maszynowego.

    Wzorzec w środowisku PyTorch:

    PyTorch przyjmuje konwencję formatu danych NCHW: (batch_size, channels, height, width).

    Python
    import torch
    import torch.nn as nn
    class ResidualConvBlock(nn.Module):
        def __init__(self, in_channels: int, out_channels: int, stride: int = 1):
            super().__init__()
            self.conv1 = nn.Conv2d(
                in_channels, out_channels, kernel_size=3,
                stride=stride, padding=1, bias=False
            )
            self.bn1 = nn.BatchNorm2d(out_channels)
            self.relu = nn.ReLU(inplace=True)
            self.conv2 = nn.Conv2d(
                out_channels, out_channels, kernel_size=3,
                stride=1, padding=1, bias=False
            )
            self.bn2 = nn.BatchNorm2d(out_channels)
            
            # Dopasowanie wymiarów przy zmianie liczby kanałów lub kroku
            self.shortcut = nn.Sequential()
            if stride != 1 or in_channels != out_channels:
                self.shortcut = nn.Sequential(
                    nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
                    nn.BatchNorm2d(out_channels)
                )
        def forward(self, x: torch.Tensor) -> torch.Tensor:
            residual = self.shortcut(x)
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.bn2(self.conv2(out))
            out += residual
            return self.relu(out)
    # Weryfikacja kształtu wejścia i wyjścia
    x = torch.randn(8, 64, 56, 56) # NCHW
    block = ResidualConvBlock(in_channels=64, out_channels=128, stride=2)
    y = block(x)
    print(f"PyTorch output shape: {y.shape}") # Zwraca: torch.Size([8, 128, 28, 28])
    

    Wzorzec w środowisku TensorFlow / Keras:

    TensorFlow domyślnie przetwarza dane w układzie NHWC: (batch_size, height, width, channels).

    Python
    import tensorflow as tf
    from tensorflow.keras import layers
    class TFResidualConvBlock(layers.Layer):
        def __init__(self, out_channels: int, stride: int = 1, **kwargs):
            super().__init__(**kwargs)
            self.out_channels = out_channels
            self.stride = stride
        def build(self, input_shape):
            in_channels = input_shape[-1]
            self.conv1 = layers.Conv2D(
                self.out_channels, kernel_size=3, strides=self.stride,
                padding="same", use_bias=False
            )
            self.bn1 = layers.BatchNormalization()
            self.relu = layers.Activation("relu")
            self.conv2 = layers.Conv2D(
                self.out_channels, kernel_size=3, strides=1,
                padding="same", use_bias=False
            )
            self.bn2 = layers.BatchNormalization()
            
            if self.stride != 1 or in_channels != self.out_channels:
                self.shortcut = tf.keras.Sequential([
                    layers.Conv2D(self.out_channels, kernel_size=1, strides=self.stride, use_bias=False),
                    layers.BatchNormalization()
                ])
            else:
                self.shortcut = lambda x: x
        def call(self, inputs, training=False):
            residual = self.shortcut(inputs)
            x = self.conv1(inputs)
            x = self.bn1(x, training=training)
            x = self.relu(x)
            x = self.conv2(x)
            x = self.bn2(x, training=training)
            return self.relu(x + residual)
    # Weryfikacja kształtu wejścia i wyjścia
    x_tf = tf.random.normal((8, 56, 56, 64)) # NHWC
    tf_block = TFResidualConvBlock(out_channels=128, stride=2)
    y_tf = tf_block(x_tf)
    print(f"TensorFlow output shape: {y_tf.shape}") # Zwraca: (8, 28, 28, 128)
    

    Zastosowania praktyczne i wytyczne inżynieryjne

    Sieci splotowe pozostają wysoce wydajnym wyborem w architekturach produkcyjnych ze względu na deterministyczny profil pamięciowy i natywne wsparcie dla akceleratorów sprzętowych (Tensor Cores):

    • Segmentacja obrazów w systemach brzegowych: Połączenie splotów depthwise separable z dylatacją pozwala na budowę kompaktowych sieci typu encoder-decoder (np. ENet, U-Net) zdolnych do działania na platformach wbudowanych w czasie rzeczywistym (>30 FPS).
    • Przetwarzanie szeregów czasowych i telemetrii: Konwolucje 1D z rosnącą wykładniczo dylatacją (D = 1, 2, 4, 8, \dots) pozwalają na modelowanie długoterminowych zależności w sygnałach wibroakustycznych maszyn przemysłowych czy elektrokardiografii, oferując równoległe przetwarzanie wykluczające rekurencyjne wąskie gardła sieci LSTM.
    • Wytyczna implementacyjna: Stosując BatchNorm2d bezpośrednio po Conv2d, należy zawsze wyłączyć wyraz wolny w warstwie splotowej (bias=False), ponieważ statystyka odejmowania średniej w procesie normalizacji całkowicie redukuje stały offset, oszczędzając parametry i operacje.

    Źródła

    Dodaj komentarz

    Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

    Powiązane posty

    Powrót do góry