Regresión logística – Theano

Aquí os dejo con un ejemplo (regresion_logistica.py) muy sencillo y claro para realizar una regresión logística.

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

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 model(X, w):
    return T.nnet.softmax(T.dot(X, w))

trX, teX, trY, teY = mnist(onehot=True)

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

w = init_weights((784, 10))

py_x = model(X, w)
y_pred = T.argmax(py_x, axis=1)

cost = T.mean(T.nnet.categorical_crossentropy(py_x, Y))
gradient = T.grad(cost=cost, wrt=w)
update = [[w, w - gradient * 0.05]]

train = theano.function(inputs=[X, Y], outputs=cost, updates=update,
                        allow_input_downcast=True)
predict = theano.function(inputs=[X], outputs=y_pred,
                          allow_input_downcast=True)

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(i, np.mean(np.argmax(teY, axis=1) == predict(teX)))

Para poder ejecutar este ejemplo, necesitas preprocesar la base de datos MNIST. Para ello, crea un archivo Load.py (sitúa dicho archivo en la misma carpeta que regresion_logistica.py) con el siguiente código:

import numpy as np
import os

data_dir = os.getcwd() + '/MNIST/'

def one_hot(x,n):
	if type(x) == list:
		x = np.array(x)
	x = x.flatten()
	o_h = np.zeros((len(x),n))
	o_h[np.arange(len(x)),x] = 1
	return o_h

def mnist(ntrain=60000,ntest=10000,onehot=True):
	fd = open(os.path.join(data_dir,'train-images.idx3-ubyte'))
	loaded = np.fromfile(file=fd,dtype=np.uint8)
	trX = loaded[16:].reshape((60000,28*28)).astype(float)

	fd = open(os.path.join(data_dir,'train-labels.idx1-ubyte'))
	loaded = np.fromfile(file=fd,dtype=np.uint8)
	trY = loaded[8:].reshape((60000))

	fd = open(os.path.join(data_dir,'t10k-images.idx3-ubyte'))
	loaded = np.fromfile(file=fd,dtype=np.uint8)
	teX = loaded[16:].reshape((10000,28*28)).astype(float)

	fd = open(os.path.join(data_dir,'t10k-labels.idx1-ubyte'))
	loaded = np.fromfile(file=fd,dtype=np.uint8)
	teY = loaded[8:].reshape((10000))

	trX = trX/255.
	teX = teX/255.

	trX = trX[:ntrain]
	trY = trY[:ntrain]

	teX = teX[:ntest]
	teY = teY[:ntest]

	if onehot:
		trY = one_hot(trY, 10)
		teY = one_hot(teY, 10)
	else:
		trY = np.asarray(trY)
		teY = np.asarray(teY)

	return trX,teX,trY,teY

En el mismo directorio donde coinciden tu archivo regresion_logistica.py de regresión logística y el archivo Load.py, crea un directorio con el nombre MNIST e introduce en él los siguientes cuatro archivos: 1, 2, 3, 4.

Por último, para ejecutar el código simplemente ejecuta: python3 regresion_logistica.py.