maandag 29 juni 2015

Kaggle, Kappa en 'boosted random forests'

Vanuit mijn uitgebreide lezerskring krijg ik terecht de opmerking dat het hier 'al even stil is aan het front'. Hoog tijd voor een nieuwe update. Het rondsnuffelen op 'deep-learning' sites brengt je langs de meest wilde en interessante ideeën. Een aardig initiatief is kaggle.com. Een site waar DL 'vraag en aanbod' elkaar kunnen vinden in de vorm van competities. Zo leeft er vanuit 'The US Center for Disease Control and Prevention ', (waarschijnlijk US-CDCP oid?) om met een machine learning algoritme zo goed mogelijk vast te kunnen stellen van een foto van de 'retina' (het netvlies van het oog) of iemand beginnende kenmerken van Diabetes heeft. Eerste prijs 100.000 dollar!!! Heee, dan kan een hobby nog interessant worden :-) En och, er doen nog maar 473 ervaren teams van over de hele wereld mee. Moet te doen zijn ;-)

In elk geval zeer interessant om daar eens mee te kijken want een heleboel ideeën en code wordt uitgewisseld. Een van de blogs threads gaat over 'boosted random forests'. Tja, dan maar eens kijken wat dat nou weer is. Daar kom je dan weer de 'kappa statistic' tegen. - Had ik die al eens eerder gezien? - De boosted random forests moet ik nog eens nakijken maar de kappa statistic wordt gebruikt om een eerlijker betrouwbaarheid weer te geven:

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. Eigelijk wel logisch. Weer wat geleerd. Leuk toch :-)





maandag 22 juni 2015

Meer graan

Nog een testje met de befaamde graankorrels. Ik heb de logische fout van op elkaar gestapelde 'graantjes' eruit gehaald. Daarnaast zit er, iig in het convolutial algoritme (convnet), 'ruis' wat erop neerkomt dat graantjes van 1 pixel groot volledig kunnen verdwijnen. (Gezien wat 'artefacten' - kleine zwarte puntjes - in het sklearn programma-resultaat denk ik dat daar ook ruis wordt toegepast. Zie afbeelding hieronder.) Dus maar een minimum 'graankorrel' van 2x2 gekozen.  Het convnet levert een betrouwbaarheid op van ruim 99%. Wat wel opvalt is dt het per leer-loop nogal varieert.  Soms loopt die snel op maar soms ook valt de betrouwbaarheid even weer behoorlijk terug. Heeft mogelijk met het type vraagstuk te maken. Geschreven cijfers lezen is toch wat anders dan graankorrels tellen. Niettemin een zeer acceptabele betrouwbaarheid: 
...

87 32.0703961849 seconds / reliability:  0.9795
88 32.0824241638 seconds / reliability:  0.992166666667
89 32.0566852093 seconds / reliability:  0.995333333333
90 32.0832369328 seconds / reliability:  0.992333333333
91 32.0895729065 seconds / reliability:  0.966333333333
92 32.048817873   seconds / reliability:  0.992333333333
93 32.0678329468 seconds / reliability:  0.995
94 32.0670650005 seconds / reliability:  0.995833333333
95 32.429267168   seconds / reliability:  0.9955
96 32.1072170734 seconds / reliability:  0.9925
97 32.0676319599 seconds / reliability:  0.99
98 32.0874857903 seconds / reliability:  0.982333333333
99 32.0707070827 seconds / reliability:  0.991666666667 

Blijkbaar door het type vraagstuk. 


Dit is de gebruikte code om de graantjes aan te maken. 60.000 plaatjes in ongeveer 9 seconden. Iets minder for-loopjes door sub-matrix bewerkingen.  

####################################
t0 = time.time()
si = 60000          # Aantal oefenafbeeldingen
t_si = -.1 * si     # testset 10%
h = 28              # hoogte
b = 28              # breedte
r = 3               # (max) graan-grootte + 2
a = 5               # (max) aantal graantjes

ima = np.zeros((si, h * b))

ima.shape = si, h , b
grains = np.floor(np.random.rand(si) * a) + 1 #minimaal 1 graantje
num = np.zeros((si,10))
for i in range(si):
    num[i,int(grains[i])]=1.

for i in range(0,si):
    for j in range(0,int(grains[i])):
        notfree = True
        while notfree:
            ho = np.floor(np.random.rand() * (h-r))
            br = np.floor(np.random.rand() * (b-r))
            vr = 2 + np.floor(np.random.rand() * r)
            #vr = r
            notfree= np.sum(ima[i,int(ho):int(ho+vr),int(br):int(br+vr)])!=0      # Test of er plaats is voor het 'graantje'.
        ima[i,int(ho):int(ho+vr),int(br):int(br+vr)] += 1

ima.shape = si, h * b
trX,trY = ima[:t_si], num[:t_si]
teX,teY = ima[t_si:], num[t_si:]
print 'test files generated', time.time() - t0, 'seconds'

####################################


zondag 21 juni 2015

Geen crash meer!!!

Na het debacle met de voeding, die ik straks terug ga sturen, schoot het mij te binnen dat ik op een andere manier de voeding aan de grafische kaart zou kunnen aansluiten. Bij de kaart zat een 2x6 female naar 1x8 male pcie voedingskabel. Daar heb ik gebruik van gemaakt om de 2 x 6 male kabels van mijn mac op aan te sluiten.
De 6 pins voedings poort op de kaart bleef dus onbezet.
verloop-kabel 2x6 female naar 8 male

6 en 8 pcie poort op de videokaart

Logischerwijs zou dat beide voedingsbronnen naar de kaart begeleiden. Maar de 'crash' van de kaart bij zwaarder gebruik leek een aanvullende voeding noodzakelijk te maken. 
Hoewel ik er weinig van verwachtte heb ik nu een van 6 pins male rechtstreeks op kaart geplugd. (en de ander laten zitten aan de verloop-kabel naar de 8 pins poort) Dat lijkt het ei van Columbus! 

Het convolutional netwerk, dat eerst crashde bij ongeveer 23 loops gaat nu zonder problemen tot de 30. En ook een 2e keer! En ook met 100 loops!  Hij lijkt stabiel!!! Nog even afwachten of dit ook bij het renderen met Final Cut zo blijft maar het ziet er hoopvol uit!  

zaterdag 20 juni 2015

Grote, kleine en convolutional graantjes

De eerste tests met de 'graantjes' waren veelbelovend. Een meting op de betrouwbaarheid zat rond de
98,4%. Toch al aardig. Wel blijkbaar afhankelijk van de het formaat (4x4) van de graankorrels. Een kleine korrel (2x2 pixels) geeft 99,8% !!!! 1 pixel doet het dan weer heel veel slechter (46,8%). Bij grotere graankorrels zal de kans van overlapping natuurlijk toenemen.

Omdat het graan-formaat zoveel uitmaakt is het ook interessant om te kijken wat een variable formaat doet. Ik kies een formaat van 1 tot 9 pixels (3x3). De betrouwbaarheid holt achteruit. (48%). Daar een convolutional network meer naar 'features' kijkt dan naar vormen zou dat hiervoor geschikter moeten zijn. Hoewel mijn videokaart nog onbetrouwbaar is (Nieuw binnengekomen voeding lijkt niet te werken) ga ik het toch maar proberen. Na enig passen en meten (sleutelen aan de vorm van input dataset met de graantjes en de resultaat dataset met de aantallen) lukt het om het programma draaiende te krijgen. Na 100 zenuwslopende leer-loops (blijft de kaart het volhouden?!) blijft de stand steken op 91% Nog niet hoog maar heel wat beter dan het skikit SVC algoritme. Blijkbaar is graantjes tellen ingewikkelder dan het lijkt. Misschien moet ik de logische fout (graantjes boven op elkaar) er eerst nog even uithalen om het echt te kunnen beoordelen.



 Hier weer het gebruikte programma:

import theano
from theano import tensor as T
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
import numpy as np
from theano.tensor.nnet.conv import conv2d
from theano.tensor.signal.downsample import max_pool_2d
import time
srng = RandomStreams()
####################################
si = 5000           # Aantal oefenafbeeldingen
t_si = -.1 * si     # testset 10%
h = 28              # hoogte
b = 28              # breedte
r = 3               # (max) graan-grootte
a = 5               # (max) aantal graantjes

ima = np.zeros((si, h * b))

ima.shape = si, h , b
grains = np.floor(np.random.rand(si) * a)
num = np.zeros((si,10))
for i in range(si):
    num[i,int(grains[i])]=1.

for i in range(0,si):
    for j in range(0,int(grains[i])):
        ho = np.floor(np.random.rand() * (h-r))
        br = np.floor(np.random.rand() * (b-r))
        vr = 1 + np.floor(np.random.rand() * r)
        #vr = r
        for x in range(int(ho),int(ho+vr)):
            for y in range(int(br),int(br+vr)):
                ima[i,x,y] = 1
ima.shape = si, h * b
trX,trY = ima[:t_si], num[:t_si]
teX,teY = ima[t_si:], num[t_si:]
####################################
def floatX(X):
    return np.asarray(X, dtype=theano.config.floatX)

def init_weights(shape):
    return theano.shared(floatX(np.random.randn(*shape) * 0.01))

def rectify(X):
    return T.maximum(X, 0.)

def softmax(X):
    e_x = T.exp(X - X.max(axis=1).dimshuffle(0, 'x'))
    return e_x / e_x.sum(axis=1).dimshuffle(0, 'x')

def dropout(X, p=0.):
    if p > 0:
        retain_prob = 1 - p
        X *= srng.binomial(X.shape, p=retain_prob, dtype=theano.config.floatX)
        X /= retain_prob
    return X

def RMSprop(cost, params, lr=0.001, rho=0.9, epsilon=1e-6):
    grads = T.grad(cost=cost, wrt=params)
    updates = []
    for p, g in zip(params, grads):
        acc = theano.shared(p.get_value() * 0.)
        acc_new = rho * acc + (1 - rho) * g ** 2
        gradient_scaling = T.sqrt(acc_new + epsilon)
        g = g / gradient_scaling
        updates.append((acc, acc_new))
        updates.append((p, p - lr * g))
    return updates

def model(X, w, w2, w3, w4, p_drop_conv, p_drop_hidden):
    l1a = rectify(conv2d(X, w, border_mode='full'))
    l1 = max_pool_2d(l1a, (2, 2))
    l1 = dropout(l1, p_drop_conv)

    l2a = rectify(conv2d(l1, w2))
    l2 = max_pool_2d(l2a, (2, 2))
    l2 = dropout(l2, p_drop_conv)

    l3a = rectify(conv2d(l2, w3))
    l3b = max_pool_2d(l3a, (2, 2))
    l3 = T.flatten(l3b, outdim=2)
    l3 = dropout(l3, p_drop_conv)

    l4 = rectify(T.dot(l3, w4))
    l4 = dropout(l4, p_drop_hidden)

    pyx = softmax(T.dot(l4, w_o))
    return l1, l2, l3, l4, pyx

trX = trX.reshape(-1, 1, 28, 28)
teX = teX.reshape(-1, 1, 28, 28)

X = T.ftensor4()
Y = T.fmatrix()

w = init_weights((32, 1, 3, 3))
w2 = init_weights((64, 32, 3, 3))
w3 = init_weights((128, 64, 3, 3))
w4 = init_weights((128 * 3 * 3, 625))
w_o = init_weights((625, 10))

noise_l1, noise_l2, noise_l3, noise_l4, noise_py_x = model(X, w, w2, w3, w4, 0.2, 0.5)
l1, l2, l3, l4, py_x = model(X, w, w2, w3, w4, 0., 0.)
y_x = T.argmax(py_x, axis=1)


cost = T.mean(T.nnet.categorical_crossentropy(noise_py_x, Y))
params = [w, w2, w3, w4, w_o]
updates = RMSprop(cost, params, lr=0.001)

