Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 zľahka - Transfer learning

V predchádzajúcom diele sme si vyskúšali, ako je ľahké v MATLAB využívať netriviálne algoritmy hlbokých neurónových sietí pre klasifikáciu obrazov do rôznych tried. Pre riadne pochopenie tohto nadväzujúceho dielu odporúčam najskôr prečítať ten prvý.

Rozoznávanie tvarov neurónovou sietí v MATLAB - Matlab

Dnešným cieľom bude vytvoriť neurónovou sieť, ktorá je schopná rozoznávať medzi štvorcom a kruhom. Nie je to žiadny dychberúci výsledok a tento problém sa dá celkom ľahko riešiť aj pomocou klasických algoritmov spracovania obrazu. Dôvodom takto jednoduchého príkladu je ľahká demonštrácie a tiež jednoduchý spôsob, ako vygenerovať trénovací dáta (obrázky s kruhom a štvorcom). Rozšíriť možnosti klasifikácie o ďalšie tvary (trojuholník, hviezda, ...) je následne veľmi triviálne. S použitím klasických algoritmov by to už tak jednoduché nebolo.

Transfer Learning

Pri riešení dnešnej úlohy si pomôžeme pomocou tzv. Transfer Learning. Slovensky by sme mohli povedať preneseného naučenia (znalosti). Myšlienka je taká, že začíname už s nejakou natrénované neurónovou sietí (napríklad Alexnet, pozri minulý diel), ktorá už chápe "ako vyzerá svet". Konkrétne Alexnet je naučená na miliónoch obrázkov z tisíc rôznych tried. Túto znalosť môžeme využiť pre klasifikáciu iných obrazov a nemusíme tak sieť učiť od piky.

Detail siete Alexnet - Matlab

Alexnet je zložená z 25 vrstiev. Prvých 22 slúži ako feature extractor (to, čo "chápe ako vyzerá svet") a zvyšné 3 slúži ako klasifikátor (povie nám do ktorej z 1000 tried patrí obrázok s danými vlastnosťami, ktoré boli získané z extraktora). Pri transfer learningu si ponecháme extractor, zatiaľ čo klasifikačné vrstvy nahradíme tak, aby musia rozpoznať obrázky do nami zvolených tried (obdĺžnik, kruh).

Načítanie a prenesenie Alexnet

V prvom kroku načítame neurónovou sieť príkazom alexnet. V prípade, že nemáte nainštalovaný patričný add-on, MATLAB vás upozorní a poskytne odkaz na stiahnutie.

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

Premenná net má vlastnosť Layers so všetkými vrstvami, ktoré sieť tvoria. Posledné 3 budeme nahrádzať, preto si do extractorLayers nakopírujeme všetky okrem týchto 3. Že sú to 3 sa dá zisti napríklad príkazom analyzeNetwork(net), kde si môžeme prezrieť aj vlastnosti jednotlivých vrstiev. K vrstvám, ktoré sme odňali z pôvodnej Alexnet, prirobíme práve tie tri zodpovedné za klasifikáciu. fullyConnectedLayer je vrstva, v ktorej sú všetky neuróny prepojené (tých čo prichádzajú z extraktora a tých čo idú ďalej do softmaxLayer). Zvýšime learning rate factor, čím zabezpečíme rýchlejší učenia oproti ostatným vrstvám (extraktore):

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

Dvojka v prvom parametri značí 2 triedy, do ktorých budeme klasifikovať. softmaxLayer zariadi, že klasifikácia sa bude odohrávať v hodnotách od 0 do 1 a súčet všetkých hodnôt (v našom prípade dvoch) bude tiež 1. To bude výstup poslednej klasifikačnej vrstvy. Výstup je teda zároveň aj pravdepodobnosťou, že klasifikácia patrí do danej triedy.

Dáta pre učenie

Databázu obrázkov, na ktorých naučíme neurónovou sieť rozoznávať kruhy a obdĺžniky, si môžeme jednoducho vytvoriť. V pribalenom .zip súboru je to skript s názvom tvorba_nahodnych_tvaru.m. Po jeho spustení dôjde k vygenerovaniu 10 obrázkov od každého tvaru s náhodnou veľkosťou, farbou a pozíciou.

Skript vytvorí nasledujúce zložkovú štruktúru, každá zložka obsahuje 10 tvarov:

zložková štruktúra - Matlab

Teraz si vytvoríme premennú imdsTrain, ktorú využijeme pri trénovaní. imdsTrain obsahuje informácie o súboroch (ich cestu) a triedu správnej klasifikácie (kruh alebo obdĺžnik):

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

