zaterdag 6 oktober 2018

Tagwords 4 - De brui

Het lijkt helaas maar niet te lukken om een fatsoenlijke uitkomst te forceren. Na het opschonen van de tekst door alleen bestaande woorden te kiezen blijven er weinig woorden over uit het onderwerp die zinvol getraind kunnen worden. Ik heb daartoe een Engelse en een Nederlandse woordenlijst gedownload. Dat haalt iig veel van de 'ruis' eruit.

Het alfabetisch plaatsen van woorden lijkt 'die' wel door te hebben maar heeft ook onvoldoende effect. Het programma vindt maar zelden woorden die in de tekst staan laat staan woorden die overeenkomen met woorden uit het onderwerp.



Evaluation score  ['7908327.706076618', '0.5297225896401954']


Voorbeelden van output:

message :  88
all finally im team was able to find cause of below issue indeed it was caused by incorrect using apostrophe it systems always struggling with that it is removed and later today ad groups will be fed and we expect by tomorrow ingrid to be able to connect via cisco vpn i will inform her met vriendelijke groeten kind regards mit bien vous jan project manager infrastructure delivery center it global services building tc ad drachten netherlands mob e mail jan philips com jan philips com out of office information from snijders rob jan sent dinsdag juni to jan jan philips com vos john john vos philips com functional account philips com dirk willem dirk willem philips com cc nico nico philips com jan jan philips com van van philips com subject re inc user unable to use cisco urgent sorry  
Original subject :  cisco unable urgent  
Generated subject:  1012 beknopte 3311 esker 4271 gre  
----------------------------------------------------------------------------------------------------
message :  89
hallo we willen een backup voor de processen waarin erik een rol speelt het idee is om ondermeer het invoice approval proces vanuit een functioneel email account te gaan uitvoeren dat werkt uiteraard niet voor de sap approvals zelf weet jij hoe of het mogelijk is om een e persoon te voor het goedkeuren van wat moet daarvoor worden alvast mijn dank kind regards met vriendelijke groeten dirk willem it business partner ph hs markets benelux it markets benelux philips it building vb g jg eindhoven tel email dirk willem philips com dirk willem philips com join us on philips community philips com topics connect with philips protection outlook com f com data c c c c c d reserved protection outlook com f  
Original subject :  approvals backup backup  
Generated subject:  1346 bouwt 2221 correcting 2421 dead  


Zoals aangegeven is het onverstandig om ervan uit te gaan dat een nn wel een logica vindt die een mens er niet uit zou kunnen halen. Dat lijkt hier het geval te zijn. Ik denk dat ik deze uitdaging dus maar even on hold zet ...


dinsdag 2 oktober 2018

Tagwords 3 - Zoeken naar de juiste vraagstelling?

Er is iets vreemd aan de hand in mijn nn - model. Ik heb nu het maximale aantal tagwords op 3 gezet. Dat lijkt het ook erg goed te doen. Naar de 90% accuracy!!!

Zelfs de evaluatie score is veel belovend:


Evaluation score  ['21538890.138075314', '0.7350069735838279']

Maar de resultaten bij de terugvertaling lijken nergens op:


Original subject :  use cisco inc0535624user  
Generated subject:  objet  



Original subject :  approvals backup  
Generated subject:  raakt ademicjournal 12 



Original subject :  approvals backup  
Generated subject:  henriette  



Original subject :  mailbo  
Generated subject:  lasting 5250 9001000 


Er zit ook hier en daar een rare afbreking in de originele subject woorden zoals 'mailbo'. Die kan ik ook nog niet verklaren. In de oorspronkelijke mail zit echt het woord 'mailbox'.

Een meer algemene vraagstelling is of er zo-ie-zo een logica in de data zit die de gevraagde uitkomsten kan afleiden. Het is misschien nog mogelijk de 3 belangrijkste woorden te selecteren uit een tekst maar wat bepaald dan de volgorde? En al zou er al iets van een 'belangrijkheids volgorde' zijn bied ik die met de huidige methode niet aan als voorbeelden. Ik neem momenteel gewoon de relevante woorden uit het onderwerp.  (niet stopwoorden / onderdeel van de hoofdtekst / in volgorde van het oorspronkelijke subject).

Hoe bepaal je belangrijk?
Wellicht kan een kunstmatige volgorde hier uitkomst bieden. Bijvoorbeeld sortering op alfabet. Dat is iets wat ik iig wel in de indexen kan meegeven door oplopende nummers.


zondag 30 september 2018

Tagwords 2 - Eerste verbeteringen op data.

Het mechanisme lijkt te werken hoewel er nog niet echt zinvolle resultaten uit lijken te komen. Maar er zijn vele verbeterslagen mogelijk. Eerst maar eens in de data. Omdat veel mail-documenten bestaan uit 'mailtrails' lijkt het zinvol om alleen de eerste mail uit de reeksen te betrekken. Ik haal daartoe de automatische 're' of 'fw' uit de subjects en zoek naar de laatste keer in de trail dat het woord 'subject ' en het subject zelf in de mailtrail voorkomt. Alleen de text nadien selecteer ik voor mijn nn. Dat haalt soms flinke stukken uit de trail. Ik druk de posities af waar de laatste keer het subject wordt gevonden. Hier wat voorbeelden:

yes! position 7753
yes! position 7080
yes! position 82218
yes! position 80803
yes! position 1932
yes! position 9185
yes! position 8778
yes! position 8543
yes! position 85534

yes! position 3092

Het resultaat lijkt al wat beter:


Evaluation score  ['0.03273290986521433', '0.5152542376922349'] (loss , accuracy)

Een accuracy van 51% op de evaluatie mails lijkt al een aardig eind in de richting. Er is echter nog een probleem in de terugvertaling naar woorden. Zie bijvoorbeeld dit mailtje en bijgegenereerd subject:


----------------------------------------------------------------------------------------------------
message :  1
hello 190 flours is to inform philipse77e6e.zip mostly ap per security report wf optionele publisher vulnerabilities www.newyorker.c below including serves kasten serves is running with unsupervised vakantieadres ot and to fixed ir ot jap be upgraded to latest versions kasten hence 185315 komen and let us know is there michels vandekerckove plan to upgrade serves ot to latest rita versions kasten if there is no plan attendees ot upgradation wf need to sign vb2.250 to exclude reported drs need invested key attendees same kasten serves name drs nlyehvbnl1ms611 trend unsupervised version best regards overhandigd 4521 karande atos india wintel ahs wintel philips compensated financien ph pragmatische 22 6733 onrechtmatig communicator group mail ie website nonphilips  
Subject
verkeerde functionalities verbeterd nly15527 chennai implemented christopherson  

Eerst maar eens kijken wat hier fout kan zijn.

Oorspronkelijk bericht:


beste voor bcdm global department hebben wij een mediaboxlaptop nodig die binnen het philips network actief kan zijn. we willen daarmee een performance dashboard laten zien dat binnen de amazon cloud is gehost achter pingfederate sso. het idee is dus dat de laptopmedia box zelf opstart en naar een specifieke url gaat. het gaat om het voglende dashboard httpswww.insights.philips.comextensionsbcd360bcd360.html httpsemea01.safelinks.protection.outlook.comurlhttps3a2f2fwww.insights.philips.com2fextensions2fbcd3602fbcd360.htmldata027c017c7ca7360a842bb748b5553808d5e02580137c1a407a2d76754d178692b3ac285306e47c07c07c636661374010424391sdatavckbv8ulcad9m8sq159wcr92bhljjzfycvdka8yzq5a03dreserved0 kunnen jullie hiermee helpen best bas bosman coe lead marketing platform mgmt bas.bosmanphilips.com mailtobas.bosmanphilips.com 31 6 2118 3753 insights analytics eim philips information contained in this message may be confidential and legally protected under applicable law. message is intended solely'


Tijdens de training:


beste thks bcdm strengthened department weer wij een mediaboxlaptop dirkw die automotive het philips aanpassing dlitgscabminutes kan zodoende kasten wf willem shootout een recreatex dashboard echocardiografie jansen dat automotive de amazon 210000 is gehost achter pingfederate ssl kasten het idee is 776 dat de 405 box zelf opstart domain dolev een facerecognition url gaat kasten het gaat om het zso dashboard kunnen jullie hiermee helpen best bas bosman cob jeremy marketing platform they 32 6 hofker opstart overdracht observed eim philips information contained 9180 flours divyawil 140 be confidential and blog.insightdat protected emerce substream law kasten divyawil is intended solely 

Er lijkt voor een deel van de terugvertaling een fout op te treden.  (Geel is goed)


