HTML

Az élet kódjai

Csináld maga. Senki nem csinálja meg helyetted.

Friss topikok

A.I.-val verébre

2022.07.13. 19:55 Travis.CG

A lányomnak vagy egy játéka, amiben egy nyolcszögletű lapon képeket kell keresni. A játék menete, hogy mindenki kap egy csomó lapot, majd egy lapot középre helyezünk. Ha a kezünkben lévő lapon olyan kép van, ami a középen megtalálható lapon is, akkor ledobhatjuk azt középre, és megint kezdődik a párkeresés. Az győz, akinek legelőször fogynak el a lapjai.

A játék során azon gondolkodtam, hogy nem alakulhat-e ki olyan eset, hogy senki nem tud rakni lapot. Azért, hogy ez ne következzen be, biztosítani kell, hogy legalább három lap (ha két játékossal és egy referencia lappal számolva) között legyen legalább egy közös kép.

Azután, ahogy az kutatóéknál lenni szokott, a játékot felváltotta a játék elemzése, aminek lányom egyáltalán nem örült, mert ilyenkor a feleségemmel elkezdünk elmélkedni, kutatási tervet készíteni, stb. A gyereknek meg elmagyarázzuk, hogy ez mennyire fontos neki, de ő valahogy ezt nem értékeli. A kérdés eldöntésére elhatároztam, hogy építek egy gráfot, ahol a csomópontok a lapok lesznek, az élek pedig a közös képet fogják reprezentálni.

Igazából az egész munka 1-2 óra alatt elkészült volna, ha fogom magam és leülök, hogy egyenként átnézzem a lapokat. Fél nap alatt meglettem volna, ha még Excelt is használok :-) De ha már képekkel dolgozunk, miért ne lehetne egy tanuló algoritmust rászabadítani, hogy nézze a képeket helyettem? Az időráfordítást tekintve ez egy elég rossz ötlet volt, tekintve, hogy már több, mint két hónapja ezen szenvedek.

A játékban 73 kép van és 73 lap, laponként 9 képpel. Először lefényképeztem a lapokat. Hogy tovább nehezítsem a saját dolgom, egy fényképen több lap is van. A lapokon különböző orientációban és nagyításban találhatóak a képek. A játék dobozának hátulján van egy felsorolás az összes képről, ezt szintén lefényképeztem, ez lett a referencia.

Gimp segítségével a referencia képeket egyforma méretre hoztam, és amennyire tudtam, a hátteret is egységesítettem. Eredményül lett 73 darab 178x140-es képem. Ezután elkezdtem építeni egy konvolúciós neurális hálót.

Ez a fajta neurális háló igen érdekes, mert konvolúciós kerneleket használnak, hogy a kép különböző jellemzőit megragadják. A konvolúció után a képből egy alacsonyabb felbontású reprezentáció lesz. Egymás után több rétegben is használhatunk konvolúciót, de az utolsó rétegnek egy összesítő rétegnek kell lennie. Ez fogja összegyűjteni az eredményeket.

Ezek a neurális hálók igen bonyolult felépítésűek, de szerencsére Kerasban nagyon egyszerűen használhatjuk őket. Építőkockánként rakhatjuk össze a hálózatot. Mivel nem vagyok jártas, hogy milyen topológiájú hálózatot érdemes használni, ezért ezt vettem alapul. Ez egy jelzőtábla felismerő program akart lenni, ezt alakítottam a saját igényeimnek.

A program lényege az volt, hogy kevés képpel etetjük meg a rendszert, amelyik a kapott képeket véletlenszerűen elforgatja, tükrözi és nagyítja, hogy megnövelje a tanuló adatok mennyiségét. Ezzel biztosítva, hogy a lapokon is felismerje a képeket bármilyen helyzetben is vannak.

Az első tanítás katasztrofális volt. Habár a rendszer azt állította magáról, hogy 98%-ban pontos, a valóságban a tehénről azt mondta, hogy zöldalma. Sőt, mindenről azt állította, hogy zöldalma. Az első hiba, amit elkövettem, hogy nem volt valódi validációs adat, ezért azt is generáltattam, a tanuló adatokhoz hasonlóan. Itt látszott rögtön, hogy hiába 98%-os a rendszer, ha igazi teszt adattal etettem meg, akkor 16%-ban volt sikeres.

