maandag 26 december 2016

06 Fish - Verbeteren en verbeteren

Yes, yes yes!

Mijn laatste verbeteringen geven in ieder geval een aardig geloofwaardige verdeling:


0 18
1 2
2 14
3 43
4 36
5 30
6 149
7 708

Dit was de trainingset verdeling:

0 200
1 117
2 67
3 465
4 299
5 176
6 734
7 1719

Onderzoek van eerdere oplossingen van winnaars van andere competities geeft altijd weer aanvullende ideeën. Bijvoorbeeld bij het identificeren van walvissen heeft men ze eerst vergelijkbaar geplaatst (van links naar rechts). Dat kan ik ook gaan doen (er zijn een aantal deelnemers die kop staart informatie al beschikbaar hebben gemaakt) maar eerst wil ik wat andere suggesties proberen. Zo-ie-zo lijkt het verstandig om dergelijke uitdagingen vergelijkbaar op te pakken als je het zelf zou leren. Bijvoorbeeld eens goed 'inzoomen' op de vinvorm of andere identificerende details.
Ik begin maar eens met het verwijderen van de ingezoomde afbeeldingen uit de validatieset. Die komt tenslotte ook niet voor in de uiteindelijke testset.
Ik laat daarnaast steeds alleen de beste oplossingen opslaan in plaats van gewoon de laatste.

Verder hebben ze in de winnende 'walvissen-oplossing' gespeeld met variatie in de training parameters. Met name een sterke aanpassing van de learning rate ergens halverwege. Ik besluit iets dergelijks te doen maar dan met de 'optimizer'. De eerste 17 rondes werk ik met 'rmsprop' om daarna over te schakelen op 'Adam'. Dat lijkt een aardig succesvolle methode:


Later nog eens kijken of ander variaties de curve opnieuw kan laten zakken. Nu eerst maar eens verder werken aan een submission file.

Spannend ....


