vrijdag 10 juni 2016

07 - Ultrasound - combineren

Goed, even alles op een rijtje.

Ik heb al een NN voor het wel/niet aanwezig zijn van een masker. Lijkt aardig te scoren.
- Nu moet er een NN bijkomen, alleen voor maskerhoudende afbeeldingen, waarmee de coordinaten van de middenpositie wordt bepaald.
- Daarnaast moet er een NN bijkomen die de maskcategorie terug weet te geven.
Ik denk dat ik dit als specialistische NNs implementeer. Hoewel het model mogelijk vergelijkbaar blijft.
Aan het einde moet het algoritme de maskers genereren, met de gevonden correctie en de dice coefficient berekenen.  Misschien is her-ijking van met name de mask-correctie dan gewenst.


06 - Ultrasound - masker categorien

De gemaakte ellipsen kan ik nu gaan categoriseren. Ik gebruik daarvoor Kmeans van sklearn.  Je geeft daarbij op hoeveel groepen je wil hebben en 'hij' verdeeld ze automatisch op basis van de beschikbare features. In dit geval de hoogte, breedte en hoek van de ellipsen. De positie hoop ik met een apart NN te berekenen.
Tja, hij doet het, en snel! Maar hoeveel groepen moet je nou gebruiken? Ik besluit het te bepalen aan de hand van mijn dice functie. Na wat geknutsel blijkt dat 8 groepen  de grootste dice waarde haalt. 



Tevens is het wellicht handig om de gevonden gemiddelde ellipse per groep iets te vergroten of te verkleinen voor een betere fit. Ook dat test ik uit. Daarvoor maak ik het formele middelpunt van de ellipse een beetje (8 posities) random daar mijn NN hiervoor ook wel niet 100% nauwkeurig zal scoren. Al snel blijkt, door een fout in de correctie, dat mijn dice functie niet helemaal goed werkt. Als ik een masker van 1 stip aanbied, vermoedelijk op de juiste plaats, dan krijg ik een dice van bijna 2! Het maximum! Even kijken of er betere voorbeeld functies zijn op het internet. En ja hoor, we kunnen weer verder. 

w = huidige maatcorrectie, cl = aantal clustergroepen, vdice  = verschil met vorige dice

Calculating optimal kmeans groupsize ...
w =  -8 cl =  6 vdice =  0.75133205691 dice =  0.75133205691
w =  -8 cl =  7 vdice =  0.00339535583778 dice =  0.754727412748
w =  -8 cl =  8 vdice =  -0.000425363850674 dice =  0.754302048897
w =  -8 cl =  9 vdice =  0.00121933082975 dice =  0.755521379727
w =  -8 cl =  10 vdice =  0.00194128204755 dice =  0.757462661775
w =  -8 cl =  11 vdice =  -0.000864609608341 dice =  0.756598052166
w =  -8 cl =  12 vdice =  0.000834459294879 dice =  0.757432511461
w =  -8 cl =  13 vdice =  7.22511220859e-05 dice =  0.757504762583

Ik denk dat hoe minder clustergroepen hoe groter de nauwkeurigheid van het NN dat het elipstype moet leren. 10 groepen (en dus niet 8) lijkt daarom hiervoor het meest gunstig.
Even kijken of w nog herzien moet worden: Hmmm ... -1 blijkbaar ...

Calculating optimal kmeans masksize ...
w =  -5 cl =  8 vdice =  0.759595105055 dice =  0.759595105055
w =  -4 cl =  8 vdice =  0.00266908869311 dice =  0.762264193748
w =  -3 cl =  8 vdice =  0.000643002717233 dice =  0.762907196465
w =  -2 cl =  8 vdice =  0.00114370904777 dice =  0.764050905513
w =  -1 cl =  8 vdice =  0.000234796748407 dice =  0.764285702261
w =  0 cl =  8 vdice =  -0.00111047120475 dice =  0.763175231057
w =  1 cl =  8 vdice =  7.32369505178e-05 dice =  0.763248468007

Nog even een verificatie:

Calculating optimal kmeans groupsize ...
w =  -1 cl =  6 vdice =  0.758648692838 dice =  0.758648692838
w =  -1 cl =  7 vdice =  0.00278931386038 dice =  0.761438006698
w =  -1 cl =  8 vdice =  0.00206029459506 dice =  0.763498301294
w =  -1 cl =  9 vdice =  0.00117066722752 dice =  0.764668968521
w =  -1 cl =  10 vdice =  -0.000578130504317 dice =  0.764090838017
w =  -1 cl =  11 vdice =  -0.000135805257527 dice =  0.763955032759
w =  -1 cl =  12 vdice =  0.00269423472313 dice =  0.766649267482

w =  -1 cl =  13 vdice =  0.000886762567938 dice =  0.76753603005

Nu zijn dus 9 groepen optimaal na de aanpassing van w naar -1 ! Alleen maar beter! 
Vervolg>>> Natuurlijk iets over het hoofd gezien. Ik heb het optimaal aantal clustergroepen bepaald inclusief de 'nul' groep: Geen masker. In het NN wil ik echter uitsluitend daarvoor de groepen met masker gebruiken. Even dus opnieuw simuleren. Het blijkt dat correctie +1 moet zijn als optimum en dat het aantal groepen het beste op 13 kan zitten. Hmmm 13? ....


w =  -1 cl =  6 vdice =  0.840136225125 dice =  0.840136225125
w =  -1 cl =  7 vdice =  -5.57458507642e-05 dice =  0.840080479274
w =  -1 cl =  8 vdice =  0.00208980003578 dice =  0.84217027931
w =  -1 cl =  9 vdice =  0.000817202322314 dice =  0.842987481633
w =  -1 cl =  10 vdice =  -0.000607069472263 dice =  0.84238041216
w =  -1 cl =  11 vdice =  0.00258267378717 dice =  0.844963085947
w =  -1 cl =  12 vdice =  -0.000985547711417 dice =  0.843977538236
w =  -1 cl =  13 vdice =  0.0044663430702 dice =  0.848443881306
w =  -1 cl =  14 vdice =  -0.00152840415147 dice =  0.846915477155
>>> execfile('/Users/DWW/Ultrasound/create_mask_clusters.py')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Loading files ...
Calculating optimal kmeans groupsize ...
w =  -5 cl =  8 vdice =  0.836293053258 dice =  0.836293053258
w =  -4 cl =  8 vdice =  0.00307849148114 dice =  0.839371544739
w =  -3 cl =  8 vdice =  0.000278751368095 dice =  0.839650296107
w =  -2 cl =  8 vdice =  0.00181491486703 dice =  0.841465210974
w =  -1 cl =  8 vdice =  -0.000838091798359 dice =  0.840627119176
w =  0 cl =  8 vdice =  -0.000194270279629 dice =  0.840432848896
w =  1 cl =  8 vdice =  -0.00131628973877 dice =  0.839116559158
w =  2 cl =  8 vdice =  -1.67883050046e-05 dice =  0.839099770853
w =  3 cl =  8 vdice =  -0.000750410370843 dice =  0.838349360482
>>> execfile('/Users/DWW/Ultrasound/create_mask_clusters.py')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Loading files ...
Calculating optimal kmeans groupsize ...
w =  -5 cl =  13 vdice =  0.844021218883 dice =  0.844021218883
w =  -4 cl =  13 vdice =  0.00152588538211 dice =  0.845547104265
w =  -3 cl =  13 vdice =  0.00098765515515 dice =  0.84653475942
w =  -2 cl =  13 vdice =  0.000417669300165 dice =  0.846952428721
w =  -1 cl =  13 vdice =  0.000617219641173 dice =  0.847569648362
w =  0 cl =  13 vdice =  -0.000492214811146 dice =  0.847077433551
w =  1 cl =  13 vdice =  0.00172947271756 dice =  0.848806906268
w =  2 cl =  13 vdice =  -0.00269821527775 dice =  0.84610869099
w =  3 cl =  13 vdice =  -0.00198209872486 dice =  0.844126592266 

dinsdag 7 juni 2016

05 - Ultrasound : Meer statistieken

De gevonden hoekverdeling

Lengte verdeling van de ellipsen

Breedte verdeling van de ellipsen

De vertikale posities (vanaf boven)

De horizontale posities (vanaf links)

04 - Ultrasound - Roem van korte duur

