maandag 25 mei 2015

Vijde deel in "Deep Learning met Python" cursus: Convolutional network

Eindelijk zijn we dan bij de 'heilige graal' aangekomen. Het convolutional network. Een netwerk architectuur die onze betrouwbaarheid naar het niveau van 99.5% moet gaan tillen. Het ontwerp gaat ervan uit dat er meer gekeken wordt naar eigenschappen (features) van de geschreven getallen dan naar de getallen als geheel. Een logische gedachte als je bedenkt dat bijvoorbeeld exact dezelfde 4 op verschillende plaatsen en met verschillende schalen en / of rotaties opgeschreven kan zijn.

Er wordt uitgegaan van kleine matrixes van 3x3 om de basiskenmerken vast te leggen van delen van de afbeeldingen. Deze werken als een soort mini-lensjes. Daarna worden die via 'downsampling' overgezet naar een 2x zo grote, volgende verborgen laag. (Ik doe nu net even of ik het snap :-)

... beschrijving code wordt vervolgd ....  

Ook deze code blijkt bij mij in eerste instantie niet te werken. Na diep spitten door alle foutmeldingen blijkt mijn installatie niet het type T.ftensor4() te kennen. Gelukkig ontdek ik dat T.dtensor4() een alias is voor hetzelfde datatype.

Nu blijkt wel heel sterk de behoefte aan rekenkracht. Een enkele leer-loop duurt meer dan 50 minuten. En ik heb er 100 te gaan! Daar kan ik niet op wachten. Gelukkig zijn de eerste betrouwbaarheids-resultaten veel belovend. Na een nachtje doorrekenen zit het al een heel eind richting de beloofde 99.5% Uit een test programmaatje blijkt dat ik dus geen gebruik maak van de GPU, de grafische processor. Tja, dat maakt experimenteren met convolutional netwerken wel erg lastig. Helaas heb ik mijn nieuwe kaart nog steeds niet aan de praat kunnen krijgen.


import theano
from theano import tensor as T
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
import numpy as np
from load import mnist
from theano.tensor.nnet.conv import conv2d
from theano.tensor.signal.downsample import max_pool_2d
import time
srng = RandomStreams()

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, teX, trY, teY = mnist(onehot=True)

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

X = T.dtensor4()    # Aangepast!!! was 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 time.time() - t0, "seconds"
    t0 = time.time()

Geen opmerkingen:

Een reactie posten