zondag 28 februari 2016

MRI - 28 - En de 61e plaats!!!

Door een foutief gebruik van 'continue' bij het opzoeken van de SliceDistances kreeg ik in eerste instantie een foutmelding in bij het aanbieden van de submission file. Minstens 2 studies bleken 'zonder meetwaarden' te zijn. Een warme douche, om de grijze cellen op gang te brengen, bracht mij al snel bij het probleem. Ik hoefde alleen de validatie beelden opnieuw aan te maken, nu dus voor alle studies, en het resultaat was een verhoging van de 68e naar de 61e plaats! Zit in nu bij de beste 10%!! (Momenteel 667 deelnemende teams)

Er is uiteraard door deze fout ook informatie bij het trainen verloren gegaan. Misschien zelfs wel alle 2 en 4 chamber informatie. Zinvol dus om opnieuw te proberen. Teven standaardiseer ik de sax-slice afstand naar 10 mm als deze nul is (meestal bij de 1e slice) en de 2ch en 4ch zet ik standaard op nul. (Slice afstand speelt daar uiteraard niet)


De Iteratie tijd is toegenomen naar 64 seconden. Dus 200 * 64 is een ruime 3.5 uur wachten. :-( Waar blijft mijn snelle computer? Even een vergeefse poging gedaan om CuDNN aan de praat te krijgen. Doe ik wel  na de sluitingstijd (morgen) van deze competitie.

--------------------------------------------------
Iteration 30/200
--------------------------------------------------
Augmenting images - rotations
4963/4963 [==============================] - 5s        
Augmenting images - shifts
4963/4963 [==============================] - 1s        
Fitting systole model...
Train on 4963 samples, validate on 1240 samples
Epoch 1/1
4963/4963 [==============================] - 23s - loss: 25.8479 - val_loss: 35.6012
Fitting diastole model...
Train on 4963 samples, validate on 1240 samples
Epoch 1/1
4963/4963 [==============================] - 23s - loss: 38.6400 - val_loss: 69.2094
Evaluating CRPS...
4963/4963 [==============================] - 5s     
4963/4963 [==============================] - 5s     
1240/1240 [==============================] - 1s     
1240/1240 [==============================] - 1s     
CRPS(train) = 0.0636899431507
CRPS(test) = 0.0613953732271

Saving weights...

zaterdag 27 februari 2016

MRI - 27 - Moeizame voortgang

Nadat de eerste blijdschap van de mooie positie is weggezakt nu de strijd om toch nog wat beter uit te komen. De 106x106 afbeeldingsgrootte heeft, 14,5 uur later, helaas geen verbeteringen opgeleverd. De submission had wel veel voeten in de aarde. Enerzijds omdat het programma de verkeerde directorie - verwijzingen had. (En 's avonds, na wat wijntjes, is het moeilijk in een keer alle verwijzingen aangepast te krijgen) Anderzijds onthoud Python veel van de data van de eerder gelopen programma's. Daardoor ontstaan regelmatig vreemde foutmeldingen. Ook kreeg ik een 'Out of memory' fout. Ik zie dat anderen dit voorkomen door elke opstart vanuit de terminal te starten, bijvoorbeeld :

>>> python submission.py 

Misschien ook maar eens een gewoonte van maken. Uiteraard vraagt dat een opstart vanuit de juiste directory.

Ik ga nu testen met de volgende aanpassingen:

  • Weer terug naar formaat 64x64 (ook voor de snelheid)
  • Inclusief 4 en 2 chamber view (dag, gewonnen snelheid :-)
  • Toevoegen van de Slice-distance
  • Tussendoor conversie naar uint8 (alleen om 'ruis' eruit te halen - In train.py wordt het weer omgezet naar een float32)
Misschien niet handig om van alles tegelijk te proberen, maar ja. Ik geloof dat ik wat onder tijddruk sta. Het is mij niet duidelijk of ik na maandag nog verder kan met testen.  



 

vrijdag 26 februari 2016

MRI - 26 - En wat nu?

De belangrijkste aanpassing die ik nu wil proberen is de afbeeldingsgrootte aanpassen van 64x64 naar 106x106. Leuk ... maar dat neemt wel veel meer rekentijd. Momenteel doet hij 4.4 minuten per iteratie over. Dat is dus voor 200 iteraties zo'n 14.5 uur! Hij is al bij de 170 dus nog maar 2,2 uur. (even voor 23:30 vanavond). Dat is heel wat langer dan met de 64x64 variant met 53 seconden per iteratie. Ik heb mij maar eens aangemeld voor cuDNN van Nvidea waarmee een 4 tot 5x snelheidsverhoging zou kunnen worden verkregen. Ik wil echter wachten met de installatie om te voorkomen dat er nu allerlei problemen ontstaan.



Slicedistance: Tja, en wat zouden we nog meer kunnen om de score te verbeteren? In ieder geval kan de slice afstand worden meegenomen als gegeven. Die metadata waarde was ik, naast leeftijd en geslacht, nog vergeten. Uiteraard een heel belangrijke omdat het de 3e dimensie grootte aangeeft. Misschien dat de randgrootte, waarin de metadata is opgenomen in de afbeelding, nog ruimer moet. (nu 3 pixels om bij de convoluties niet te 'verdwijnen'.)

Modellen: Momenteel worden de systolische en de diastolische waarden in aparte modellen berekend. Ze krijgen wel beide de systolische en diastolische posities als input. Wellicht werkt 1 model met 2 outputs dan beter. Of 2 modellen met gesplitste input. Gevoelsmatig werkt de eerste beter. Uiteraard kunnen ook alle parameters uit het model worden aangepast. Er zijn nu afwisselend 6 convolutie lagen, 3 maxpooling en 4 dropout lagen. Best veel. Optimalisatie is 'Adam'. Ken ik op zich niet. Tot nu toe alleen met wat andere optimalisatie routines gewerkt. (sgd, rmsprop adagrad). De leernauwkeurigheid staat op 0.0001. Ook mee te experimenteren.  

Uint8: Toen ik in een tussenresultaat bijna volledig zwarte afbeeldingen kreeg heb ik ontdekt dat dat aan de conversie naar uint8 lag (unsigned byte). In het gebruikte voorbeeldmodel werd een aanroep gedaan naar de imresize functie van Scipy. Deze blijkt zelf te schalen naar een getal tussen 0 en 255 en tevens de input om te zetten naar een uint8. Omdat ik deze functie niet meer gebruikte bleef mijn matrix tussen 0 en 1. Met het maximum altijd op 1. Vandaar de witte puntjes in mijn eerdere afbeeldingen. Voor de snelheid en wellicht ook het terugbrenging van ruis kan ik nu toch ook weer uitgaan van uint8.

2/4 Chamber view: Ik wilde ook de 2 en 4 kamer view toevoegen aan het NN. Deze moeten toch ook heel veel informatie kunnen bijdragen aan de verwachte volumes. Nog niet zeker of ze nou het beste in een eigen model moeten worden getraind of in het (de) zelfde model(len).

Pre-learning: Een extra mogelijkheid waarmee ik al eerder bezig ben geweest is natuurlijk om het systeem eerst (handmatig) specifieke zaken te leren. Zoals de positie van het LV (linker boezem) en de positie van het aanknopingspunt van de hartkleppen bij de 2ch / 4ch view. Dit kan dan bijvoorbeeld als input dienen om  een nauwkeuriger uitsnede van de afbeelding te maken.

Eens kijken waar ik op uit ga komen met (een paar van) deze aanpassingen.  



      

donderdag 25 februari 2016

MRI - 25 - En weer omhoog !!!


Een van de parameters is de 'noise reduction' . Ik heb deze eerder 'op het gevoel' van 0.1 naar 0.001 gezet. Dit gaf eerder aardige resultaten. Nu maar eens aangeboden met 0.01. En weer 12 posities omhoog! Gaaf!

  

MRI - 24 - Score, score, score!

Yes! Ik had mij stiekem het doel gesteld om bij de 100 beste scores te komen!




Plaats 78 !!! Na 2x meedoen ! Met een score van 0.029591 !!! Oke de topscore zit inmiddels op 0.009826  maar zij hebben dan ook al 55 keer meegedaan en natuurlijk ?! veel meer tijd dan ik :-)
Ik ben in ieder geval alvast heel blij met het resultaat!



MRI - 23 - datatype issues

Na de furore over de eerste Kaggle inzending de bezinning op het tegenvallende resultaat. In plaats van een verbetering lijkt het resultaat alleen maar slechter te worden Ik bekijk de inputafbeeldingen en krijg heel vreemde resultaten:


Wat ik ook doe het lijken alleen maar nullen met een streepje (de sexe?) en een enkel stipje te zijn. Ja, geen wonder dat hij daar weinig van kan leren. Uiteindelijk vind ik het euvel. Aan het einde van de datacollectie worden de afbeeldingen naar het type uint8 geconverteerd:


X = np.array(X, dtype=np.uint8)

Tja ... 8 bytes voor een getal van 0 .. 255. Op zich aardig maar het uitgangspunt voor de afbeeldingen was een float getal tussen 0 en 1 : 

image = image.pixel_array.astype(float)
image /= np.max(image)  # scale to [0,1]

Hoe doet die dan de conversie? Vreemd. Ik heb er wel wat functies tussen geplaatst maar m.i. niet die het datatype aanpassen. Hoe kan de oorspronkelijke Kaggle code dan wel goede resultaten geven?

Afijn, na nog een keertje de mist in te gaan doordat de uint8 op 2 plaatsen in het programma staat, draait hij nu zo te zien met de juiste data. Hopelijk gaat dit wel top-scores opleveren.    




maandag 22 februari 2016

MRI - 22 - De smaak te pakken


De smaak te pakken! Nu gaan we voor het echie! Hoewel je 3 inzendingen per dag mag doen laat mijn overbelaste hardware dat helaas niet toe. De vorige trainingsessie heeft er zeker zo'n 15 uur over gedaan om 200 iteraties te doorlopen. Maar goed, mijn afbeeldingsresolutie was dan ook vrij hoog: 106 x 106. Misschien ook de reden waarom 200 iteraties niet voldoende blijken om minstens even goed te scoren.
Ik besluit maar eens terug te gaan naar een resolutie van 64 x 64. Dan wordt het model ook wellicht weer wat beter beheersbaar.
Daarnaast pas ik de nauwkeurigheid aan van de de-noising routine: denoise_tv_chambolle. De 'weight' staat gegeven op 0.1 terwijl ik eerder visueel een veel aannemelijker resultaat (net voldoende nauwkeurigheid) met een weight van 0.001. Maar ja het blijft gokken.

In ieder geval lijkt de trainingstijd per iteratie sterk omlaag. (Ik ben vergeten om dat bij de vorige training goed te registreren.) Hier een voorbeeld van de output:

--------------------------------------------------
Iteration 10/200
--------------------------------------------------
Augmenting images - rotations
4173/4173 [==============================] - 4s       
Augmenting images - shifts
4173/4173 [==============================] - 1s       
Fitting systole model...
Train on 4173 samples, validate on 1043 samples
Epoch 1/1
4173/4173 [==============================] - 19s - loss: 29.5016 - val_loss: 37.0514
Fitting diastole model...
Train on 4173 samples, validate on 1043 samples
Epoch 1/1
4173/4173 [==============================] - 19s - loss: 45.1807 - val_loss: 71.5258
Evaluating CRPS...
4173/4173 [==============================] - 4s     
4173/4173 [==============================] - 4s     
1043/1043 [==============================] - 1s     
1043/1043 [==============================] - 1s     
CRPS(train) = 0.0666437912542
CRPS(test) = 0.0649356651026
Saving weights...
--------------------------------------------------
Iteration 11/200
--------------------------------------------------      
Na 200 iteraties lijken de resultaten tegen te vallen:

--------------------------------------------------
Iteration 200/200
--------------------------------------------------
Augmenting images - rotations
4173/4173 [==============================] - 4s       
Augmenting images - shifts
4173/4173 [==============================] - 1s       
Fitting systole model...
Train on 4173 samples, validate on 1043 samples
Epoch 1/1
4173/4173 [==============================] - 19s - loss: 27.9951 - val_loss: 44.8814
Fitting diastole model...
Train on 4173 samples, validate on 1043 samples
Epoch 1/1
4173/4173 [==============================] - 19s - loss: 42.5693 - val_loss: 103.7565
Evaluating CRPS...
4173/4173 [==============================] - 4s     
4173/4173 [==============================] - 4s     
1043/1043 [==============================] - 1s     
1043/1043 [==============================] - 1s     
CRPS(train) = 0.094819204133
CRPS(test) = 0.0814857771288

Saving weights...

Het gaat wel lekker snel met de kleinere afbeeldingen maar de cprs moet ergens rond de 0.036 uit kunnen komen. Toch iets te enthousiast de de-noising aangepast? Of is mijn uitgangsgedachte fout dat alleen de systolische en de diastolische positie interessant is? En dus niet alle posities ertussen. Of wellicht zit er nog ergens een fundamentele fout in de code. We gaan maar eens de-buggen.

MRI - 21 - Eerste Kaggle submission !

Yes! Vandaag mijn allereerste Kaggle submission. Oke, toegegeven de resultaten vallen ietsjes tegen. Met alle verbeteringen t.o.v. de oorspronkelijke Keras inzending kom ik slechter uit?! Met een score van 0.042552 kom ik op positie 303. Vreemd ten opzichte van de originele Keras Deep Learning tutorial (~0.0359). Ik had wel verwacht daar minstens een beetje in de buurt te komen. Maar dat is voor later. Voorlopig blijdschap voor de eerste 'submission'.




zondag 21 februari 2016

MRI - 20 - Terug naar de MRI challenge

De deadline voor de Kaggle competitie "second-annual-data-science-bowl" komt snel dichterbij. (14 maart 2016)  Niet dat ik verwacht in de prijzen te vallen maar het zou toch leuk zijn om in ieder geval ook een inzending te hebben. Ik heb al vele mogelijkheden onderzocht maar ik ben nog niet dicht bij een inzendbaar resultaat. Het laatste deel van het onderzoek richtte zich op het vinden van de juiste slices vanuit de 2chamber en 4 chamber view. De vertaling van deze posities naar de juiste slice is ingewikkeld en mij nog niet gelukt.

Mijn deeplearning pogingen voor deze competitie heb ik tot nu toe voor dit op basis van Keras gedaan. Mede ook omdat er een mooi voorbeeld van is gepubliceerd t.b.v. deze competitie. Ik besluit maar eens uit te gaan van dit voorbeeld en daar mijn 'eigen intelligentie' aan toe te voegen. (Ben ik snel klaar :-) .

Het Keras voorbeeld biedt alle 30 afbeeldingen van de sax-slices vrijwel geheel aan aan een neuraal netwerk. Dat moet veel slimmer kunnen. Ik voeg een routine toe die de diastolische positie opzoekt op basis van het kleinste verschil in afbeeldingen 'rond het startpunt'. (Een beetje op het gevoel gekozen positie -10 tot 5) Daarna zoek ik voor de systolische positie de afbeelding met de grootste afwijking t.o.v. de diastolische positie.

Zoeken naar afwijkingen :-)
Ik haal daarna wat oude code van mij op waarmee ik op basis van deze twee posities het centrum van de grootste afwijking kan vinden. Daarmee selecteer ik per sax laag van de gevonden systolishe en diastolische afbeelding het relevante gedeelte. Dat met de linker hartkamer. Ik corrigeer, ook met de eerde gemaakte code, de afbeeldingen naar dezelfde schaal en maak ze even groot. In plaats van de oorspronkelijke 64x64 maak ik ze 106x106. Een behoorlijk betere resolutie van een veel significanter deel van de afbeelding. Dat moet toch punten opleveren. (De 106 heb ik eerder al eens gekozen om bij de meest gebruikte afbeeldingsresolutie een 15x5 cm beeld te krijgen)  Tevens haal ik de extreme waarden er weer uit. Deze zijn, denk ik, vaak een gevolg van de meting of van ruis.

Omdat ik denk, en bevestigd heb gekregen,  dat de metadata, leeftijd en geslacht, ook al een aardige indicatie geeft van de volumes geef ik die waardes mee in de randen van de afbeeldingen. Ik kies voor randen van 3 pixels diep zodat de waarden volgens mij relevant blijven bij gebruik in het convolutional network.    

Het kost even moeite om alles weer foutloos? te krijgen maar nu lijkt hij naar het gewenste resultaat te werken. Ik heb daarbij nog niet aparte data voor systole en diastole gemaakt. Dat moet zeker ook nog gaan gebeuren. Daarnaast denk ik dat ik later ook nog de 2- en 4 chamber view mee ga nemen. Tenslotte geven die m.i. ook heel veel informatie over het verwachte volume.

woensdag 10 februari 2016

Feestje!

De nan waarden uit de vorige oefening zijn achteraf (natuurlijk achteraf) wel logisch. Als de standaard deviate nul is deelt hij door nul en levert dus daarom nan waarden. Duhh. Maar, na wat geknutsel om dat goed te krijgen, lijken de uitkomsten veel belovend! De redenen van de anomalien worden heel duidelijk. Bij de eerste bijvoorbeeld krijg ik dit:

Grootste bijdrage (%):
AV HR                62.0977108461
MM/IVSd              8.90512457027
LVOT Env.Ti          3.50103481496
P_Vein D             2.40014065928
LVOT VTI             1.92522539672
Age                  1.91912714246
MV A Dur             1.67217234175
AV Vmax              1.59201646016
AV VTI               1.49362709077