Elkezdtem játszani a paraméterekkel. Beadtam neki 20 ezer képet kategóriánként, de a hatékonyság nem növekedett. Próbáltam a modellt egyszerűsíteni, de ezek a kísérleteim is kudarcot vallottak. Úgy döntöttem, keresek egy példát, amihez adat is van. Sajnos a fenti tutorial nem az igazi, mert emailt, telefonszámot, meg talán még vérmintát is kér, hogy végig lehessen csinálni. Ezért másikat kerestem.

Végigcsináltam egy egyszerű példaprogramot, ami igaz, csak bináris klasszifikációt csinált (elkülönítette a repülőket és a személyautókat), és az meglepően jól működött, pedig csak 200 kép volt, és a tanítási idő sem volt vészes. Közben begépeltem számtalan más példaprogramot is, amik pedig egyszerűen nem működtek. Dobálták össze-vissza a hibákat. Egy részük csak más verziószámú Tensorflow-t igényelt, de elég sok valóban hibás kód volt. Többek között az első is, ami alapján a saját progimat összehoztam.

A másik dolog, amit nem értettem, hogy bár két GPU van a gépemben, összesen 8G memóriával, mégis rendszeresen kaptam a figyelmeztetéseket, hogy a videokártya memóriája mindjárt meg fog telni. Akár mennyi képpel is tanítottam a hálózatot, a GPU memóriája 95-98%-ban tele volt.

A tutorial után visszatértem az előző kódhoz. Egy hirtelen ötlettől vezérelve kiírattam a képeket, amelyeket generál a tanításhoz. Kiderült, hogy a kék és vörös csatárnákat megcserélte. Nem csoda, hogy képtelen bármit is megtanulni, hiszen nem ugyan az a két adatsor. Olyan, mintha más lenne a lecke és másból kellene felelni. A javítás után egy kicsit jobb lett a helyzet, de még így is messze volt a használhatótól.

Néha a számok alapján már majdnem úgy tűnt, hogy elértem a célom, de ha egy olyan képet adtam be neki, amit korábban nem látott, akkor látszott, hogy a rendszerem nem tanult semmit. Egyre biztosabb voltam, hogy nekem egy sokkal egyszerűbb modellre van szükségem. Végül találtam egyet. A leírásban 500 lépésben tanították a modellt, ami bődületesen soknak tűnt, de úgy döntöttem, kipróbálom. Ezt a hálót is a saját igényeimnek megfelelően átalakítottam, majd elkezdtem tanítani. Ez hét órát vett igénybe. A tanító kód itt van:

from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPool2D
from keras.layers import Flatten
from keras.layers import Dropout
from keras.layers import Dense
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator

NUM_EPOCHS = 500

class SmallNet:
  def build(width, height, depth, classes):
    model = Sequential()
    model.add(Conv2D(32,3,padding="same", activation="relu", input_shape=    (height, width, depth)))
    model.add(MaxPool2D())
    model.add(Conv2D(32,3,padding="same",activation="relu"))
    model.add(MaxPool2D())
    model.add(Conv2D(64,3,padding="same", activation="relu"))
    model.add(MaxPool2D())
    model.add(Dropout(0.4))
    model.add(Flatten())
    model.add(Dense(128,activation="relu"))
    model.add(Dense(classes, activation="softmax"))
  return model

train_datagen = ImageDataGenerator(rescale = 1.0 / 255, zoom_range=0.2, horizontal_flip = True, rotation_range=180)

test_datagen = ImageDataGenerator(rescale = 1.0 / 255)

train_generator = train_datagen.flow_from_directory("test2", target_size = (140,178), batch_size = 64, class_mode = 'categorical')

test_generator = test_datagen.flow_from_directory("test2", target_size = (140,178), batch_size = 64, class_mode = 'categorical')

model = SmallNet.build(width=178, height=140, depth=3, classes=73)
opt = Adam(lr=0.000001)

model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])

model.fit_generator(train_generator, steps_per_epoch = 14000 // 64, epochs=NUM_EPOCHS, validation_data = test_generator, validation_steps = 1000 // 64)

model.save("./imagesearchmodel")

Ez volt az első eset, hogy a képeket jól azonosította be. Sajnos legrosszabb esetben 24%-ban volt biztos a helyes megoldásban, de legalább helyes volt a megoldás. Még a kivit sem nézte zöldalmának. Végezetül beadtam neki a saját arcképemet, mire a rendszer megállapította, hogy ez egy banán. Remélem ez nem egy kritika az algoritmus részéről.

 

Szólj hozzá!

Címkék: machine learning

A bejegyzés trackback címe:

https://cybernetic.blog.hu/api/trackback/id/tr5417879153

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása