6. Dane MNIST
W poprzednim rozdziale przedstawiona została biblioteka NeuralNetworks - jej struktura, kluczowe komponenty oraz sposób definiowania, trenowania i wykorzystywania modeli sieci neuronowych. Omówione zostały elementy niskopoziomowe, takie jak operacje macierzowe i funkcje straty, oraz wyższego poziomu abstrakcje obejmujące modele, warstwy, operacje, optymalizatory oraz proces trenowania. Celem tamtego rozdziału było przedstawienie względnie elastycznego, ogólnego narzędzia, które ułatwi dalszą, praktyczną pracę z sieciami neuronowymi bez konieczności każdorazowego implementowania ich od podstaw.
W niniejszym rozdziale przejdziemy od opisu biblioteki do jej praktycznego zastosowania. Jako przykład wykorzystamy klasyczny zbiór danych MNIST, zawierający obrazy odręcznie pisanych cyfr, który tradycyjnie stanowi punkt odniesienia w zadaniach klasyfikacji obrazów.
Analiza danych MNIST zostanie przeprowadzona z wykorzystaniem sieci opartych o warstwy gęste (ang. dense layers, fully connected layers) oraz z wykorzystaniem sieci konwolucyjnych.
6.1. Zbiór danych MNIST
Podobnie jak zbiór Boston Housing, dane MNIST są powszechnie dostępne i stosowane w literaturze. Zbiór ten zawiera 70 000 obrazów odręcznie pisanych cyfr (0-9), podzielonych na 60 000 obrazów treningowych i 10 000 obrazów testowych. Każdy obraz ma rozmiar 28x28 pikseli i jest reprezentowany jako macierz wartości szarości (od 0 do 255). Celem zadania jest sklasyfikowanie każdego obrazu do jednej z dziesięciu klas odpowiadających cyfrom od 0 do 9 (problem klasyfikacji wieloklasowej z pojedynczą etykietą, ang. multi-class, single-label classification problem).
W naszych eksperymentach będziemy pracować na znacznie mniejszym zbiorze uczącym, zawierającym jedynie 20 000 obrazów (plus 10 000 obrazów testowych). Zbiór ten znajduje się na GitHub.

Rysunek 6.1. Przykładowe obrazy z zestawu danych MNIST (źródło: Wikipedia)
6.2. Warstwy gęste
6.2.1. Architektura modelu
W naszych eksperymentach wykorzystamy prostą sieć neuronową zbudowaną z warstw gęstych. Architektura modelu będzie następująca:
class MnistModel(SeededRandom? random)
: BaseModel<float[,], float[,]>(new SoftmaxCrossEntropyLoss(), random)
{
private const float Dropout1KeepProb = 0.85f;
private const float Dropout2KeepProb = 0.85f;
private readonly Operation2D activationFunction1 = new ReLU();
private readonly Operation2D activationFunction2 = new LeakyReLU();
protected override LayerListBuilder<float[,], float[,]> CreateLayerListBuilder()
{
GlorotInitializer initializer = new(Random);
Dropout2D? dropout1 = new(Dropout1KeepProb, Random);
Dropout2D? dropout2 = new(Dropout2KeepProb, Random);
return AddLayer(new DenseLayer(178, activationFunction1, initializer, dropout1))
.AddLayer(new DenseLayer(46, activationFunction2, initializer, dropout2))
.AddLayer(new DenseLayer(10, new Linear(), initializer));
}
}
Listing 6.1. Definicja modelu MNIST z warstwami gęstymi
Model składa się z trzech warstw gęstych. Pierwsza warstwa zawiera 178 neuronów z funkcją aktywacji ReLU, druga warstwa ma 46 neuronów z funkcją aktywacji Leaky ReLU, a trzecia warstwa wyjściowa składa się z 10 neuronów (po jednym na każdą klasę cyfr) z liniową funkcją aktywacji. Dla pierwszych dwóch warstw zastosowano mechanizm dropout z prawdopodobieństwem zachowania neuronu równym 0.85, co pomaga w redukcji przeuczenia modelu. Funkcja straty użyta w modelu to Softmax Cross-Entropy, odpowiednia dla zadań klasyfikacji wieloklasowej.
W modelu zastosowano dwie różne funkcje aktywacji: ReLU (Rectified Linear Unit) oraz Leaky ReLU, jednak można eksperymentować z innymi funkcjami, takimi jak Sigmoid czy Tanh, aby ocenić ich wpływ na wyniki modelu.
Inicjalizacja wag
Dropout
Funkcje straty
Użytą w naszym modelu funkcją straty jest Softmax Cross-Entropy, która jest powszechnie stosowana w zadaniach klasyfikacji wieloklasowej.
6.2.2. Proces trenowania
6.2.2.1. Przygotowanie danych
6.2.2.2. Wyniki trenowania
6.3. Sieć konwolucyjna
Sieć konwolucyjna jest specjalnym rodzajem sieci neuronowej, która jest szczególnie skuteczna w analizie danych o strukturze przestrzennej, takich jak obrazy. W przeciwieństwie do warstw gęstych, które łączą każdy neuron z każdym innym neuronem w poprzedniej warstwie, warstwy konwolucyjne wykorzystują operacje konwolucji, które pozwalają na wykrywanie lokalnych wzorców w danych wejściowych.
Operacja konwolucji przebiega następująco:
- Na wejściu mamy obraz reprezentowany jako macierz pikseli (np. 28x28 dla obrazów MNIST).
- Nakładamy na obraz mały filtr (jądro konwolucyjne), który przesuwamy po obrazie, np. piksel po pikselu, wykonując operację iloczynu skalarnego między wartościami filtra a odpowiadającymi im wartościami pikseli w obrazie.
- Wynikiem tej operacji jest nowa macierz (mapa cech), która reprezentuje wykryte wzorce w obrazie. Pojedynczą mapę cech nazywamy kanałem. W praktyce stosuje się wiele filtrów, co prowadzi do powstania wielu kanałów.
6.3.1. Architektura modelu
6.3.2. Proces i wyniki trenowania
Created: 2025-12-19
Last modified: 2026-01-10
Title: 6. Dane MNIST i warstwy gęste
Tags: [C#] [Sieci neuronowe] [Biblioteka] [NeuralNetworks] [MNIST] [Warstwy gęste] [Dense Layers] [Fully Connected Layers]