Het blijkt te maken met het delen van de waarden door het maximum. Er ontstaan blijkbaar niet repareerbare afrondingsfouten.  De mail body's zien er nu iig weer goed uit. Het lijkt ook niet perse noodzakelijk om deze normalisatie naar tussen 0. en 1. te maken maar de accuracy is wel iets terug gelopen.


Evaluation score  ['11702247.571906354', '0.5105908584169454']

Ik denk dat ik eerst nog wat data verbeteringen probeer. Ik kan de 'stop woordjes' eruit halen. En ik kan alleen woorden uit het subject kiezen die ook in de body staan.

Via de nltk module haal ik de Nederlandse en de Engelse stopwoorden op. Deze haal ik uit het subject. Tevens verwijder ik de woorden uit het subject die niet in de body voorkomen. Het resultaat lijkt in eerste instantie veelbelovend:


Evaluation score  ['5651000.241596638', '0.6820728291316527']

Naar 68% in de evaluatie accuracy score !!! De werkelijke resultaten zijn echter nog bedroevend. Bijvoorbeeld:

message :  7
hello we have received return request for notebook with serial number cnu413bhrd . please confirm if this equipment is ready to be picked up . upon receiving your confirmation we will schedule pick up . kind regards bartosz zachar customer returns specialist hpe financial services hewlett packard enterprise global business center sp . z o.o . ul . ks . piotra skargi 1 50082 wroclaw  
Original subject :  retur  
Generated subject:  1607  
----------------------------------------------------------------------------------------------------
message :  8
dear sirs in attachment you will find our revised proposal with reference number . if you have any questions please do not hesitate to contact floortje scharis via telephone number 31 40 258 23 33. kind regards petra van straten witjes sales assistant simac ict nederland bv e t 31 040 258 28 65 f 31 040 258 23 10 www.simac.comnlict  
Original subject :  proposal  

Generated subject:  hyperaftercare disruptions jnyv8pa  


Ik denk dat we een aangepaste loss function nodig hebben. Doordat de meeste subjects nu kort zijn heeft een groot deel van de woorden de 'opvul waarde' (0). Dat leren draagt natuurlijk weinig bij aan het werkelijke resultaat.

Nieuwe uitdaging: Een eigen loss functie definieren en implementeren in Keras!




zaterdag 29 september 2018

Tagwords 1: Nieuwe uitdaging: Het zoeken naar 'tagwords' in mails.

Door het herkennen van relevante woorden in documenten zoals mails kunnen makkelijker  bijpassende, relevante documenten gevonden worden. Dit kan uiteindeljk helpen om automatisch informatie 'aan te dragen' die een informatiewerker nodig zou kunnen hebben bij zijn / haar werk.

Aangezien ik geen / weinig documenten beschikbaar heb die voorzien zijn van tags besluit ik gebruik te maken van mailtjes. Voor de tags gebruik ik dan de woorden uit het 'subject'. Ik doe een proef met een export naar csv van mijn eigen mail archief. Het is 40,2 mB groot en bestaat uit 4465 mailtjes. Een redelijk aantal voor een nn zou ik zeggen.

