# HG changeset patch # User Joseph Turian # Date 1215575997 14400 # Node ID 269d5c5a4209a5cab1a1df5940e809b87fa742bd # Parent 8796b91a9f09da52158dbbfd1308e0f245e4e5a5 Cleaned up, added sparse_instance diff -r 8796b91a9f09 -r 269d5c5a4209 sandbox/rbm/README.txt --- a/sandbox/rbm/README.txt Tue Jul 08 21:42:21 2008 -0400 +++ b/sandbox/rbm/README.txt Tue Jul 08 23:59:57 2008 -0400 @@ -1,1 +1,4 @@ +An RBM with binomial units trained with CD-1. +by Joseph Turian + This seems to work fine. diff -r 8796b91a9f09 -r 269d5c5a4209 sandbox/rbm/globals.py --- a/sandbox/rbm/globals.py Tue Jul 08 21:42:21 2008 -0400 +++ b/sandbox/rbm/globals.py Tue Jul 08 23:59:57 2008 -0400 @@ -4,7 +4,7 @@ INPUT_DIMENSION = 1000 #INPUT_DIMENSION = 100 -HIDDEN_DIMENSION = 100 +HIDDEN_DIMENSION = 10 #HIDDEN_DIMENSION = 20 #HIDDEN_DIMENSION = 6 LEARNING_RATE = 0.1 diff -r 8796b91a9f09 -r 269d5c5a4209 sandbox/rbm/main.py --- a/sandbox/rbm/main.py Tue Jul 08 21:42:21 2008 -0400 +++ b/sandbox/rbm/main.py Tue Jul 08 23:59:57 2008 -0400 @@ -1,6 +1,7 @@ #!/usr/bin/python """ - An RBM with binomial units trained with CD-1. +Simple SGD RBM training. +(An example of how to use the model.) """ @@ -22,4 +23,4 @@ instance = nonzero_instances[i % len(nonzero_instances)] # SGD update over instance - model.update(instance) + model.update([instance]) diff -r 8796b91a9f09 -r 269d5c5a4209 sandbox/rbm/model.py --- a/sandbox/rbm/model.py Tue Jul 08 21:42:21 2008 -0400 +++ b/sandbox/rbm/model.py Tue Jul 08 23:59:57 2008 -0400 @@ -14,13 +14,21 @@ random.seed(globals.SEED) import pylearn.nnet_ops +import pylearn.sparse_instance def sigmoid(v): + """ + @todo: Move to pylearn.more_numpy + @todo: Fix to avoid floating point overflow. + """ # if x < -30.0: return 0.0 # if x > 30.0: return 1.0 return 1.0 / (1.0 + numpy.exp(-v)) def sample(v): + """ + @todo: Move to pylearn.more_numpy + """ assert len(v.shape) == 2 x = numpy.zeros(v.shape) for j in range(v.shape[0]): @@ -35,14 +43,28 @@ Compute the crossentropy of binary output wrt binary target. @note: We do not sum, crossentropy is computed by component. @todo: Rewrite as a scalar, and then broadcast to tensor. + @todo: Move to pylearn.more_numpy + @todo: Fix to avoid floating point overflow. """ return -(target * numpy.log(output) + (1 - target) * numpy.log(1 - output)) class Model: + """ + @todo: input dimensions should be stored here! not as a global. + """ def __init__(self): self.parameters = parameters.Parameters(randomly_initialize=True) + def sample(self, instances, iterations=1): + v = pylearn.sparse_instance.to_vector(instances, globals.INPUT_DIMENSION) + for i in range(iterations): + q = sigmoid(self.parameters.b + dot(v, self.parameters.w)) + h = sample(q) + p = sigmoid(self.parameters.c + dot(h, self.parameters.w.T)) + v = sample(p) + return v + def update(self, instances): """ Update the L{Model} using one training instance. @@ -50,12 +72,8 @@ @todo: Should assert that nonzero_indices and zero_indices are correct (i.e. are truly nonzero/zero). """ - v0 = numpy.zeros((len(instances), globals.INPUT_DIMENSION)) minibatch = len(instances) - for i in range(minibatch): - for idx in instances[i].keys(): - v0[i][idx] = instances[i][idx] - + v0 = pylearn.sparse_instance.to_vector(instances, globals.INPUT_DIMENSION) q0 = sigmoid(self.parameters.b + dot(v0, self.parameters.w)) h0 = sample(q0) p0 = sigmoid(self.parameters.c + dot(h0, self.parameters.w.T)) diff -r 8796b91a9f09 -r 269d5c5a4209 sparse_instance.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sparse_instance.py Tue Jul 08 23:59:57 2008 -0400 @@ -0,0 +1,22 @@ +""" +Sparse instances. +Each instance is represented as dict with key dimension. +Dimensions not present in the dict have value 0. +""" + +from numpy import zeros + +def to_vector(instances, dimensions): + """ + Convert sparse instances to vectors. + @type instances: list of sparse instances + @param dimensions: The number of dimensions in each instance. + @rtype: numpy matrix (instances x dimensions) + """ + assert isinstance(instances, list) + v = zeros((len(instances), dimensions)) + l = len(instances) + for i in range(l): + for idx in instances[i].keys(): + v[i][idx] = instances[i][idx] + return v