Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu

20.04 | 09:39 | Žumpa | bedňa

V tomto zápisku si vyskúšame naprogramovať svoju prvú neurónovú sieť na rozpoznávanie obrazu. Pre nedočkavých je na konci v TL;DR hotový príklad.

Predchádzajúce zápisky

Data augmentation
Vytvorenie datasetu
Prvé kroky k programovaniu
Umelá inteligencia v rozpoznávaní obrazu
Umelá inteligencia nás všetkých zabije

Ideme na to

Budeme vychádzať z toho čo som písal v minulých zápiskoch ako sa učí malé dieťa rozpoznávať veci vo svojom okolí. Čiže ju naučíme rozpoznávať svoju mamu a to čo naša mama nie je (v našom prípade Angelina Jolie :)). To čo naša mama nie je môže byť postieľka, stolička, fľaška ...

Použijeme neurónovú sieť ktorú som už spomínal a to konvolučnú neurónovú sieť z Wikipedie.

Nedostatky nášho postupu

1.) Ako som už spomínal pre dobré naučenie siete potrebujeme okolo tisíc obrázkov, ja som náhodne stiahol 22 obrázkov z ktorých som ešte jeden zmazal, pretože to bol len zarámovaný obrázok, čo mohlo viac ublížiť ako pomôcť. Potom som pomocou data augmentation vygeneroval (21 x 25 + 21) x 2 = 1092 obrázkov.

2.) Tá sieť je dosť plytká, má len sedem vrstiev, čo v niektorých prípadoch môže byť aj dosť, ale pretože riešime trochu komplexnejší problém, asi nebude fungovať úplne perfektne.

Príprava

Dostatok obrázkov Angeliny Jolie sme si už vytvorili cez data augmentation. Pre dobré výsledky budeme potrebujeme sieti ukázať, čo všetko mama nie je. Takže si posťahujeme pár obrázkov detských fľašiek, stoličiek, postieľok a všetkého možného čo mama nie je.

Začíname programovať

Pôvodný zámer som značne zredukoval, pretože sa to začalo rozťahovať cez tri zápisky. Takže si to skrátime na nejakú únosnú formu.

Naklonujeme si už hotový projekt z GitHubu:
git clone https://github.com/bedna-KU/First-Convolutional_neural_network.git
Vstúpime do projektu:
cd First-Convolutional_neural_network
V projekte máme štyri skripty:
divide.py - Rozdelí obrázky na train a test
predict.py - Predpoveď jedného obrázka
predict_live.py - Predpoveď obrázkov na desktope - live video
train.py - Učenie siete

Rozdelenie obrázkov na trénovacie a testovacie

Musíme mať dva priečinky s obrázkami a to mom a no_mom Obrázky si roztriedime do štruktúry pre trénovacie a testovacie obrázky, tak ideálne v pomere 80% ku 20%. Na to tu máme skript divide.py.
python3 divide.py --test 20 --input cesta_k_obrázkom/mom --output data
a ešte rozdelíme obrázky kde nie je mama na 80% ku 20%:
python3 divide.py --test 20 --input cesta_k_obrázkom/no_mom --output data
Štruktúra priečinku bude vyzerať takto:
├── LICENCE
├── README.md
├── data
│   ├── test
│   │   ├── mom
│   │   │   ├── image_mom_1.jpg
│   │   │   └── ...
│   │   └── no_mom
│   │       ├── image_no_mom_1.jpg
│   │       └── ...
│   └── train
│       ├── mom
│       │   ├── image_mom_1a.jpg
│       │   └── ...
│       └── no_mom
│           ├── image_no_mom_1a.jpg
│           └── ...
├── divide.py
├── live_predict_keras.gif
├── predict_live.py
├── predict.py
└── train.py
Prepínače pre skript divide,py:
--test Počet percent pre testovacie dáta
--input Vstupný priečinok s obrázkami
--output Výstupný priečinok pre train a test

Učenie konvolučnej neurónovej sieťe

Na učenie slúži skript train.py. Na začiatku skriptu sa načítajú všetky potrebné knižnice. Riadok:
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
Potlačí všetky otravné hlášky z TensorFlow.

V časti PARAMETERS si nastavíme parametre pre učenie:
####################################################################
# PARAMETERS
####################################################################