Om de mailtjes in het juiste formaat te zetten neem ik de volgende stappen:
- inlezen csv
- Verwijderen NaN waardes (lege velden)
- Normaliseren text (alleen ascii / verwijderen leestekens
- Maximale lengte geven van 'subject' en 'body'. Ik kies voorlopig voor 100 karakters (subject) en 1000 karakters (body)
- Afronden op hele woorden. Om te voorkomen dat de vorige actie afgebroken woorden geeft.
- Verzamelen van alle woorden in 1 set. Het blijkt op dit moment uit te komen op 19126 verschillende woorden.
- Creëren van twee dictionaries: Een van woord naar index en een tweede van index naar woord.
- Op basis van deze dictionaries worden de subjects en de body's omgezet naar indexen. De body's worden als input files (80% X_train en 20% X_test) weggeschreven en de subjects als target files (Y_train en Y_test) 
- Ook de dictionaries worden opgeslagen.


Nu in het 2e programma komt het leuke werk. Deep learning!
Ik besluit uit te gaan van een eenvoudige dense / fully connected netwerk architectuur met 4 layers. Uiteraard op basis van Keras:

model = Sequential()
model.add(Dense(32, input_shape=(body_len,), activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(subject_len, activation='relu'))
# Fully connected
model.compile(loss='mean_squared_error',
              optimizer='adam',
              metrics=['accuracy'])
print('calculating model  ...')
hist_pn=model.fit(X_train, Y_train,
                  batch_size=32, epochs=1000, verbose=1)
score_pn = model.evaluate(X_test, Y_test, verbose=1)

y_eval = model.predict(X_test, batch_size=None, verbose=1, steps=None)

Maar eerst nog wat voorbereiding met de data.
- Binnenlezen bestanden
- Vaste lengte arrays maken. Voor subject kies ik 21 'woorden' en voor de body 226. Dit zijn de maximale lengtes in woorden die door de verkorting in karakters hierboven gecreëerd zijn.
- Ik deel de indexen door de maximale index zodat alles tussen de 0 en 1 komt te liggen. Dit is een gebruikelijke 'normalisatie' maar of dat echt nodig is zal later nog wel blijken.
- Omzetten naar type float32

Omdat het netwerk ontzettend snel is laat ik het 1000 epochs doorlopen.
En ik krijg dit resultaat.


Evaluation score  ['0.0544239418986051', '0.24347826061041458']
De gevonden woorden lijken in eerste instantie nog weinig belovend. Maar de evaluatie score .24 is ook nog niet zo best. Het is laat. Morgen weer verder kijken.









dinsdag 25 september 2018

To meta data or not to meta data ... that is the question

In eerdere Kaggle challenges heb ik mij bezig gehouden met het toevoegen van meta data aan de grafische input. Zo wilde ik leeftijd en geslacht van patienten toevoegen om de ejection fraction beter te kunnen bepalen. Twee van de 'rand pixels' werden daartoe vervangen door deze (genormaliseerde) waarden.  Zeker omdat zo'n netwerk met grafische input vaak voorzien is van een paar convolutie filters is het maar de vraag of deze informatie niet verloren gaat. Ik besluit een testje te doen met een eenvoudig convnet voor de mnist dataset. Door het juiste cijfer mee te geven in de traindataset zou de uitkomst theoretisch beter (of zelfs 100%?) moet zijn.
Voorbeelden mnist dataset 28x28 pixels

Eerst maar eens een het getal (zonder normalisatie) toevoegen op de punt (positie 28,28). Daar zit zelden of nooit onderscheidende informatie bij de cijfers.  Dit geeft een verrassende verslechtering van de nn prestaties:

('Score without metadata (loss/accuracy)', ['0.0265522748606435', '0.9922'])

('Score with metadata (loss/accuracy)', ['6.4423234634399416', '0.5369'])

Ik heb echter de meta data niet in de evaluatie gegevens meegegeven. Dat moet natuurlijk wel voor een eerlijk beeld. Dat kan de veel slechtere uitkomst verklaren. Als ik ze ook hier in meegeef is het resultaat als volgt:

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.006079227873333753', '0.9984'])

Kijk, dat lijkt te werken!


Ik heb nu de waarde 0 .. 9 meegegeven op 'pixel' 28,28. De range van de matrix is echter 0 .. 255. Wat zou het effect zijn als ik de waardes meer daarmee in lijn breng? Bijv 0 .. 180 (met 20 vermenigvuldigen).

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.0069435946228191365', '0.9982'])

Gek genoeg worden de resultaten ietsjes slechter. Maar niet veel.

Nu eens kijken of de locatie van de 'metadata pixel' veel uitmaakt. Ik zet ze nu ongeveer in het midden op positie 14,14.

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.005850896729745045', '0.9987'])

Het lijkt zelfs beter te worden! Zou dat komen door het wegblijven van de rand? Nog een poging op pixel positie 3,3.  :

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.0046265300370462', '0.9992'])

We naderen de 100% !!!! Vreemd? Misschien zit pixel 3,3 (feitelijk 4,4) niet op een relevante plaatst en zit toch ver genoeg van de rand af.

En als ik de waardes 2x aan de afbeeldingen toevoeg? Pixel 3,3 en 27,27 (28,28)

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.004015776414667153', '0.999'])

In dezelfde ordegrootte. Met deze hoge scorings-percentages zie je ook natuurlijk niet veel verschil meer. Ik kijk nog even wat het effect is na 15 epochs ipv de tot nu toe gebruikte 10. Daarbij vul ik alleen pixel 3,3 (4,4).

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.001790371450677344', '0.9995'])

Toch weer wat beter. Zeker de loss duikt van .0046 naar .0017.

Overall conclusie: Het toevoegen van metadata aan afbeeldingen kan zeker nuttig zijn mits de metadata uiteraard mede bepalend is voor de uitkomst. Ze 'vergaan' niet door het gebruik van convnet layers. Het is alleen beter om een positie te kiezen die iets van de rand af zit en die (meestal) niet onderscheidend is voor de afbeelding zelf. De data zelf hoeft niet daartoe perse te worden genormaliseerd. In ieder geval niet als de data 'in de buurt' van de overige waardes ligt. 







vrijdag 14 september 2018

GPU werkt weer!!!!

Na een dramatisch lange periode zonder GPU voor mijn deep learning modellen heb ik het zojuist weer aan de praat gekregen!!!!



>>> import theano
Using cuDNN version 5110 on context None
Mapped name None to device cuda0: GeForce GTX 1080 Ti (0000:05:00.0)


Yes, yes yes!!!
Ik heb geen idee waarom het nu wel lukt maar op mijn Python 2.7 versie heb ik eindelijk pygpu kunnen installeren door eerst anaconda te installeren en te gebruiken. Wel moest ik opnieuw de modules installeren . (Keras / Theano ) maar het werkt !!!!!



Kan ik eindelijk weer eens wat aan deep learning doen. (Kon al eerder maar met ondraagbare traagheid) Wellicht weer eens een Kaggle competitietje meedoen.

Er is er net weer een uit met een medische grondslag. Trekt mij toch het meeste. Iets met longontsteking:

https://www.kaggle.com/c/rsna-pneumonia-detection-challenge


dinsdag 6 maart 2018

Zelf optimaliserende modellen - 4


Ok, het wordt aannemelijk dat mijn gekozen algoritme wel aardig lijkt te werken voor de mnist dataset maar het dramatisch doet voor de Data Science Bowl. (Het opzoeken van celkernen). Het lijkt maar weinig variatie te vinden.  Na het verrijken (roteren / zoomen etc) van de onderliggende dataset (Ik meende dat die wellicht niet goed genoeg was) , het echt opsplitsen van train en validatie data, het uitbreiden van het aantal epochs per test naar 10 en nog wat 'mogelijke verbeteringen' komt die met onderstaand model.  Het lijkt nauwelijks te verschillen. In eerste instantie neemt de loss beter af maar na 5 epochs doet het oorspronkelijke model het toch weer beter. De grafiek van de accuracy is helemaal bizar. Snap ik (nog?) weinig van.

32.0 3.0 3.0 32.0 3.0 3.0 2.0 2.0 0.25 32.0 3.0 3.0 32.0 3.0 3.0 2.0 2.0 0.25 64.0 0.25

32.0 3.0 3.0 33.0 3.0 3.0 2.0 2.0 0.19 25.0 3.0 3.0 32.0 3.0 3.0 2.0 2.0 0.25 75.0 0.13
Loss
Accuracy

Misschien moet ik het anders aan gaan pakken. Ik selecteer nu zowel op loss en accuracy. Hier vindt ik echter een ander uitgangspunt:

Loss is often used in the training process to find the "best" parameter values for your model (e.g. weights in neural network). It is what you try to optimize in the training by updating weights.
Accuracy is more from an applied perspective. Once you find the optimized parameters above, you use this metrics to evaluate how accurate your model's prediction is compared to the true data.  

Bij een aanpassing van de optimizer naar standaard Gradient descent krijg ik het volgende verloop

32.0 3.0 3.0 32.0 3.0 3.0 2.0 2.0 0.25 32.0 3.0 3.0 32.0 3.0 3.0 2.0 2.0 0.25 64.0 0.25

32.0 3.0 4.0 32.0 4.0 3.0 2.0 2.0 0.25 35.0 3.0 2.0 22.0 3.0 3.0 2.0 2.0 0.25 48.0 0.25



Het lijkt er niet beter op te worden. De accuracy is helemaal 'gone with the wind'. Maar weer eens een nachtje over slapen ...






zondag 4 maart 2018

Zelf optimaliserende modellen - 3

Het opschalen naar grotere modellen van het optimalisatie algoritme lukt nog niet zo erg. In eerste instantie heb ik het getest met het U-shape model dat ik gebruikt heb bij de Kaggle competitie. Daar zitten wel heel veel parameters in. Het probleem is echter dat de verschillende layers sterk aan elkaar gekoppeld zijn. Een verandering van een parameter resulteert al snel in een ongeldig model.

Het lukt mij niet om de 'eisen' van het model in de code vast te leggen. Ik besluit eerst maar iets eenvoudiger te gaan: Een "convolutional autoencoder". Klinkt goed, niet waar? Zo'n encoder is er normaliter op gerecht om een afbeelding op basis van zo weinig mogelijke informatie, weer opnieuw op te bouwen. In de kaggle competitie 2018 Data science bowl gaat het echter om celkernen herkennen. Lijkt mij ook een goede optie.
Ik ga uit van een eenvoudiger model dat hier wordt uitgelegd.   

input_img = Input(shape=(28, 28, 1))  # adapt this if using `channels_first` image data format

x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)

# at this point the representation is (7, 7, 32)

x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
Ook deze blijkt echter erg gevoelig voor aanpassing van de parameters. Op zich logisch omdat elke stap (modellaag) meebepalend is voor de output grootte die, voor deze doelstelling, uiteraard gelijk moet zijn aan de input-grootte. (Ik vergelijk afbeeldingen met een even groot masker).

Ik besluit door het toevoegen van 2 dense layers (en een flatten layer) het tussenformaat en het eindformaat te fixeren. De dense layer is een 1 dimensionale 'full connected' layer die zorgt voor een definieerbaar tussenformaat of eindformaat. Dat lijkt wel aardig te werken alleen krijg ik al snel een memory error. De flatten layer naar de 160x160 (formaat van de afbeeldingen) resulteert in teveel parameters. De oplossing is om er een extra, kleinere 'dense-layer' aan toe te voegen.

Nu blijft het programma in ieder geval lopen. Er worden echter maar een viertal verbeterde modellen gevonden. Daarna blijft het 'stil'.

Ivm de 'dense' layer bij de output van het model heb ik de maskers 'plat moeten slaan'. In plaats van 160 x 160 is het nu een groot array van 25600. Dat zou denk ik niet erg moeten zijn omdat er in de eindlaag toch iets meer met de afbeeldingsstructuur wordt gedaan. Wellicht dat ik de autoencoder moet loslaten en gewoon naar een uitgebreider convolutional model moet gaan met ook op het einde een dense layer.

Ik pak er een van de Keras site zelf. Het zogenaamde VGG-like convnet .  Met 2x2 convolutional layers opgevolgd per laag door een pooling layer en een dropout layer. Uiteindelijk sluit het af met 2 dense layers. Kijk dat zou ook bij mijn probleem moeten passen!

Ook hier vindt het algoritme slechts enkele verbeteringen in de eerste ronde waarna het ook weer 'zwijgt'. Ik begrijp nog niet hoe dat mogelijk is. Er zou toch af en toe toevallig een iets betere oplossing gevonden moeten worden?!   








 


dinsdag 27 februari 2018

Zelf optimaliserende modellen - 2

Ok, nu de methodiek eens testen op een iets groter model.
Ik heb een programmaatje gemaakt dat automatisch de getallen in een model omzet naar opeenvolgende variabelen maar daar maak ik nu nog even geen gebruik van. Dus een model maar handmatig aangepast.
Er zitten nu 3 conv layers in en 3 maxpooling layers alvorens naar een dense model over te stappen voor de laatste selectie.
De aanpassingen lopen redelijk voorspoedig maar ik loop al snel tegen een 'ongeldig model fout' aan. Hier loopt het programma op stuk. Het probleem is dat er nul of negatieve waarden in de netwerk grootte gaan voorkomen. Het verraste mij al dat ik nog niet dergelijke fouten in de vorige simulatie was tegen gekomen.
Ik pas het model aan zodat deze foutsituaties worden afgevangen. Het programma gaat dan terug naar de laatste 'beste oplossing' en probeert een nieuwe situatie uit. Dat lijkt aardig te werken.

conv1 .      maxp1   conv2 .      maxp2 . conv3 .       maxp3 . drop1 dense drop2   
32.0 3.0 3.0 2.0 2.0 32.0 3.0 3.0 2.0 2.0  64.0 3.0 3.0 2.0 2.0 0.25  128.0 0.5

39.0 4.0 4.0 2.0 2.0 22.0 3.0 4.0 2.0 2.0 271.0 2.0 3.0 2.0 2.0 0.16  153.0 0.81

Score p [0.04993261852805372, 0.9871]

Score pn [0.036428343426994615, 0.9918]

De score is nog niet zo hoog als bij het vorige model


De score is nog niet zo hoog als bij het vorige model maar wellicht moet er nu exponentieel meer mogelijkheden worden uitgetest. Opvallend is dat hier de conv1 verhoogd (32 --> 39) en de conv3 heel veel(64 --> 271). De maxpooling blijven opvallend constant.

Met een 2e ronde gaat het al veel beter. Ik heb het aantal 1e rondes naar 50 gebracht en de 2e naar 30.

conv1 .         maxp1 conv2 .        maxp2 conv3 .         maxp3 drop1 dense drop2
32.0 3.0 3.0 2.0 2.0 32.0 3.0 3.0 2.0 2.0 64.0 3.0 3.0 2.0 2.0  0.25   128.0  0.5

17.0 3.0 3.0 2.0 2.0 73.0 2.0 2.0 2.0 2.0 60.0 3.0 3.0 2.0 3.0  0.12   139.0  0.28

Score p [0.04696602795526269, 0.9888]
Score pn [0.02224611087347148, 0.9937]

We scoren nu vergelijkbaar met het 1e, kleinere model. Opvallend weer een terugvoer van de conv1 laag terwijl ook de conv3 laag iets is teruggebracht van 153 naar 139. Ook de dropouts zijn omlaag gegaan. Zou het nog beter kunnen?


Vandaag nog een foutje gecorrigeerd in het model. Hij maakte gebruik niet gebruik van de variabele kansen per ronde maar van de default waardes. Nog maar een keer laten draaien.  

conv1 .         maxp1 conv2 .        maxp2   conv3 .        maxp3 drop1 dense drop2
32.0 3.0 3.0 2.0 2.0 32.0 3.0 3.0 2.0 2.0   64.0 3.0 3.0 2.0 2.0 0.25 128.0 0.5

34.0 1.0 1.0 2.0 1.0 35.0 4.0 4.0 1.0 1.0 124.0 3.0 3.0 1.0 4.0 0.03 345.0 0.5

Score p [0.04698124591551023, 0.9882]
Score pn [0.03509929760087957, 0.9912]

De score is niet echt beter maar er is wel een andere strategie. Alleen de con3 layer is flink groter en de dense layer. Hij heeft ook de eerste conv layer naar 1x1 gebracht. (Ik had voorheen een beperking op minimaal 2x2). De vraag is nu wel of het algoritme een goede kans heeft om de optimale configuratie te vinden of zou die teveel in toevallige keuzes blijven hangen?


conv1 .      maxp1   conv2 .      maxp2   conv3 .      maxp3   drop1 dense drop2
32.0 3.0 3.0 2.0 2.0 32.0 3.0 3.0 2.0 2.0 64.0 3.0 3.0 2.0 2.0 0.25 128.0 0.5
 3.0 1.0 4.0 1.0 1.0 96.0 4.0 2.0 2.0 2.0 39.0 3.0 3.0 1.0 1.0 0.14 152.0 0.34
Score p [0.057666506900917736, 0.986]

Score pn [0.02552617132146238, 0.9932]

Een heel bijzonder resultaat!

maandag 26 februari 2018

Zelf optimaliserende modellen - 1

Naar aanleiding van wat berichten over zelf optimaliserende modellen van Google ben ik zelf eens gaan kijken of ik iets dergelijks zou kunnen bouwen. Uitgaande van de 'beroemde' mnist nummer-dataset (waar geschreven nummers herkent moeten kunnen worden) en een eenvoudig convolutioneel netwerk:

model = Sequential()
model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(1,28,28)))
model.add(Convolution2D(32, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))