train = theano.function(inputs=[X, Y], outputs=cost, updates=updates, allow_input_downcast=True)
predict = theano.function(inputs=[X], outputs=y_x, allow_input_downcast=True)
t0 = time.time()

for i in range(100):
    for start, end in zip(range(0, len(trX), 128), range(128, len(trX), 128)):
        cost = train(trX[start:end], trY[start:end])
#print np.mean(np.argmax(teY, axis=1) == predict(teX))
    print i, time.time() - t0, "seconds / reliability: ", np.mean(np.argmax(teY, axis=1) == predict(teX))
    t0 = time.time()

#time.sleep(60)

vrijdag 19 juni 2015

Hij kan tellen!

Niet laten hinderen door een instabiele videokaart. Toch maar even het voornemen om even slim te zijn als de kraaien uit te proberen. Ik meen toch zeker dat ik daarover heb geschreven maar ik kan nu het bericht zo snel niet terugvinden. Enfin, ze hebben ontdekt dat kraaien kunnen tellen.
(http://www.nu.nl/wetenschap/4064944/kraaien-hebben-vermogen-tellen.html)


Als machine learning enig respect wil houden zal het dat toch minsten moeten kunnen evenaren!
De handschoen opgepakt! Ook hier gaat het weer vooral om 'datamanipulatie'. Hoe maak je een dataset met veel afbeeldingen van 'graantjes'? Dat lijkt nu gelukt! Ongetwijfeld niet op de mooiste manier (in numpy / python moet je for-loopjes kunnen vermijden) maar toch: Tellen (tot 3) lijkt alvast te lukken:





Of met 6 graan varianten: (0 .. 5):



Hierbij weer de code:

import matplotlib.pyplot as plt
from sklearn import svm
import numpy as np

# Kraaien kunnen tellen. Dat blijkt uit een experiment http://www.nu.nl/wetenschap/4064944/kraaien-hebben-vermogen-tellen.html
# Toch eens kijken of dat een DL programma dat ook kan.

si = 1000
h = 28
b = 28
r = 4
ima = np.zeros((si, h * b))
ima.shape = si, h , b
grains = np.floor(np.random.rand(si) * 4)

for i in range(0,si):
    for j in range(0,int(grains[i])):
        ho = np.floor(np.random.rand() * (h-r))
        br = np.floor(np.random.rand() * (b-r))
        for x in range(int(ho),int(ho+r)):
            for y in range(int(br),int(br+r)):
                ima[i,x,y] = 1

clf = svm.SVC(gamma=0.0001, C=100)
ima.shape = si, h * b
x,y = ima, grains

clf.fit(x[:-10],y[:-10])

#print ('Prediction:', clf.predict(im[t]))

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

def fillim(c):
    im = ima[c]
    im.shape = h,b
    return im

fig = plt.figure(1, (10., 10.))
grid = ImageGrid(fig, 111, # similar to subplot(111)
                 nrows_ncols = (2, 5), # creates 2x2 grid of axes
                 axes_pad=0.5, # pad between axes in inch.
                 )

for c in range(10):
    grid[c].imshow(fillim((si - 10) + c),cmap=plt.cm.gray)
    title = 'Predict: ' +  str(clf.predict(ima[(si - 10) + c]))
    grid[c].set_title(title, weight='light', size='small', position=(0.5, 1.1),
         horizontalalignment='center', verticalalignment='center')


plt.show()

Nieuwe PSU

In dienst hadden we ook onze PSU (persoonlijke standaard uitrusting) maar nu gaat het toch echt om een 'power supply unit' oftewel een voedinkie. Hoewel er verschillende sites / forums zijn waar wordt aangegeven dat de geforce gtx980 goed met de standaard mac pro voeding te gebruiken zou moeten zijn geeft Apple 300watt in zijn specificaties beschikbaar en vraag dit krachtkaartje toch een minimum van 500watt. De 200 watt verschil zou heel best wel eens de reden kunnen zijn van de crash. Ik hoop het morgen te weten als ik mijn nieuwe 'PSU' binnen heb gekregen. Je moet toch wat als je een computer intelligent wil krijgen ...

woensdag 17 juni 2015

Crash ....

De feestvreugde is maar van korte duur. De MAC blijft crashen na verloop van tijd zodra ik hem met het convolutional network aan het werk zet. Het ergste is dat hij dan even niet meer lijkt op te starten. De schermen blijven zwart en dat is iets waar ik met de vorige kaart toch wat allergie voor heb gekregen. Gelukkig na de 3e harde reset fitsen de schermen weer aan. Even googelen ... en ja hoor. Bij de MacPro 3.1 (2008), de mijne, is er een probleem als de kaart in het laagste (eerste) slot zit.  Dat is natuur lijk te verhelpen! En nu weer duimen :-)


