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)

Geen opmerkingen:

Een reactie posten