MV A Velocity        1.40011585242

62% bijdrage van de hearth-rate!. Even kijken ...

4              AV HR                HR  5449.7794118         BPM

Ja hoor bijna 5.500 'beats per minute'! Duidelijk een kommafoutje.

Bij de 2e anomalie blijkt de patient een heel groot hart te hebben. Zeker verliefd :-)  Bij een volgende een onwaarschijnlijk hoge bloed snelheid in bij de pulmonaalklep.  En zo lijkt hij op het eerste gezicht aardige anomalien te vinden. En belangrijker ... de juiste reden. Het is nu niet direct zo dat de registratiefouten vanzelf hebben geleid tot foute diagnoses. Daar is het proces robust genoeg voor. De belangrijkste conclusies worden aan de hand van de echobeelden zelf gedaan. De meetwaarden dienen ter ondersteuning. 



 

dinsdag 9 februari 2016

Even een ouder onderzoek

In een eerder diagnose onderzoek heb ik gekeken of er zinvol anomalien gevonden konden worden in vastgelegde echo-onderzoeksgegevens. Dat lijkt hoopvol alleen de onderbouwing is niet altijd even goed terug te vinden. Om de meest 'bijdragende' meetfactoren te bepalen heb ik de absolute afwijking van het gemiddelde per meetwaarde genomen. Deze zijn in principe vergelijkbaar omdat ik alle meetwaarden heb teruggebracht tussen nul en een. De meetwaarden met de grootste afwijking van het gemiddelde heb ik bovenaan gezet. Er lijkt wel enige relatie maar het rapport verklaart dus echter niet zo heel sterk waarom bepaalde onderzoeken als anomalie zijn geselecteerd.