Helaas na ongeveer 20 leerloops houdt hij het toch weer voor gezien. Misschien moet ik hem gewoon tussen de loops even wat laten 'uitrusten'.

De catacomben


Behalve dat de mac pro na het opstarten aangeeft dat er opnieuw, wegens een fout, is opgestart lijkt de nieuwe kaart goed te werken. Het testprogramma voor Theano geeft echter nog aan dat de cpu en niet de gpu gebruikt wordt. Tijd dus om opnieuw de installatie instructie voor Theano door te nemen. Opnieuw Cuda geïnstalleerd en tevens naar de laatste versie bijgewerkt. Kijk dat scheelt alweer. Als ik nu met onderstaand commando het testprogramma opstart geeft hij aan dat de GPU gebruikt wordt. Ook behoorlijk wat sneller:
CPU: Looping 1000 times took 2.90439796448 seconds
GPU: Looping 1000 times took 0.767756938934 seconds
Dat helpt!
Het commando is:

  • THEANO_FLAGS='floatX=float32,device=gpu0,nvcc.fastmath=True'  python /Users/DWW/Documents/test_gpu.py

Start ik hier echter het convolutional network algoritme op vergelijkbare wijze mee op dan krijg ik de melding dat 'load' (het load.py programma om de mnist dataset te laden) niet gevonden kan worden. Blijkbaar heb ik het juiste pad (PATH) nog niet toegevoegd. (Daarnaast moet ik nu mijn eerdere aanpassing van T.ftensor4 naar T.dtensor4 weer terugdraaien. Blijkbaar iets met de Cuda installatie te maken?)

Om de $PATH parameter aan te passen kom ik in een exotische editor via


  • vi ~/.bash_profile
Het lukt mij uiteindelijk wel om daarmee aanpassingen te doen maar het programma blijft de fout geven. Ook bedenk ik mij dat het dan om een tijdelijke setting, per aangeboden programma, gaat. Uit de instructies blijkt dat ik de parameters 'floatX=float32 en device=gpu0' ergens in een .theanorc file moet aanpassen. Die file is echter nergens terug te vinden. Uiteindelijk vindt ik hoe dat dan zou moeten:
  • echo -e "\n[global]\nfloatX=float32\n" >> ~/.theanorc
Dit doet wel een beetje aan de oude DOS tijd denken maar zal voor Linux gebruikers gesneden koek zijn. Het werkt! Nadat er eerst wat voorwerk wordt gedaan (vermoedelijk wat c++ compilaties) loopt de leer-loop uit het convolutional network nu in gemiddeld 37,5 seconden! Bij het gebruik van de CPU was er voor hetzelfde loopje meer dan 50 minuten nodig! Kijk nu wordt het interessant. Dan kan ik ook met dit type deep learning netwerk wat gaan experimenten. De tocht door de catacomben van OSX (en de dure videokaart :-) begint nu vruchten af te werpen. Na ongeveer 30 loops zit de betrouwbaarheid al op 99,5%!!!

De computer crashed echter bij het typen van de voorgaande zin. Wat een ironie! De kaart moet nog wel een stapje stabieler worden.
Ik bedenk mij nu dat ik de 'vi' editor dan ook moet kunnen gebruiken voor de .theanorc file. Er blijkt een hoop troep in te staan van mijn eerdere experimenten met het echo commando. Gelukkig kan ik alles nu opschonen.  Er staat nu :

[global]
nfloatX=float32
device=gpu0