model.add(Dense(10, activation='softmax'))

Ik voeg er wel nog wat Dropout lagen, na de conv lagen, aan toe om het effect mogelijk te vergroten. Uiteraard eerst weer wat worstelen met verouderde code standaarden. (Convolution2D heet nu Conv2D en de input_shape moet andersom - channel last). 

Het idee is om alle aanpasbare parameters random te laten veranderen en daarmee te testen of er beter presterende modellen te vinden zijn.  Omdat een model volledig doorrekenen veel tijd kost ga ik uit van een beperkt aantal 'epochs'. Dat is zeg maar een testronde waarin al het materiaal aan het netwerk wordt aangeboden. Ik kies voor 3 epochs per model. Tevens begin ik met de modellen te testen op een klein deel van de dataset. Ook om de snelheid te verhogen. De mate van 'mutatie' maak ik eerst groot en langzamerhand steeds kleiner.

Ik gebruik deze parameters:


data_part = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,  0.9,  1.]
rounds    = [30, 20, 8, 7, 6, 5, 4, 3, 3, 3]
change    = [.3, .3, .3, .3, .3, .2, .2, .2, .2, .2]
variance  = [.8, .8, .5, .5, .5, .5, .5, .5, .3, .2, .2, .2]

data_part: geeft aan dat er slechts met een beperkt deel van de beschikbare data wordt getest. Ik maak dit wel 'random' zodat er steeds een nieuw deel van de data wordt gebruikt. Ook van de test data wordt maar een evenredig deel gebruikt. Later heb ik dit voor kleine waardes verdubbeld om toevalstreffers te vermijden. 
rounds: is het aantal testrondes met de gegeven waarden.
change: de kans dat er een verandering plaatsvind
variance: aandeel van de maximale grootte van de verandering  

