IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

MATLAB zlehka - Transfer learning

V předchozím díle jsme si vyzkoušeli, jak je snadné v MATLAB využívat netriviální algoritmy hlubokých neuronových sítí pro klasifikaci obrazů do různých tříd. Pro řádné pochopení tohoto navazujícího dílu doporučuji nejdříve přečíst ten první.

Rozeznávání tvarů neuronovou sítí v MATLAB - Matlab

Dnešním cílem bude vytvořit neuronovou síť, která je schopná rozeznávat mezi čtvercem a kruhem. Není to žádný dechberoucí výsledek a tento problém lze celkem snadno řešit i pomocí klasických algoritmů zpracování obrazu. Důvodem takto jednoduchého příkladu je snadná demonstrace a také snadný způsob, jak vygenerovat trénovací data (obrázky s kruhem a čtvercem). Rozšířit možnosti klasifikace o další tvary (trojúhelník, hvězda, ...) je následně velice triviální. S použitím klasických algoritmů by to už tak snadné nebylo.

Transfer Learning

Při řešení dnešní úlohy si pomůžeme pomocí tzv. Transfer Learning. Česky bychom mohli říci přeneseného naučení (znalosti). Myšlenka je taková, že začínáme již s nějakou natrénovanou neuronovou sítí (například Alexnet, viz minulý díl), která již chápe "jak vypadá svět". Konkrétně Alexnet je naučena na milionech obrázků z tisíce různých tříd. Tuto znalost můžeme využít pro klasifikaci jiných obrazů a nemusíme tak síť učit od píky.

Detail sítě Alexnet - Matlab

Alexnet je složena z 25 vrstev. Prvních 22 slouží jako feature extractor (to, co "chápe jak vypadá svět") a zbylé 3 slouží jako klasifikátor (řekne nám do které z 1000 tříd patří obrázek s danými vlastnostmi, které byly získány z extraktoru). Při transfer learningu si ponecháme extractor, zatímco klasifikační vrstvy nahradíme tak, aby rozeznávaly obrázky do námi zvolených tříd (obdélník, kruh).

Načtení a přenesení Alexnet

V prvním kroku načteme neuronovou síť příkazem alexnet. V případě, že nemáte nainstalovaný patřičný add-on, MATLAB vás upozorní a poskytne odkaz ke stažení.

net = alexnet;
extractorLayers = net.Layers(1:end-3); % všechny vrstvy, kromě třech posledních

Proměnná net má vlastnost Layers se všemi vrstvami, které síť tvoří. Poslední 3 budeme nahrazovat, proto si do extractorLayers nakopírujeme všechny kromě těchto 3. Že jsou to 3 se dá zjisti například příkazem analyzeNetwork(net), kde si můžeme prohlédnout i vlastnosti jednotlivých vrstev. K vrstvám, které jsme odňali z původní Alexnet, přiděláme právě ty tři zodpovědné za klasifikaci. fullyConnectedLayer je vrstva, ve které jsou všechny neurony propojené (ty co přicházejí z extraktoru a ty co jdou dále do softmaxLayer). Zvýšíme learning rate factor, čímž zajistíme rychlejší učení oproti ostatním vrstvám (extraktoru):

layers = [
    extractorLayers
    fullyConnectedLayer(2, 'WeightLearnRateFactor', 20, 'BiasLearnRateFactor', 20)
    softmaxLayer
    classificationLayer];

Dvojka v prvním parametru značí 2 třídy, do kterých budeme klasifikovat. softmaxLayer zařídí, že klasifikace se bude odehrávat v hodnotách od 0 do 1 a součet všech hodnot (v našem případě dvou) bude také 1. To bude výstup poslední klasifikační vrstvy. Výstup je tedy zároveň i pravděpodobností, že klasifikace patří do dané třídy.

Data pro učení

Databázi obrázků, na kterých naučíme neuronovou síť rozeznávat kruhy a obdélníky, si můžeme jednoduše vytvořit. V přibaleném .zip souboru je to skript s názvem tvorba_nahodnych_tvaru.m. Po jeho spuštění dojde k vygenerování 10 obrázků od každého tvaru s náhodnou velikostí, barvou a pozicí.

Skript vytvoří následující složkovou strukturu, každá složka obsahuje 10 tvarů:

složková struktura - Matlab

Nyní si vytvoříme proměnnou imdsTrain, kterou využijeme při trénovaní. imdsTrain obsahuje informace o souborech (jejich cestu) a třídu správné klasifikace (kruh nebo obdélník):

imdsTrain = imageDatastore('imgs_shapes', ... % Obrázky z této složky
    'IncludeSubfolders', true, ... % Ber to z podsložek
    'LabelSource', 'foldernames'); % jako název třídy použij název složky

Funkce imageDatastore() je dostatečně schopná, aby pochopila (řekneme jí to v parametrech), že názvy složek jsou zároveň názvem třídy pro klasifikaci.

Trénink neuronové sítě