IMG_WIDTH = 50			# Šírka vstupného obrázka
IMG_HEIGHT = 50			# Výška vstupného obrázka
IMG_COLOR_DEPTH = 1		# Farebná hľbka
INPUT_SHAPE = (IMG_HEIGHT,
               IMG_WIDTH,
               IMG_COLOR_DEPTH)	# Vstupný tvar obrázkov
NUM_CLASSES = 2			# Počet tried obrázkov
BATCH_SIZE = 32			# Dávka naraz spracovaných obrázkov
EPOCHS = 20			# Počet opakovaní učenia
WEIGHTPATH = "weights.hdf5"	# Súbor kde sa uložia váhy

###################################################################
Funkcia def create_model (input_shape, num_classes): nám definuje celý model. Tento model sme si popísali tu.

Čo nám pribudlo je táto časť s nastaveniami:
model.compile (loss = categorical_crossentropy,
	   optimizer = Adam (),
	   metrics = ['accuracy'])
Jedná sa o nastavenia a heuristiky ktoré som už spomínal tu, úplne dole. Loss a metrics nájdete vysvetlené tu a optimizéry tu.

Funkcia def load_dataset (): nahrá dataset a spraví s ním operácie ktoré sme nastavili.
Tu sa bajt (uint8) prevedie na hodnoty od nuly po jednotku:
datagen = ImageDataGenerator (rescale = 1. / 255)
V kóde:
train_data = datagen.flow_from_directory (os.path.join (input, 'train'),
                                          target_size = (IMG_HEIGHT, IMG_WIDTH),
                                          color_mode = 'grayscale',
                                          class_mode = 'categorical',
                                          batch_size = BATCH_SIZE)
je uvedená cesta odkiaľ sa obrázky majú načítať, na akú veľkosť sa majú obrázky skonvertovať, že sa budú obrázky načítavať v odtieňoch šedej, v akej forme triedy a koľko obrázkov naraz.