Funkcia imageDatastore() je dostatočne schopná, aby pochopila (povieme jej to v parametroch), že názvy zložiek sú zároveň názvom triedy pre klasifikáciu.

Tréning neurónové siete

Teraz máme architektúru siete, vrátane váh, ktoré sme prevzali z Alexnet. Sme krôčik od toho, aby sme mohli spustiť tréning. Potrebujeme ešte špecifikovať nastavenie pre učenie:

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

Možností, ako upraviť parametre učenia, je veľa. Toto je veľmi zjednodušená varianta s defaultným nastavením väčšiny parametrov.

Celé učenie zariadi funkcie trainNetwork(). Prvý parameter je vyššie vytvorená databáza obrázkov. Druhý parameter je poskladaná architektúra siete, ktorú sme definovali skôr (layers). Tretím parametrom sú špecifikované options.

netTransfer = trainNetwork(imdsTrain,layers,options);

Sieť sa trénuje na dvadsiatich obrázkoch. Vo výstupe uvidíte relatívne krátky postup tréningu:

tréningový progress - Matlab

Počas 13 sekúnd sa sieť natrénovali na grafickej karte (tá je rýchlejší ako CPU. Ak ju máte, MATLAB na ňu sám prepne) so 100% presnosťou. Tréningový proces prehnal počas tých pár sekúnd každý z 20 obrázkov neuronkou 30x. Väčšinou, keď je niečo s presnosťou 100%, je to podozrivé. Presnosť je navyše na dátach, na ktorých trénujeme. Toho sa snažíme väčšinou vyvarovať, aby sme sieť nepřeučili (preučené sieť funguje dobre len na tréningových dátach). Validačný dáta sme z postupu kvôli jednoduchosti však vypustili. Ak je sieť naučená správne, zistíme nasledovne.

Testovanie siete

Z trénovacího procesu nám vznikla premenná netTransfer, ktorá vie rozoznávať dva tvary. S pomocou funkcie classify() jej otestujeme na niekoľkých obrázkoch. 16 útvarov je naskladaný v jednom .png súboru (tiež priložený v .zip archíve). Prvých 8 sú prosté kruhy a obdĺžniky, ďalšie tvary už tak jasné nie sú:

tvary ku klasifikácii - Matlab

Nasledujúci kód, rozseká .png súbor na 16 obrázkov, každý zvlášť klasifikuje a pripíše k nemu výsledok, vrátane pravdepodobnosti:

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ýsledok:

Výsledok klasifikácia tvarov neurónovou sietí v MATLAB - Matlab

Kruhy a obdĺžniky rozoznala neurónové siete s prehľadom (a 100% presnosťou). Keďže sieť nie je natrénovaná na nič iné ako práve na kruh a obdĺžnik, nie je potrebné schopná rozoznať smajlík (vraj kruh), ani prázdnotu (vraj obdĺžnik). Ručne kreslený "kruh" a obdĺžnik rozoznala správne. Pokiaľ má obdĺžnik zaoblené rohy príliš, klasifikuje to už ako kruh.

Záver a pár poznámok

Využili sme naučenú neurónovou sieť Alexnet k tvorbe vlastnej neurónové siete, ktorá je schopná rozoznať štvorca od koliesok. Článok je spísaný a kód konštruovaný tak, aby čo najrýchlejším spôsobom demonštroval danú problematiku a ukázal všetko jednoducho a bez komplexných opisných častí. Takmer každému vysvetlenie by mohlo predchádzať "zjednodušene povedané".

Čas učiaceho procesu je závislý od veľkosti učiacej databázy, zvolených parametroch a železe, na ktorom sa učenie uskutočňuje. Tu to zabralo 13 sekúnd, čo sa rádovo líši od scenárov skutočného sveta (napríklad aj dni, týždne).

Vzniknutá neurónové siete sa dá ľahko rozšíriť. V prvom kroku treba o viac tvarov. Iba sa pridá ďalšia zložka s predpripravenými obrázkami a zmení sa počet neurónov vo fullyConnectedLayer.

Obrázky tvarov sa dajú ľahko nahradiť inými (napríklad jablko vs hruška vs pomaranč alebo zatiahnutá obloha vs slnečno vs dážď), čo nás už približuje k nejakému skutočnému scenári.

Ďalšie podstatnú časť, ktorá si zaslúži úpravu, je tréningový proces. options majú veľa možností, medzi ktoré patrí napríklad databázy validačných dát, počet opakovaní, zmena algoritmu, atď.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 10x (42.91 kB)
Aplikácia je vrátane zdrojových kódov

 

Všetky články v sekcii
Matlab
Článok pre vás napísal tesař.tech
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje dýchání přibližně celý život
Aktivity