dinsdag 16 juni 2015

Nieuwe grafische kaart

Eindelijk weer de stap durven maken. Nadat de vorige GTX980 niet aan de praat te krijgen was nu opnieuw eentje besteld. Er blijken wel heel veel 'soorten en maten' gtx980 kaarten te zijn. Het vorige type was al niet meer bij Coolblue te koop. Dan maar een die erop lijkt. De Asus Strix. Deze kaart heeft een 6 en 8 prins pcie voedingskabel (de vorige 2x6) en dus ook maar bij BOL een verloopsnoertje besteld. De volgende dag is die alweer binnen.  De doos ziet er ook weer indrukwekkend uit. Er blijkt een passend verloop voedingskabeltje bij geleverd te zijn. (2x6 naar 1x8) Dus .. gelijk proberen en duimen. En ja ... na een iets te lange tijd ... hartkloppingen ... verschijnt het aanlogscherm. Eindelijk beeld! Nog maar op 1 scherm maar ja, dan moet je beide schermen ook aansluiten. Geen vga verbinding meer maar gelukkig kan mijn Philips monitor ook HDMI aan. De andere gaat op de DVI uitgang. Prachtig beeld! Sneller? Nu ook GPU voor 'deep learning'? We gaan het uitproberen!

  

zondag 7 juni 2015

Oefendatasets.

Het leukste is natuurlijk om deep learning uit te proberen met een 'eigen' dataset. Misschien leidt dat tot onverwachte inzichten. (En lukt het eindelijk om daarmee miljonair te worden :-)

Dat blijkt echter nog niet zo eenvoudig (eigen datasets - maar ook dat miljonair worden). Met name datasets geschikt maken om met de dl-algoritmen te laten werken lijkt een behoorlijke klus. In een van de tutorials (weet even niet meer welke) hadden ze daarvoor al gewaarschuwd. Om te oefenen is er echter meer dan voldoende beschikbaar:

Op de site mldata.org is een grote variatie aan datasets beschikbaar.


Ook zijn er 'taken', 'methodes' en 'uitdagingen' te vinden. Misschien een keer een prijsje winnen in de heeeel verre toekomst ? :-)

vrijdag 5 juni 2015

Alleen nullen, enen en tweeën (3)

Het is nu ook gelukt om alles goed (redelijk :-) weer te geven. Bijvoorbeeld:

Prediction for number with index: ( 0 ) =  [2] Known value =  2
Prediction for number with index: ( 1 ) =  [3] Known value =  3
Prediction for number with index: ( 2 ) =  [2] Known value =  2
Prediction for number with index: ( 3 ) =  [2] Known value =  2
Prediction for number with index: ( 4 ) =  [0] Known value =  0
Prediction for number with index: ( 5 ) =  [2] Known value =  2
Prediction for number with index: ( 6 ) =  [2] Known value =  2
Prediction for number with index: ( 7 ) =  [2] Known value =  2
Prediction for number with index: ( 8 ) =  [1] Known value =  1
Prediction for number with index: ( 9 ) =  [1] Known value =  1




Het leeralgoritme blijkt dus inderdaad goed te werken. Het geeft de juiste som van de afzonderlijke cijfers weer.
Het is nu natuurlijk ook eenvoudig om gewoon het getal weer te geven:

Prediction for number with index: ( 0 ) =  [20] Known value =  20
Prediction for number with index: ( 1 ) =  [12] Known value =  12
Prediction for number with index: ( 2 ) =  [2] Known value =  2
Prediction for number with index: ( 3 ) =  [11] Known value =  11
Prediction for number with index: ( 4 ) =  [0] Known value =  0
Prediction for number with index: ( 5 ) =  [2] Known value =  2
Prediction for number with index: ( 6 ) =  [11] Known value =  11
Prediction for number with index: ( 7 ) =  [2] Known value =  2
Prediction for number with index: ( 8 ) =  [1] Known value =  1

Prediction for number with index: ( 9 ) =  [10] Known value =  10



Wow! wat knap is ie toch :-)