Teraz si uložíme páry trieda a číslo pre neskoršie použitie pri predikcií do JSON súboru:
classes = train_data.class_indices
cprint (train_data.class_indices, 'yellow', attrs = ['bold'])
json.dump (classes, open ("classes.json", 'w'))
Samotné učenie sa spustí funkciou:
def train_model ():
    cprint ("Start learning", 'yellow', attrs = ['bold'])
        tst = model.fit_generator (train_data,
                                   validation_data = test_data,
	                           steps_per_epoch = train_data.n // BATCH_SIZE,
                                   validation_steps = (test_data.n // BATCH_SIZE),
                                   epochs = EPOCHS,
                                   callbacks = callbacks)
train_data Sú trénovacie obrázky
validation_data Sú obrázky na ktorých sa overí naučenie siete
steps_per_epoch Na koľko krokov sa má rozdeliť jedno kolo učenia
validation_steps Na koľko krokov sa má rozdeliť overenie správnosti predpovedania siete
epochs Počet kôl učenia sa
callbacks Spustí každé kolo nejakú funkciu.

Okrem spomínanej možností fit_generator máme pre učenie sa neurónovej siete ešte možnosť fit.

Učenie neurónky spustíme skriptom train.py:
python3 train.py --input data
Prepínačom --input určíme priečinok, kde máme náš dataset.

Na notebooku Lenovo ThinkPad E560 mi naučenie siete trvalo približne 20 minút.

Predikcia s konvolučnou neurónovou sieťou

Na odhad toho čo je na obrázku slúži skript predict.py.

Rozoberieme si čo v ňom nájdeme:
Funkcia def read_classes (): načíta triedy obrázkov.
Funkcia def create_model (input_shape, num_classes): načíta model, tu nič nového nie je.
Funkcia def load_weights (): načíta naučené váhy.
Funkcia def load_image (): načíta obrázok na predikciu v odtieňoch šedej.

Pre nás zaujímavá a nová vec sa nachádza vo funkcií def predict (image):, ktorá slúži na samotnú predikciu obrázka:
def predict (image):
	img_in = cv2.resize (image, dsize = (IMG_HEIGHT, IMG_WIDTH), interpolation = cv2.INTER_CUBIC)
	img_in = img_in.astype ('float') / 255
	img_in = np.expand_dims (img_in, axis = 0)
	img_in = np.expand_dims (img_in, axis = 3)
	result = model.predict (img_in, batch_size = BATCH_SIZE, verbose = 1)
	class_name = classes[np.argmax (result)]
	return class_name
Na začiatku funkcie sa prevzorkuje obrázok na veľkosť vstupu siete.
Ďalej sa prevedú bajty na desatinné čísla v rozsahu 0 až 1.
Pomocou np.expand_dims expandujeme dimenzie obrázka na tvar (batch, 50, 50, 1) = vstup siete s dávkou (batch).
Samotnú predikciu robí model.predict, jediný povinný parameter je vstupný obrázok. Vráti sa nám ndarray s pravdepodobnosťou pre každú triedu.
Predikovanú triedu nám vráti classes[np.argmax (result)]. V našom prípade to bude mom, alebo no_mom.
Funkcia def draw_image (image): nám len ukáže obrázok ktorí sme dali na predikciu.

Teraz si predikciu spustíme:
python3 predict.py image.jpg
image.jpg si nahradíme názvom nejakého obrázka.

Vidíme že predikcia trvala 36 milisekúnd a rozpoznala, že to mama nie je.

Live predikcia s konvolučnou neurónovou sieťou

Skript pre live predikciu nájdeme v súbore predict_live.py.

Funguje to tak, že si v našom obľúbenom internetovom vyhľadávači dáme vyhľadávať obrázky zmenšíme ho na polovicu plochy a umiestnime ho vľavo ako na obrázku a vyhodnocovanie prebieha v pravej polovici obrazovky. Predikcia je rovnaká ako s jedným obrázkom, akurát tu sa obrazovka rozseká na obdĺžniky veľkosti 159 x 180 pixelov. Keď sa zobrazí plný červený obdĺžnik, tak sa predpovedá, že to nie je mama a keď zelený rámik, tak že to je mama.

Skript spustíme pomocou príkazu:
python3 predict_live.py

TL;DR

Táto časť je pre tých čo nechcú nič riešiť, len si chcú vyskúšať umelú inteligenciu na rozpoznávanie obrazu.

Naklonujeme si hotový projekt:
git clone https://github.com/bedna-KU/First-Convolutional_neural_network.git
Vstúpime do projektu:
cd First-Convolutional_neural_network
Upgradneme pip:
python3 -m pip install --upgrade pip
Nainštalujeme závislosti:
python3 -m pip install -r requirements.txt
Stiahneme si naučené váhy:
wget https://downloads.sourceforge.net/project/example-dataset/weights.hdf5
Vytvoríme si priečinok data:
mkdir data
Vstúpime do priečinka:
cd data
Stiahneme dataset:
wget https://downloads.sourceforge.net/project/example-dataset/data.zip
Rozbalíme dataset:
unzip data
Vrátime sa do root projektu:
cd ..
Live predikciu spustíme príkazom:
python3 predict_live.py
Ak si chceme vyskúšať spustiť učenie:
python3 train.py --input data

Záver

Základom úspechu v rozpoznávaní obrazu konvolučnými neurónovými sieťami je dostatočne veľký počet obrázkov pre každú rozpoznávanú kategóriu, čo sme porušili a umelo sme z 21 obrázkov vyrobili 1092. Nejak nám sieť funguje, ale proste bude chybovať.

Použili sme dosť plytkú sieť, len s dvomi konvolučnými vrstvami, bežne ich bývajú desiatky. Takže keď si to zhrnieme, spravili sme všetko zle, ale nejak nám to trochu funguje :-)

Ak sa chceme posunúť niekam ďalej potrebujeme podľa mojich skúseností minimálne tristo obrázkov a na ne nasadiť data augmentation a vytvoríme si napríklad tisícdvesto obrázkov.

Môžeme pridať ďalšie konvolučné vrstvy. V train.py sú zakomentované. Ďalej môžeme pre dve kategórie, čo je náš prípad, namiesto softmaxu použiť sigmoid. Môžeme sa pohrať s veľkosťou vstupu a podobne.

Prípadne môžeme použiť už nejaký hotový model z Keras.