Na de, uiteraard uitgebreide, viering met schuimende bierkoppen en de bijbehorende drankliederen, nu even de bezinning. Mijn behaalde moeizaam behaalde 47e positie is nu alweer teruggevallen naar de 60e. Roem is maar van korte duur...

De verbetering is met name bereikt door het standaard masker dat ik gebruikte te optimaliseren. Tot nu toe heb ik mijn NN alleen nog maar op wel/niet aanwezigheid van een masker getraind. Op basis van alle maskers bij elkaar heb ik een 'groot gemiddeld' masker gemaakt dat ik voor alle situaties in heb gezet. Door te kijken met welk masker ik de beste dice coefficient kan krijgen op mijn train-data is het gelukt om een veel kleiner standaard masker te gebruiken met dus een veel kleinere fout.


Het belangrijkste is echter dat mijn y/n NN het dus blijkbaar redelijk lijkt te doen. Als ik daarnaast ook betere maskers handteer moeten de resultaten verder verbeteren.

Nu eerst maar eens wat beter kijken naar de maskers zelf. Lekker wat statistiek bedrijven. Op basis van een voorbeeld script is het mogelijk om de aangegeven maskers vrij aardig in ellipsen te 'vangen'. Mijn eigen pogingen werkten alleen met het hoogste en laagste punt en daartussen het linker en rechter punt:

of



 Dit ziet er echter (veel) beter uit:



Kijk, daar kan ik wat mee. Er zit in OpenCV blijkbaar een prachtige functie 'fitEllipse' die netjes het centrum, de lengte van de korte en lange as en de hoek teruggeeft van de 'best fitting ellipse'. Met deze metadata moeten we verder komen, lijkt mij. Daar gaan we eerst eens wat histogrammetjes over fabriceren.

maandag 6 juni 2016

03 Ultrasound - Scoren!!!! Eindelijk boven de nullijn!

Yes! eindelijk boven de 'nullijn '. Positie 47 van de 177 deelnemers!! Bijzonder hoe lastig het blijkt bij deze competitie om met een reƫle inzending beter uit uit te komen dan met een 'lege inzending'. (Nu slechts 52 deelnemers beter dan 'leeg')


Later meer over het 'hoe'. 

woensdag 1 juni 2016

02 Ultrasound - Eerste NN voor deze competitie

Eindelijk mijn convolutional netwerk aan de praat. Ik moest de afbeeldingen terugbrengen van 420x480 naar 105x145 om het een beetje aan het werk te krijgen. Daarnaast heb ik op basis van voorgaande 'blob' ook wat stukjes af willen snijden (gecropt). (Ik zie nu net dat dat nog niet gelukt is. Daarvoor moet ik mijn 'crop-parameter' op True zetten :-)

Hij is nu 'lekker' aan het rekenen op mijn eerste uitdaging nl. om te bepalen of er wel of niet een 'masker' zou moeten zijn. Ik train het met 640 records per keer en met 360 validatie records. Elke 20 epochs shuffle ik de gehele dataset en pak dus weer een nieuw batch van 1000 records. Dat moet m.i. toch overfitting tegengaan zou ik zo zeggen.

Hoewel de loss steeds beter lijkt te worden (nu al op 0.3053) en ook de validatie loss omlaag gaat (0.4260) zie ik dat hij nog steeds maar zo'n 68% van de gevallen goed heeft. Deze waarde veranderd niet veel gek genoeg. Even nadenken wat dat betekent ...

Wat statistiek:

De traindataset bestaat uit 5635 records. Daarvan zijn er 3312 (58,78%) met een 'leeg masker' en dus 2323 = 41.2% met masker.

De testdataset bestaat uit 5508 records. 59% zou dan op 3237 lege en dus 2271 'gevulde' maskers moeten gaan uitkomen.

Hoe goed doet ie het als ik niet weet? Ik moet even denken aan een waarde die ik vorig jaar ben tegengekomen als juiste meetwaarde voor NN resultaten:

kappa = O - E / (1 - E) 

Waarbij O de waargenomen (observed) betrouwbaarheid is en E de verwachte (expected) betrouwbaarheid op basis van statistiek. Deze parameter corrigeert dus het resultaat voor de statistische uitkomst.