""" This code is adapted from the tutorial introducing denoising auto-encoders (dA) using Theano. """ import numpy import theano import theano.tensor as T from theano.tensor.shared_randomstreams import RandomStreams class dA(object): """Denoising autoencoder""" def __init__(self, numpy_rng, theano_rng, numvis, numhid, vistype, corruption): self.numvis = numvis self.numhid = numhid self.corruption = corruption self.vistype = vistype self.theano_rng = theano_rng self.W_init = numpy.asarray( numpy_rng.uniform( low = -4*numpy.sqrt(6./(numhid+numvis)), high = 4*numpy.sqrt(6./(numhid+numvis)), size = (numvis, numhid)), dtype = theano.config.floatX) self.W = theano.shared(value = self.W_init, name ='W') self.bvis = theano.shared(value=numpy.zeros(numvis, dtype=theano.config.floatX), name='bvis') self.bhid = theano.shared(value=numpy.zeros(numhid, dtype=theano.config.floatX), name ='bhid') self.inputs = T.matrix(name = 'inputs') self.params = [self.W, self.bhid, self.bvis] self._corruptedinputs = self.theano_rng.binomial(size = self.inputs.shape, n=1, p=1-self.corruption, dtype=theano.config.floatX) * self.inputs #self._corruptedinputs = self.theano_rng.normal(size=self.inputs.shape, avg=0.0, std=corruption, dtype=theano.config.floatX)+self.inputs self._hiddens = T.nnet.sigmoid(T.dot(self._corruptedinputs, self.W) + self.bhid) if self.vistype == 'binary': self._outputs = T.nnet.sigmoid(T.dot(self._hiddens, self.W.T) + self.bvis) elif self.vistype == 'real': self._outputs = T.dot(self._hiddens, self.W.T) + self.bvis ##### if self.vistype == 'binary': L = - T.sum(self.inputs*T.log(self._outputs) + (1-self.inputs)*T.log(1-self._outputs), axis=1) elif self.vistype == 'real': L = T.sum(0.5 * ((self.inputs - self._outputs)**2), axis=1) self._cost = T.mean(L) self._grads = T.grad(self._cost, self.params) self.cost = theano.function([self.inputs], self._cost) self.grad = theano.function([self.inputs], T.grad(self._cost, self.params)) self.hiddens = theano.function([self.inputs], self._hiddens) def updateparams(self, newparams): def inplaceupdate(x, new): x[...] = new return x paramscounter = 0 for p in self.params: pshape = p.get_value().shape pnum = numpy.prod(pshape) p.set_value(inplaceupdate(p.get_value(borrow=True), newparams[paramscounter:paramscounter+pnum].reshape(*pshape)), borrow=True) paramscounter += pnum def get_params(self): return numpy.concatenate([p.get_value().flatten() for p in self.params]) def save(self, filename): numpy.save(filename, self.get_params()) def load(self, filename): self.updateparams(numpy.load(filename))