Gebruikte code:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np
import time
from sklearn import svm
from load import mnist
trX, teX, trY, teY = mnist(onehot=True)

t0 = time.time()

ga = 0.028          # Hiermee (gamma = 0.028) wordt bij 10.000 oefeningen 97.07% betrouwbaarheid gehaald
size = 1000

clf = svm.SVC(gamma=ga, C=100)

# Eerst nullen, eenen en tweeen voor de oefendataset selecteren.
Y = np.argmax(trY,axis=1)
index=[]
elem = Y.size
for x in range(0,elem-1):
    if Y[x] in range(0,3):
        index += [x]
#print Y[x]
XX = np.take(trX, index, axis=0)
YY = np.take(Y,index)

# Nu nullen, eenen en tweeen voor de testdataset selecteren.
Y = np.argmax(teY,axis=1)
index=[]
elem, val = XX.shape
for x in range(0,size):
    if Y[x] in range(0,3):
        index += [x]

XXt = np.take(teX, index, axis=0)
YYt = np.take(Y,index)

#Nu samenstellen

XXX = np.concatenate((XX,np.flipud(XX)), axis = 1)
YYY = YY+np.flipud(YY)

XXXt = np.concatenate((XXt,np.flipud(XXt)), axis = 1)
YYYt = YYt+np.flipud(YYt)

clf.fit(XXX[0:size],YYY[0:size])

#clf.fit(XXX,YYY)     # Totale set 'leren'.

print ""
print "reliability: ", np.mean(YYYt == clf.predict(XXXt)), time.time() - t0, "seconds, gamma: ", ga, " size :", size
print ""

t = 0
i = 0
fig = plt.figure(1,(5.,5.))
grid = ImageGrid(fig,111,
                 nrows_ncols = (10,2),
                 axes_pad=0.1,
                 )
while (t < 19 and i < 100):
    if (YYYt[i] != clf.predict(XXXt[i])):
        print "Prediction for number with index: (",i, ") = ", clf.predict(XXXt[i]), "Known value = ",YYYt[i]
        im1 = XXXt[i,0:784]
        im2 = XXXt[i,784:2*784]
        im1.shape=28,28
        im2.shape=28,28
        grid[t].imshow(im1,cmap=plt.cm.gray_r)
        grid[t+1].imshow(im2,cmap=plt.cm.gray_r)
        #plt.imshow(im1, cmap=plt.cm.gray_r, interpolation="nearest")
        t += 2
    i += 1

plt.show()

donderdag 4 juni 2015

Alleen nullen, enen en tweeën (2)

Ok, de selectie van de nullen, enen en tweeën was dus uiteindelijk gelukt. Nu wil ik ze in 1 plaatje combineren. Alle waarden moeten dus bijvoorbeeld de vorm krijgen :


Afbeeldingen van 56 x 28. Het systeem zou dan moeten leren dat dit de uitkomst 2 + 1 = 3 heeft.

Het lijkt een aardige oefening, temeer daar in de tutorials verteld wordt dat het belangrijkste werk meestal is het bewerken van je invoer data. Hierdoor kan ik ook hierin wat oefenen en ervaring opbouwen.

Ook het samenvoegen zoals in bovenstaande afbeelding valt niet mee totdat je de juiste commando's hebt gevonden. Ik besluit de array met cijferafbeeldingen te combineren met zichzelf in omgekeerde volgorde. Uiteindelijk lukt dat met de volgende code:
XXX = np.concatenate((XX,np.flipud(XX)), axis = 1)

YYY = YY+np.flipud(YY) 
Het is zo eenvoudig als je eenmaal de juiste hebt gevonden :-). Ik blijf mij verbazen over de kracht van dit soort array of matrix-bewerkingen in Python / Numpy. Btw de 'ud' staat voor up-down.
Hetzelfde moet ik dan doen voor de testdata. Nu nog kijken of hij 't doet. En ook hoe ik ze juist af kan beelden. 
Na 1279 seconden geeft hij een betrouwbaarheid van 97,8%. Toch niet slecht lijkt mij. Alleen krijg ik nog een foutmelding bij het weergeven van de afbeeldingen.