Nu wreekt de weggezakte statistiek kennis zich even. Een meetwaarde is natuurlijk meer afwijkend bij een kleine variatie in de waarden dan bij een grote variatie. Kortom ik moet met de standaard deviatie rekening gaan houden. Gelukkig is Numpy daar ook goed in. Ik deel de absolute afwijking van het gemiddelde door de standaard deviatie. Daarmee zou ik dichter bij een verklaring voor de anomalien moeten komen. Ik hoop dat ik dat goed heb bedacht. :-)

Bij het uitvoeren van het programma krijg ik rare 'warnings':


DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.

Tevens hebben mijn meetwaarden allen een gewicht 'nan':

Grootste bijdrage (%):
MR Vmax              nan
MV E/Eprime Ratio/Calc nan
PRend Vmax           nan
2D/EDV(Teich)        nan
2D/%FS               nan
2D/EF(Teich)         nan
2D/ESV(Teich)        nan
2D/SV(Teich)         nan
MV Eprime Velocity   nan

LALs(A4C)            nan

Hmmm. Toch maar eens de voorgestelde reshape(1,-1) erbij uitvoeren. Ik krijg in ieder geval de waarschuwing niet meer. Maar hij doet er nu wel heel lang over. Uiteindelijk komt hij toch terug met de waarschuwingen. Ik zie nu dat het waarschijnlijk aan de 'predict-functie' van sklearn ligt. De moet, net als in andere NN's nu een array als input krijgen in versie 0.19. Ik pas het aan:

if clf.predict(X[i:i+1])[0] == -1:

Helaas, nog steeds nan waarden. Zal dus toch in de toegevoegde standaard deviatie code zitten. Morgen maar eens verder zoeken. 
  


      

zondag 7 februari 2016

MRI - 19 - Weer op stoom

Nu het 'appeltje' weer bij is kunnen we weer vrolijk door met wat Kaggle experimenten. In een voorbeeld oplossing met Keras wordt ook gebruik gemaakt van een de-noising routine voor afbeeldingen.  Die wil ik ook eens proberen. Ik kies ook voor de exotisch genaamde routine: denoise_tv_chambolle.


from skimage.restoration import denoise_tv_chambolle
def Denoise(ImIn):
    return denoise_tv_chambolle(ImIn, weight=0.001, multichannel=False)

Met 'weight' kan je daar instellen of het een grote, vage vlek moet worden of dat er toch nog wat details zichtbaar moeten blijven. Na wat experimenteren kies ik voor 0.001. Zo te zien hou je dan genoeg nauwkeurigheid over om 'slim' de positie van de LV te kunnen bepalen.
Het leeralgoritme blijft echter hangen in 'NaN' resultaten. Ik denk nu toch dat enkele random verschuivingen van de afbeeldingen af en toe 'lege plekken' oplevert die dan met NaN worden ingevuld. Ik vervang ze met nul en nu lijkt alles weer goed te lopen. Ook besluit ik de afbeeldingen aan te bieden inclusief de normalisatie functies. Deze halen de 'outliers' weg en schalen naar een 'zichtbare' reeks.

 

