![]() |
Gelukt om met matplotlib de grafiek na te bootsen! |
Om het principe uit te leggen van 'learning models' wordt gestart met een eenvoudig model namelijk 'Lineaire regressie'. Door een 'wolk' van waarnemingen wordt een zo optimaal mogelijke lijn getrokken die de relatie tussen 2 variabelen weergeeft.
De code is eerst totaal 'abracadabra' voor mij. Stapje voor stapje wordt alles duidelijker en weet ik er zelfs de grafische weergave bij te ontwikkelen. (Helaas wordt die in de cursus er niet bij verstrekt)
Python is in principe een interpreter taal. D.w.z. dat ze lijn voor lijn wordt gecompileerd en uitgevoerd. In onderstaand programma wordt eerst een denkbeeldige dataset van puntenparen (TrX, TrY) gemaakt. Hierbij geeft trX 100 getallen tussen -1 en 1. TrY is ongeveer 2 x TrX met een random variatie. Het model moet dus de waarde 2 gaan terugvinden.
In de code gebeurd dan iets waar ik even op moest 'kauwen': Er worden definities (expressies) neergezet die niet op dat moment uitgevoerd worden maar die (elkaar) later oproepen. Zo rekent de regel cost = T.mean(T.sqr(y-Y)) op dat moment nog niets. Dat gebeurd blijkbaar pas als op het eind in de 'for-loop' de train-funktie wordt aangeroepen met daarin de verwijzing naar 'output=cost'. Het lijkt een soort eenregelige functie-definititie.
Ook de dubbele rechte haken bij 'updates' is even verwarrend. Deze lijst-weergave wordt blijkbaar gebruikt om te vertellen hoe 'w' aangepast moet worden bij de aanroep. Waarom dit zo gaat is mij echter nog niet duidelijk.
Het maakt het echter wel mogelijk om eerst, haast abstract, het model met de relevante factoren neer te zetten om het daarna te gaan gebruiken.
De opzet is hierbij gestandaardiseerd voor ook meer complexe modellen die later gebruikt worden.
Eerst de model definitie met de letter 'w' voor weight; de 'leer-variabele'. Door 'w' te definieren als theano.shared is deze ook buiten de functie te gebruiken. Dan de 'Cost' functie te bepalen welke de afwijking weergeeft tussen het berekende en het werkelijke resultaat. Via 'updates' en 'gradient' wordt in dit model vervolgens de 'verbeterrichting' bepaald.
'train' is de Theano functie waarmee alles aan elkaar wordt gekoppeld en het model getraind wordt.
(allow_input_dowcast heeft, meen ik, iets te maken met omzetten van 32 naar 64 bit variabelen)
de 'train-functie' wordt aangeroepen in de dubbele loop (100 x het aantal trX,trY paren). w.getvalue() geeft tenslotte de gevonden uitkomst (ongeveer 2)
import theano
from theano import tensor as T
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
trX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.33
fig, ax = plt.subplots()
X = T.scalar()
Y = T.scalar()
def model(X, w):
return X * w
w = theano.shared(np.asarray(0., dtype=theano.config.floatX))
y = model(X, w)
cost = T.mean(T.sqr(y - Y))
gradient = T.grad(cost=cost, wrt=w)
updates = [[w, w - gradient * 0.01]]
train = theano.function(inputs=[X, Y], outputs=cost, updates=updates, allow_input_downcast=True)
# create pyplot graphfig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([-1.5,1.5,-3,3])
plt.ion()
plt.scatter(trX, trY)
plt.show()
# iterate through the data 100 times and train the model on
# each example of input and output pairs
for i in range(100):
for x, y in zip(trX, trY):
c = train(x, y)
# print to plot
if ax.lines: del ax.lines[0]
ax.plot(trX, trX * w.get_value(), "-", linewidth=2, color='red')
plt.title('slope is currently {0:4.2f}, cost is currently {1:6.4f}'.format(float(w.get_value()),float(c)))
plt.draw()
time.sleep(0.5/(float(i)+1))
print 'plotting for {0:0d}/100'.format(i)
raw_input()
Geen opmerkingen:
Een reactie posten