12 KiB
Uczenie maszynowe – zastosowania
13. Splotowe sieci neuronowe (CNN)
Konwolucyjne sieci neuronowe wykorzystuje się do:
- rozpoznawania obrazu
- analizy wideo
- innych zagadnień o podobnej strukturze
Innymi słowy, CNN przydają się, gdy mamy bardzo dużo danych wejściowych, w których istotne jest ich sąsiedztwo.
Warstwy konwolucyjne
Dla uproszczenia przyjmijmy, że mamy dane w postaci jendowymiarowej – np. chcemy stwierdzić, czy na danym nagraniu obecny jest głos człowieka.
Tak wygląda nasze nagranie:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-9-xs.png)
(ciąg próbek dźwiękowych – możemy traktować je jak jednowymiarowe „piksele”)
Najprostsza metoda – „zwykła” jednowarstwowa sieć neuronowa (każdy z każdym):
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-9-F.png)
Wady:
- dużo danych wejściowych
- nie wykrywa własności „lokalnych” wejścia
Chcielibyśmy wykrywać pewne lokalne „wzory” w danych wejściowych.
W tym celu tworzymy mniejszą sieć neuronową (mniej neuronów wejściowych) i _kopiujemy ją tak, żeby każda jej kopia działała na pewnym fragmencie wejścia (fragmenty mogą nachodzić na siebie):
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-9-Conv2.png)
Każda z sieci A ma 2 neurony wejściowe (mało realistycznie).
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-9-Conv3.png)
Każda z sieci A ma 3 neurony wejściowe (wciąż mało realistycznie, ale już trochę bardziej).
Warstwę sieci A nazywamy warstwą konwolucyjną (konwolucja = splot).
Warstw konwolucyjnych może być więcej niż jedna:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-9-Conv2Conv2.png)
W dwóch wymiarach wygląda to tak:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv2-9x5-Conv2.png)
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv2-9x5-Conv2Conv2.png)
Zblizenie na pojedynczą jednostkę A:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv2-unit.png)
Tak definiujemy formalnie funckję splotu dla 2 wymiarów:
$$ \left[\begin{array}{ccc} a & b & c\\ d & e & f\\ g & h & i\\ \end{array}\right] * \left[\begin{array}{ccc} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ \end{array}\right] =\\ (1 \cdot a)+(2 \cdot b)+(3 \cdot c)+(4 \cdot d)+(5 \cdot e)\\+(6 \cdot f)+(7 \cdot g)+(8 \cdot h)+(9 \cdot i) $$
Więcej: https://en.wikipedia.org/wiki/Kernel_(image_processing)
A tak to mniej więcej działa:
![](https://devblogs.nvidia.com/wp-content/uploads/2015/11/Convolution_schematic.gif)
Jednostka warstwy konwolucyjnej może się składać z jednej lub kilku warstw neuronów:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-A.png)
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv-A-NIN.png)
Jeden neuron może odpowiadać np. za wykrywanie pionowych krawędzi, drugi poziomych, a jeszcze inny np. krzyżujących się linii.
Przykładowe filtry, których nauczyła się pierwsza warstwa konwolucyjna:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/KSH-filters.png)
_Pooling
Obrazy składają się na ogół z milionów pikseli. Oznacza to, że nawet po zastosowaniu kilku warstw konwolucyjnych mielibyśmy sporo parametrów do wytrenowania.
Żeby zredukować liczbę parametrów, a dzięki temu uprościć obliczenia, stosuje się warstwy _pooling.
_Pooling to rodzaj próbkowania. Najpopularniejszą jego odmianą jest max-pooling, czyli wybieranie najwyższej wartości spośród kilku sąsiadujących pikseli.
![](https://upload.wikimedia.org/wikipedia/commons/e/e9/Max_pooling.png)
Warstwy _pooling i konwolucyjne można przeplatać ze sobą:
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/Conv2-9x5-Conv2Max2Conv2.png)
_Pooling – idea: nie jest istotne, w którym dokładnie miejscu na obrazku dana cecha (krawędź, oko, itp.) się znajduje, wystarczy przybliżona lokalizacja.
Do sieci konwolucujnych możemy dokładać też warstwy ReLU.
Możliwości konwolucyjnych sieci neuronowych
![](http://colah.github.io/posts/2014-07-Conv-Nets-Modular/img/KSH-results.png)