vrijdag 5 februari 2016

Even weer installatie perikelen.

El Captain, de nieuwe versie van het operating system, lonkt al enige tijd. Toch ben ik wat angstig om daar aan te beginnen omdat het vermoedelijk weer een wissel van de grafische kaar nodig heeft. (de GTX890 wekt niet standaard op de macpro en vraagt dus wat trucken met de oude kaart en de drivers) . Anderzijds omdat ik het effect niet ken op mijn huidige python/theano/numpy/keras en noem maar op installatie. Maar ... eens moet je toch dus waarom vanavond niet.


Een handleiding voor de OS switch met gtx980 van Macvidcards.com lijkt niet te werken. Het intoetsen van de Command keys en de 'S' bij het opstarten geeft geen 'zwart scherm met een muur van tekst'.  Dan toch maar de oude kaart er even in plaatsen. Daarna gaat de update naar El Captain zonder noemenswaardige problemen. Alleen het terugplaatsen van de videokaart gaat wat moeizaam. Ik besluit om de usb3.0 uitbreidingskaart er nog maar weer even uit te houden. Heb ik tot nu toe nog nooit gebruikt. (En feitelijk vergeten dat die erin zat).

Spannend! Na het opstarten nog even de eerste installatie schermen door en ja hoor. Daar is die! Ik zie zo op het eerste gezicht nog weinig verschil. Maar misschien is dat wel een goede zaak. Snel Python opstarten en mijn laatste neuraal netwerkje proberen. Ik zie nu dat de .py files standaard de editor 'Idle' opstarten in plaats van Xcode. Hmmm. Meer kleurtjes in de tekst dus wellicht meer overzicht. Kan eens kijken of het bevalt. Er ontstaan wel wat warnings maar geen echte foutmeldingen. Alleen staat er bij CNMeM is disabled.