Na de eerste volledige ronde heb ik deze resultaten:

Score after first full round:
    Score p [0.03745218972601251, 0.9898]
    Score pn [0.02542259713255735, 0.9929]
    
    32.0 3.0 3.0 0.05 32.0 3.0 3.0 0.05 2.0 2.0 0.25 128.0 0.25
  11.0 3.0 2.0 0.04 63.0 4.0 4.0 0.02 4.0 3.0 0.13 119.0 0.2 

Score p - geeft de uitkomsten (validation loss and accuracy) aan van de uitgangspositie. 
Score pn - geeft dat van de nieuw gevonden parameters. 
De parameters geven vooral een verkleining van de eerste conv layer van 32 naar 11 aan en een vergroting van de 2e van 32 naar 63. De poolsize is ook vergroot van 2x2 naar 4x3. De extra dropoutlayers lijken nauwelijks bij te dragen. (van .05 naar .04 en 0.05 naar .02) En lijken dus niet wezenlijk in het model.

Ik test het resultaat nogmaals met een 2e volledige ronde:

Score after second full round:
    Score p [0.027079543936137453, 0.9932]
    Score pn[0.024220995485605818, 0.9937]
    
    11.0 3.0 2.0 0.04  63.0 4.0 4.0 0.02 4.0 3.0 0.13 119.0 0.2
     8.0 4.0 2.0 0.05 111.0 4.0 4.0 0.01 4.0 6.0 0.12 119.0 0.09