dinsdag 2 juni 2015

Alleen nullen, enen en tweeën (1)

Ik wil eens kijken of er met een andere input ook leuke resultaten te behalen zijn. Maar waar haal je een interessante dataset vandaan? De sklearn biedt verschillende oefendatasets. Ik wil echter nog even bij de mnist dataset blijven. (De 60.000 geschreven getallen set). Ik wil alleen de werking wat op zijn kop gooien. Wat als deze nou 2 cijfers tegelijk leest en daar een uitkomst bij bepaald?

Uit de dataset neem ik alleen 0,1 en 2. Ik combineer deze en de uitkomst is bijvoorbeeld hun som. 
Dus de uitdaging is om dit te leren:
  • 00 = 0
  • 01 = 1
  • 02 = 2
  • 10 = 1
  • 11 = 2
  • 12 = 3
  • 20 = 2
  • 21 = 3
  • 22 = 4
Oke, maar hoe selecteer je alleen al deze getallen? In de mnist dataset zijn het gescheiden numpy arrays. (data: trX en targets: trY). De selectie kan alleen op trY. Er moet een makkelijke manier zijn om dat op te lossen. Ik probeer ze eerst samen te voegen met het 'zip' commando. Dan is selectie heel goed mogelijk. Het lukt mij alleen niet om ze weer netjes in een 'data' en 'target' array op te splitsen. Hij blijft fouten geven op de array-vorm. Dezelfde soort fout ontstaat als ik ze beide in een for-loop opnieuw probeer op te bouwen. Met de targets-set zit ik waarschijnlijk goed maar de data-set (trX) is 2 dimensionaal (60.000x784) maar blijkbaar niet meer na deze bewerking. Ergo: nog te weinig verstand van numpy.array bewerkingen. 

Na veel experimenteren vind ik een redelijk elegante oplossing. De 'numpy take functie'. Na eerst een array van alle indexes van trY te bouwen waar een 0, 1 of 2 staat (Even 'index' genoemd - waarom ook niet? :-)  kan ik eenvoudig de volgende selectie maken:

XX = np.take(trX, index, axis=0)    

Wel moet ik hierbij dus voor trX de axis aangeven. 
Even laten leren ... en ... 100% betrouwbaarheid! Als het alleen op deze waarden (0,1 en 2) uitkomt weet het algoritme foutloos te scoren! 

Een andere keer verder om bovenstaande te combineren. Voorlopig ben ik al bij dat dit gelukt is! 

import matplotlib.pyplot as plt
import numpy as np
import time
from sklearn import svm
from load import mnist
trX, teX, trY, teY = mnist(onehot=True)

t0 = time.time()

ga = 0.028          # Hiermee (gamma = 0.028) wordt bij 10.000 oefeningen 97.07% betrouwbaarheid gehaald
size = 10000

clf = svm.SVC(gamma=ga, C=100)

# Eerst nullen, eenen en tweeen voor de oefendataset selecteren.
Y = np.argmax(trY,axis=1)
index=[]
for x in range(0,size):
    if Y[x] in range(0,3):
        index += [x]
#print Y[x]
XX = np.take(trX, index, axis=0)
YY = np.take(Y,index)

# Nu nullen, eenen en tweeen voor de testdataset selecteren.
Y = np.argmax(teY,axis=1)
index=[]
for x in range(0,size):
    if Y[x] in range(0,3):
        index += [x]
#print Y[x]
XXt = np.take(teX, index, axis=0)
YYt = np.take(Y,index)

clf.fit(XX,YY)

print ""
print "reliability: ", np.mean(YY == clf.predict(XX)), time.time() - t0, "seconds, gamma: ", ga, " size :", size
print ""

t = 0
i = 0
while (t < 10 and i < 100):
    if (YYt[i] != clf.predict(XXt[i])):
        t += 1
        print "Prediction:", clf.predict(XX[i]), YY[i], "i = " , i
        im=XX[i]
        im.shape=28,28
        plt.imshow(im, cmap=plt.cm.gray_r, interpolation="nearest")
        plt.show()
    i += 1