Using gpu device 0: GeForce GTX 980 (CNMeM is disabled)

Ik zoek het na en een Keras blog belooft een hoge snelheid voor neurale netwerken als het wel wordt enabled. Interessant! Er moet iets in de .Theanorc file aangepast worden. Hoe moest dat ook alweer. Dat had ik al eens eerder in dit blog beschreven. De editor 'vi' is daar zeer bruikbaar voor.


vi ~/.theanorc

Ik voeg de aanbevolen code toe:

[lib]
cnmem=.75


Hij geeft aan te werken.


Using gpu device 0: GeForce GTX 980 (CNMeM is enabled)

Een eerste test met een 'gpu-test' programmaatje geeft geen verschil. Dan maar weer naar het neurale netwerk. Ook daar merk ik nog weinig. Ik kan het mij verbeelden maar de opbouw van het model lijkt zelfs vrij lang te duren. Het trainen is hetzelfde gebleven. 72 seconden per Epoch (5990 afbeeldingen).  Misschien nog wat spelen met de waarden. Ik ben iig al blij dat tot nu toe alles lijkt te werken.


dinsdag 2 februari 2016

MRI - 18 - LV zoeken

De test met het vinden van het linker ventrikel gaat over wat meer hobbels dan gedacht. Op zich is e.e.a. vrij eenvoudig om te bouwen. Alleen een extra kenmerkje toevoegen of de slice 'relevant' is. Een uurtje stevig 'doorklikken' en het opnieuw laten genereren van variaties: Uiteindelijk 6600 stuks. Om een of andere reden geeft het leeralgoritme nu echter af en toe een 'NaN' terug. Oftewel een ongeldige waarde. Waarom nu wel en bij de eerdere 3-punt test van de 2chamber en 4 chamber view niet is mij niet duidelijk. Na wat code-prutsen loopt hij daar in ieder geval niet meer op stuk. Ik zet tevens de oorspronkelijke punten in de afbeelding erbij. Na 100 epochs van 71 seconden elk krijg ik een loss waarde van 5.66 en een score van 4.77. Niet gek. Ook de afbeeldingen lijken over het algemeen redelijk. Niet goed genoeg voor een oppervlakte inschatting maar wel al heel aardig voor een locatie bepaling:

Zwart is oorspronkelijk, licht is berekend.

Ook als de LV niet in het midden zit.

Jammer, net ernaast.




 

maandag 1 februari 2016

MRI - 17 - Heel niet slecht - maar toch ...

Met een hogere leersnelheid (lr van 0,0001 naar 0,001) wordt in 100 epochs een prachtig resultaat bereikt : loss 5.99 en een score van 3.29. Nog eens 200 extra epochs extra (het was toch nacht) maakt de resultaten maar ietsjes beter: loss 5.2 en score 3.23 . Een groot deel van de gevonden punten lijken nu op hun plaatst. De vraag is wel in welke mate er sprake is van 'overfitting'. Dat wil zeggen dat de train-waarden perfect worden gevonden maar nieuwe voorbeelden niet. Normaal wordt dit volledig afgevangen door het onderscheid in train en test data. Door de 'automatische generatie' van de meerdere voorbeelden op basis van een deelset kan er toch overfitting plaatsvinden. Misschien moet ik ook maar eens testen met de validatie data.

Het aardige van de huidige opzet is dat ik die ook kan toepassen op de sax-view. Enerzijds om automatisch het LV te lokaliseren en anderzijds om automatisch te leren welke slices niet bruikbaar zijn.  Dat kan best wel eens 2 vliegen in een klap zijn.