Prílohy



    • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 10:00
      Avatar debian+   Návštevník

      User Mario?

    • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 10:18
      Avatar WlaSaTy   Návštevník

      Pekné. Vedelo by sa to použiť aj na identifikáciu duplikátnych bobrázkov, s vyhdnotením najkvalitnejšieho? A bez uscalingu a zbierky vodoznakov.

      • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 11:06
        Avatar bedňa LegacyIce-antiX  Administrátor

        Aby sieť usúdila ktorý obrázok je kvalitnejší, chcelo by to veľa obrázkov, kde by si každému dal počet hviezdičiek. Ak sa ti do toho chce, tak poďme na to. Kód ti k tomu naťukám :-)

        Nejaké pokusy som už na nete videl, ale neskúšal.

        Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
        • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 11:34
          Avatar WlaSaTy   Návštevník

          Myslel som lepšie rozlíšenie a menšie zrno.

          Tie hviezdičky by po verejnom trénovaní skončili inklinujúc ku falošnému hdr. Viac basov, lepšia muzika kámo. (Sarkazmus)

          • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 12:42
            Avatar bedňa LegacyIce-antiX  Administrátor

            Pravdu povediac ja nie som odborník na digitálne fotky, to by musel niekto navrhnúť metriku, aké parametre sledovať. Ale viem si predstaviť, že by to šlo aj bez AI. Napr. na meranie šumu použiť scikit-image estimate_sigma

            Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
            • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 12:59
              Avatar WlaSaTy   Návštevník

              Myslel som vybratie fotky z bežného životného cyklu. Niekto nafotí strašidelného pavúka a dá na 9gag. Tam si to niekto pozrie na mobile. Keďže sa mu nechce kliknúť na "uložiť obrázok", tak stlačí Power+VolDown aby urobil snímok obrazovky. Ten sa mu objaví v Notifikáciách a odtiaľ tú akoby fotku nazdieľa na Facebook. Tam si tú fotku niekto zoberie, stiahne a zväčší v fotoobchode na 4k, a nahrá na rouming kde pribudne vodoznak. Tam to nájde ďalší, a pridá motivačný tekst so smajlíkami a postne na zomri.

              Vo výsledku to vyzerá ako keď premietaš diapozitív na pokrčený pauzák. A teraz uhádni ktorý obrázok z toho je najkvalitnejší.

              • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 13:35
                Avatar bedňa LegacyIce-antiX  Administrátor

                Aha, to by šlo.

                Možno niekedy, keď sa budem moc nudiť :)

                Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
                • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 15:25
                  Avatar WlaSaTy   Návštevník

                  A v druhej generácii SW by si mohol urobiť detekciu širokouhlých filmov, ktoré niekto nahrával z telky mobilom ktorý mal v ruke, a potom do toho dorobil okraje aby sa to dalo pozerať na výšku bez otočenia telefónu.

    • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 12:16
      Avatar debian+   Návštevník

      Nemas tam uvedene zavistlosti, ze co treba mat vsetko nainstalovane.

      • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 12:42
        Avatar bedňa LegacyIce-antiX  Administrátor

        Mno môžem doplniť.

        Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
        • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 13:08
          Avatar debian+   Návštevník

          Dopln. Lebo to jedine chyby v TL;DR.

          • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 01.05 | 09:33
            Avatar bedňa LegacyIce-antiX  Administrátor

            Doplnené.

            Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
            • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 01.05 | 09:39
              Avatar debian+   Návštevník
              python3 -m pip install -r requirements.txt

              Sikovne.

        • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 20.04 | 21:34
          Avatar debian+   Návštevník

          Alebo pridat link na http://linuxos.sk/blog/zumpa/detail/umela-inteligencia-/, kde spominas instalaciu.

    • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 24.04 | 16:54
      Avatar valgan Devuan / amd 64  Používateľ

      Ahoj,

      Mna by zaujimalo, aky silny hardware clovek potrebuje,aby si to mohol vyskusat?

      • RE: Umelá inteligencia - prvý praktický príklad v rozpoznávaní obrazu 24.04 | 17:49
        Avatar bedňa LegacyIce-antiX  Administrátor

        HW nemusí byť vôbec silný, jediná podmienka je, aby nebol moc technologicky zastaralý, pretože sa využívajú niektoré špeciálne "moderné" inštrukcie procesorov aby sa celý ten proces urýchlil. Čiže na jeden tik procesoru dokáže spracovať viac informácií ako bežné inštrukcie.

        Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org