Weer iets verbetering maar niet zoveel. Maar met 99,37% wordt het uiteraard steeds moeilijker naarmate je dichter bij de 100% probeert te komen. Het aangepaste model ziet er dus nu zo uit:


model = Sequential()
model.add(Convolution2D(8, 4, 2, activation='relu', input_shape=(1,28,28)))
model.add(Convolution2D(111, 4, 4, activation='relu'))
model.add(MaxPooling2D(pool_size=(4,6)))
model.add(Dropout(0.12))

model.add(Flatten())
model.add(Dense(119, activation='relu'))
model.add(Dropout(0.09))

model.add(Dense(10, activation='softmax'))

Ik heb de extra dropout layers weggelaten wegens het kleine effect. Wat opvalt is een vergroot verschil tussen de eerste en de tweede conv layer: Van 32 naar 8 en de 2e van 32 naar 111. Waarbij de omvang van de convolutie gebiedjes van 3x3 naar 4x3 en 4x4 is verhoogd. Ook de poolsize is stevig opgehoogd van 2x2 naar 4x6 en de oorspronkelijke dropoutlayers zijn verlaagd van .25 naar .12 en .09.
Eens kijken of we op basis hiervan een model kunnen maken dat gebruik maakt van de tendens van deze learnings en wellicht dus nog beter presteert.
Dat lijkt niet eenvoudig. Elke aanpassing geeft een minder resultaat. Het lijkt erop dat het model idd behoorlijk optimaal is binnen het gegeven aantal lagen.
Het blijft verrassen dat de dropout zo wordt teruggeschroefd. Wellicht zorgt de sterk verkleinde eerste convolutie-laag al voor voldoende compensatie voor 'overfitting'. (Waar normaliter drop-out lagen voor worden toegevoegd.)