Hmmm :-( valt vies tegen. Ook nog een flink stuk van het 'sample submission' niveau.
Toch lijkt die regelmatig behoorlijk zeker van zijn zaak. Hieronder voor de eerste dertig de hoogste waarschijnlijkheid:

0 0.394905
1 0.865984
2 0.893556
3 0.514651
4 0.455819
5 0.587176
6 0.693616
7 0.505812
8 0.952622
9 0.476833
10 0.862486
11 0.556331
12 0.993129
13 0.649682
14 0.366256
15 0.766741
16 0.835264
17 0.552001
18 0.463462
19 0.758394
20 0.624866
21 0.503535
22 0.64195
23 0.653738
24 0.713803
25 0.846063
26 0.897888
27 0.718468
28 0.859618
29 0.86105  

woensdag 21 december 2016

05 Fish - En nu een submission maken.

Ik heb mij nog niet zo bezig gehouden met het voorbereiden van de werkelijke submission. Zelfs de testdata bleek ik nog niet op mijn pc te hebben geladen. Snel een download en een programma om de data in he juiste formaat om te zetten. Tevens 'sorteer' ik ook deze afbeeldingen op 'overeenkomstigheid' omdat ik vermoed dat er regelmatig, kort op elkaar volgende afbeeldingen zijn gebruikt waar dus dezelfde soort vis op te zien moet zijn. Bij twijfel kan dat dus een doorslag geven.



De gewenste output ziet er zo uit: (meegeleverd voorbeeld)

image,ALB,BET,DOL,LAG,NoF,OTHER,SHARK,YFT
img_00005.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00007.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00009.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00018.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00027.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733

Een waarschijnlijkheid dus per vissoort. Mooi dat regelt mijn gebruikte model ook als output alleen besef ik mij nu dat ik de 'vis volgorde' heb aangepast:


fishtypes = ['BET','DOL','LAG','NoF','OTHER','SHARK','YFT','ALB']

Hierdoor kwam de grootste groep aan het einde. Ik geloof dat dit vooral was om snel te kunnen testen.

Mijn tussenuitkomsten zien er zo uit:


[  5.55696040e-02   3.63390967e-02   3.35246362e-02   2.71632709e-02
   1.92823112e-01   1.01814854e-04   5.17386533e-02   6.02739811e-01]
[ 0.07084329  0.01330838  0.01655073  0.02492231  0.05961363  0.00400923
  0.10697447  0.70377797]
[  3.16158533e-02   5.14484383e-02   8.70272238e-03   1.64415389e-02
   3.37270200e-01   9.72153975e-06   2.47996226e-02   5.29711902e-01]
[ 0.09419882  0.01306145  0.04260941  0.01321667  0.08773319  0.00299926
  0.10487828  0.64130288]
[ 0.02304434  0.00076831  0.00147995  0.00258547  0.18335994  0.06462369

  0.31772998  0.40640843]

Opvallend is dat meestal de laatste groep de hoogste kans heeft. Gelukkig zijn er wat uitzonderingen : (Aantal hoogste kans per vissoort)


0 0
1 0
2 0
3 21
4 2
5 3
6 47

7 927

Ligt een beetje in lijn met het aantal vissen per vissoort in de traindataset:


0 200
1 117
2 67
3 465
4 299
5 176
6 734
7 1719

Maar ja, gevoelsmatig valt het nog een beetje tegen. Was leuk geweest als die van alle types wat meer had herkent. Maar goed, we zullen eens kijken wat dit oplevert.






zaterdag 17 december 2016

04 Fish - ook eerst de visjes herkennen

De vorige resultaten vielen nogal tegen. Door de data 'te verrijken' met draaien, spiegelen, schuiven, zoomen, voorkom je dat een NN 'overfit'. Oftewel de foto's zo goed kent dat alleen die betreffende foto's de juiste resultaten weergeven en niet bij een nieuwe, onbekende foto.


Doordat de fotos vaak vanuit dezelfde hoek zijn genomen en ook vaak kort achter elkaar loop je hier het risico dat eerder een voorspelling wordt gedaan op basis van de boot en 'omstandigheden' (aantal / positie mensen etc) dan op basis van de vissen zelf. Ik heb daarom nu, op basis van eerder, handmatig verkregen, positiedata, uitsneden toegevoegd van de vissen zelf. De resultaten zijn veelbelovend. Veel minder variatie in de resultaten:


Waarom mijn testdata het nu structureel beter doet dan mijn traindata, iig in de 'loss', snap ik niet. Wel zou ik eigenlijk mijn testdata zonder de uitsnedes moeten doen.

Feitelijk zou ik daarnaast voor een juiste validatie de bootcamerabeelden per boot moeten scheiden. Helaas zijn er m.i. daarvoor te weinig boten. Een stuk of 8-10 geloof ik ergens gezien te hebben.
Wellicht is het wel zinvol om te kijken of ik de 'vaste boot beelddelen' kan onderdrukken. Daar zit veel informatie in die buiten beschouwing zou moeten blijven. Ik heb al eerder een subroutine gemaakt om de beelden in volgorde van de minste verschillen te plaatsen. Misschien moet ik daar nogeens verder mee experimenteren.


woensdag 14 december 2016

03 Fish - Natural stupidity


Tja, beter kan ik het niet maken. Alle combinatie testen van gisteren zijn zinloos geweest. Ik heb de eerste versie van mijn programma 'classifier_from_little_data_script_2.py' genoemd en de combinatie opvolger nr 3. Ik ben echter het eerste programma steeds blijven aanroepen. Duh!!! Geen wonder dat het weinig leek te reageren op mijn aanpassingen. Maar wle voldoende om geen alarmbellen te laten rinkelen.

Nu dus aangepast en opnieuw opgestart. In lijn met de verwachtingen duurt elke epoch nu veel langer. 69 seconden zonder rotatie. Zo'n 72 tot 127 seconden met rotatie (veel variatie hier?!)
Duurt dus even tot we resultaat hebben. Had ik nou maar zo'n mooie nvidea supercomputer :-(
    

Dit zijn de resultaten: 



Erg veel variatie in de test 'loss'. Bovendien komt deze uiteindelijk op zo'n 1.17 uit. Veel hoger dan de eerste meting zonder de data-augmentation die richting de 0.5 aan het lopen was. Ook grote verschillen in de acccuracy. Natuurlijk kan het zo zijn dat bij deze waarneming de herkenning van de omgeving minder een rol gaat spelen. (En dus in het eerste model teveel). Of er zit gewoon nog ergens een stomme fout in.  
Misschien moet ik zo-ie-zo het systeem even wat beter de 'visvorm' gaan laten herkennen. Ik heb al eerder handmatig de vis-locaties vastgelegd. (rsi gevoelig klusje). Maar daar kan ik nu misschien fijn gebruik van gaan maken.   

dinsdag 13 december 2016

03 Fish - De combi


Wow! In 1 keer lukt het om de data augmentation en het VGG16 netwerk gebruik te combineren. Hier de resultaten:


De variatie in de loss bij de testdata fluctueert nu nog meer! Maar het gaat wel supersnel en ik zie een accuracy van wel 89%. Dat geeft wel hoop. Misschien maar eens over een submission na gaan denken!
De fluctuatie blijkt voor een belangrijk in de gekozen dropout te zitten (.5). Hier bijvoorbeeld een dropout van 0.2:

 

02 Fish - Bouwen op bestaande NN's kennis

Bij het vorige algoritme, waar ik voor het eerst met Keras ImageDataGenerator heb gewerkt op basis van deze blog, staat ook een mooi voorbeeld van he gebruik van een al eerder getraind NN.  In dit geval een 'VGG16 architecture, pre-trained on the ImageNet dataset'.  ImageNet bestaat uit een geclassificeerde dataset van miljoenen afbeeldingen. Daardoor heeft het model al de features in zich van foto's van allerlei dieren en objecten. Daar bovenop is dan alleen nog maar een relatief eenvoudig model nodig om de vissoorten te herkennen uit al die features.


Voorbeelden uit ImagNet
 Het lukt al vrij snel om het voorbeeld model om te bouwen voor de visjes. Hier zijn de resultaten:


Op zich ziet het er netjes uit behalve dat de test data erg 'springerig' is. Ik weet niet zeker wat de oorzaak zou kunnen zijn. De testset is in principe een random subset van het totaal. In deze competitie speelt wel het probleem dat er dus veel vergelijkbare afbeeldingen kunnen zijn en dat een deel van de 'kennis' wellicht afgeleid wordt van de boot informatie ipv de werkelijke vis. Daarnaast bevatten sommige afbeeldingen meerdere vissen.    

In deze 'oplossing' is nog niet gebruik gemaakt van 'data augmentation' (draaien / flippen / schuiven / zoomen) zoals in het vorige blogbericht. Dit zou zijn omdat de VGG16 anders veel te veel processingtijd zou nemen. 
Ik ga eens proberen of we dat met Keras 'trainable=False' parameter kunnen ondervangen.  








zondag 11 december 2016

01 Fish - Nieuwe Kaggle competitie

Het is helaas geen medische competitie maar wel een grafische. Misschien hier wat meer succes dan bij de EEGs. Het gaat in deze competitie (the-nature-conservancy-fisheries-monitoring) om het herkennen van bijvangst bij vissers. Men heeft camera's op de schepen geplaatst om daar de bijvangst (dolfijnen / haaien etc) automatisch te identificeren.
Helaas zijn er maar relatief weinig foto's en ze overlappen elkaar ook behoorlijk.

plenty of fish in the sea
Bij Keras, mijn favorite ML omgeving, zit ook een module bij om afbeeldingen te draaien / schuiven zoomen etc zodat er met minder afbeeldingen toch betere resultaten bereikt kunnen worden. Hier wordt daar een voorbeeld van uitgewerkt. Het moet met name 'overfitting' voorkomen bij gebruik van kleine datasets.
Ik heb zelf al eerder dergelijke functies gemaakt en gebruikt maar deze doet het allemaal 'on-the-fly' en automatisch. Wel even wennen aan de syntax:

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(rotation_range=20,
                                   rescale=1./255,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow(X_train,y_train, batch_size=32)

validation_generator = test_datagen.flow(X_test,y_test, batch_size = 32)

history = model.fit_generator(
                    train_generator,
                    samples_per_epoch=nb_train_samples,
                    nb_epoch=nb_epoch,
                    validation_data=validation_generator,

                    nb_val_samples=nb_validation_samples)

Zie hier de resultaten van 50 epochs trainen:




       

CuDNN eindelijk eens actief!!!

Na veel zoeken en testen is het gelukt om CuDNN, de speciale NVDEA software accelerator voor NN's aan de praat te krijgen.


>>> import theano
Using gpu device 0: GeForce GTX 980 (CNMeM is disabled, cuDNN 5105)
/usr/local/lib/python2.7/site-packages/theano/sandbox/cuda/__init__.py:600: UserWarning: Your cuDNN version is more recent than the one Theano officially supports. If you see any problems, try updating Theano or downgrading cuDNN to version 5.
  warnings.warn(warn)

Oke met een warning omdat ik al op een heel nieuwe versie zit maar toch.

Even vastleggen hoe mij dat gelukt is.
Ik heb de nieuwste Xcode software geladen. Dat is goed maar de developer tools zijn van een te nieuwe versie:


nvcc fatal   : The version ('80000') of the host compiler ('Apple clang') is not supported

Dus weer terugzetten naar versie 7.3. Hier vind ik hoe dat moet. 
Met name ook het terugzetten naar de juiste versie is belangrijk.

sudo xcode-select --switch /Library/Developer/CommandLineTools

Voor CuDNN heb ik de handmatige installatie gedaan. Eerst versie 8.0 gedownload van de NVIDEA site. Daarna de bestanden naar de actieve cuda directory gekopieerd. Het gaat om deze bestanden:


Het eerste bestand gaat naar de

/Developer/NVIDIA/CUDA-8.0/include

de andere naar de /Developer/NVIDIA/CUDA-8.0/lib

et voila. Het werkt!

Nu kijken of we er iets interessants op kunnen laten draaien. Een Keras autoencoder voorbeeld lijkt al prima te werken.