zondag 9 augustus 2015

Bingo!

Gelukkig, ook het neurale netwerk werkt nu met de Titanic data! Het probleem bleek een te trage leercurve te zijn. Zodra ik de 'leer quotient' die aangeeft welk aandeel van de gradient moet worden genomen om de 'weights' aan te passen ophoog van 0.01 in de richting van bijvoorbeeld 0.3, begint de bereikte betrouwbaarheid omhoog te gaan. Afhankelijk van enkele andere parameters tot wel 82%.


Als ik de standaard stogastic gradient funktie (sgd) vervang door de RMSprop (uit het 'modern net' - zie eerdere berichten) functie lijkt e.e.a. nog beter te gaan. (tot boven de 84%) Wel blijft het resultaat vrij sterk afhankelijk van de voorsortering (shuffling) van de gegevens. Waarschijnlijk is de dataset te klein (750 voorbeelden en 141 testwaardes) om dit te voorkomen.

Ik heb de hidden laag in grootte aangepast tussen 0.5 * Col (0.5 * 8 inputkolommen = 4) en 10 * Col. Het effect blijft slecht zichtbaar. Rond 8 hidden neurons lijkt een soort optimum. De initiƫle random invulling van de netwerk 'weights' geeft zo-ie-zo variatie in de uitkomsten.

Hieronder de gebruikte code. Ik heb de voorbewerkingen van de data (klasse variabelen met per waarde een kolom en standaardiseren van numerieke waarden tussen 0 en 1) in een apart programma gezet.


'''
    File format
    0    sequence number To compare with original data
    1    age             Age (between 0 and 1)
    2    sibsp           Number of Siblings/Spouses Aboard (between 0 and 1)
    3    parch           Number of Parents/Children Aboard (between 0 and 1)
    4    survival        (0 = No; 1 = Yes)
    5    no survival     (0 = No; 1 = Yes)
    6    pclass1         Passenger Class (0 = No; 1 = Yes)
    7    pclass2         Passenger Class (0 = No; 1 = Yes)
    8    pclass3         Passenger Class (0 = No; 1 = Yes)
    9    sexFemale       Sex (0 = No; 1 = Yes)
   10    sexMale         Sex (0 = No; 1 = Yes)
'''
import csv
import numpy as np
from sklearn.utils import shuffle

# File inlezen
file = '/Users/DWW/Downloads/train_out.csv'
with open(file,'rb') as f:
    reader = csv.reader(f)
    Data = list(reader)

x_cols = [1,2,3,6,7,8,9,10]             # De kolommen met relevante invoer waarden
y_cols = [4,5]                          # De uitkomst kolommen (survival / no survival)

DataN = np.array(Data,dtype=np.float)   # Volledig overzetten van Python naar Numpy
Rec, Col = DataN.shape

XX = DataN[:,x_cols]                     # Alle waarden
YY = DataN[:,y_cols]                     # Alle uitkomsten

XX, YY = shuffle(XX,YY , random_state=1) #, random_state=1

Size = 750
x,y   = XX[:Size], YY[:Size]        # Oefendeel
xt,yt = XX[Size:], YY[Size:]        # Testdeel

Rec, Col = x.shape
print x.shape, xt.shape
#-----------------------------------------------

import theano
from theano import tensor as T
import numpy as np

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 RMSprop(cost, params, lr=0.01, 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_h, w_o):
    h = T.nnet.sigmoid(T.dot(X, w_h))
    pyx = T.nnet.softmax(T.dot(h, w_o))
    return pyx


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

w_h = init_weights((Col, Col * .2 ))
w_o = init_weights((Col * .2, 2))

py_x = model(X, w_h, w_o)
y_x = T.argmax(py_x, axis=1)

cost = T.mean(T.nnet.categorical_crossentropy(py_x, Y))
params = [w_h, w_o]
updates = RMSprop(cost, params)

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)

for i in range(10000):
    cost = train(x,y)

print 'Reliability: ', np.mean(np.argmax(yt, axis=1) == predict(xt))

# Print enkele voorbeelden
for i in range(10):

    print '>>',np.argmax(yt[i]) , predict(xt[i:i+1])

Geen opmerkingen:

Een reactie posten