Nyní máme architekturu sítě, včetně vah, které jsme převzali z Alexnet. Jsme krůček od toho, abychom mohli spustit trénink. Potřebujeme ještě specifikovat nastavení pro učení:

options = trainingOptions('sgdm','InitialLearnRate',1e-4);

Možností, jak upravit parametry učení, je spousta. Toto je velice zjednodušená varianta s defaultním nastavením většiny parametrů.

Celé učení zařídí funkce trainNetwork(). První parametr je výše vytvořená databáze obrázků. Druhý parametr je poskládaná architektura sítě, kterou jsme definovali dříve (layers). Třetím parametrem jsou specifikované options.

netTransfer = trainNetwork(imdsTrain,layers,options);

Síť se trénuje na dvaceti obrázcích. Ve výstupu uvidíte relativně krátký postup tréninku:

tréninkový progress - Matlab

Během 13 sekund se síť natrénovala na grafické kartě (ta je rychlejší než CPU. Pokud ji máte, MATLAB na ni sám přepne) se 100% přesností. Tréninkový proces prohnal během těch pár sekund každý z 20 obrázků neuronkou 30x. Většinou, když je něco s přesností 100 %, je to podezřelé. Přesnost je navíc na datech, na kterých trénujeme. Toho se snažíme většinou vyvarovat, abychom síť nepřeučili (přeučená síť funguje dobře jen na tréninkových datech). Validační data jsme z postupu kvůli jednoduchosti však vypustili. Jestli je síť naučená správně, zjistíme následovně.

Testování sítě

Z trénovacího procesu nám vznikla proměnná netTransfer, která umí rozeznávat dva tvary. S pomocí funkce classify() jí otestujeme na několika obrázcích. 16 útvarů je naskládáno v jednom .png souboru (také přiložen v .zip archivu). Prvních 8 jsou prosté kruhy a obdélníky, další tvary už tak jasné nejsou:

tvary ke klasifikaci - Matlab

Následující kód, rozseká .png soubor na 16 obrázků, každý zvlášť klasifikuje a připíše k němu výsledek, včetně pravděpodobnosti:

A = imread('shapes16b.png'); % načti obrázek s 16 tvary

% překonvertovat na buňky o velikosti 227x227x3
A_in_cells  = mat2cell(A, [227 227 227 227], [227 227 227 227], [1 1 1]);

ind = 1;
for ii = 1:4 % projít všech 16 obrázků
    for yy = 1:4 % v těchto 2 cyklech
        % složit obrázek z buněk...
        one_shape = cat(3, A_in_cells{ii, yy, 1}, A_in_cells{ii, yy, 2}, A_in_cells{ii, yy, 3});
        [label,score] = classify(netTransfer,one_shape); % vlastní klasifikace
        Classified_images{ind} = insertText(one_shape,[1 1],... % přidání výsledku klasifikace
            cellstr(string(label) + " " + num2str(max(score) * 100) + " %"), 'FontSize', 26);
        ind = ind + 1;
    end
end

montage(Classified_images) % zobrazení několika obrázků najednou.

Výsledek:

Výsledek klasifikace tvarů neuronovou sítí v MATLAB - Matlab

Kruhy a obdélníky rozeznala neuronová síť s přehledem (a 100% přesností). Jelikož síť není natrénovaná na nic jiného než právě na kruh a obdélník, není třeba schopná rozeznat smajlík (prý kruh), ani prázdnotu (prý obdélník). Ručně kreslený "kruh" a obdélník rozeznala správně. Pokud má obdélník zakulacené rohy příliš, klasifikuje to již jako kruh.

Závěr a pár poznámek

Využili jsme naučenou neuronovou síť Alexnet k tvorbě vlastní neuronové sítě, jež je schopna rozeznat čtverce od koleček. Článek je sepsán a kód konstruován tak, aby co nejrychlejším způsobem demonstroval danou problematiku a ukázal vše jednoduše a bez zevrubných popisných částí. Téměř každému vysvětlení by mohlo předcházet "zjednodušeně řečeno".

Čas učícího procesu je závislý na velikosti učící databáze, zvolených parametrech a železe, na kterém se učení provádí. Zde to zabralo 13 sekund, což se řádově liší od scénářů skutečného světa (třeba i dny, týdny).

Vzniklá neuronová síť se dá snadno rozšířit. V prvním kroku třeba o více tvarů. Pouze se přidá další složka s předpřipravenými obrázky a změní se počet neuronů ve fullyConnectedLayer.

Obrázky tvarů se dají snadno nahradit jinými (například jablko vs hruška vs pomeranč nebo zatažená obloha vs slunečno vs déšť), což nás už přibližuje k nějakému skutečnému scénáři.

Další podstatnou část, která si zaslouží úpravu, je tréninkový proces. options mají spoustu možností, mezi něž patří třeba databáze validačních dat, počet opakování, změna algoritmu, atd.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 10x (42.91 kB)
Aplikace je včetně zdrojových kódů

 

Všechny články v sekci
Matlab
Článek pro vás napsal tesař.tech
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Autor se věnuje dýchání přibližně celý život
Aktivity