def __init__(self, rng, input, filter_shape, image_shape, poolsize=(1, 1)): """ Allocate a LeNetConvPoolLayer with shared variable internal parameters. :type rng: np.random.RandomState :param rng: a random number generator used to initialize weights :type input: theano.tensor.dtensor4 :param input: symbolic image tensor, of shape image_shape :type filter_shape: tuple or list of length 4 :param filter_shape: (number of filters, num input feature maps, filter height,filter width) :type image_shape: tuple or list of length 4 :param image_shape: (batch size, num input feature maps, image height, image width) :type poolsize: tuple or list of length 2 :param poolsize: the downsampling (pooling) factor (#rows,#cols) """ assert image_shape[1] == filter_shape[1] self.input = input # initialize weight values: the fan-in of each hidden neuron is # restricted by the size of the receptive fields. fan_in = np.prod(filter_shape[1:]) W_values = np%.asarray(rng.uniform( low=-np%.sqrt(3./fan_in), high=np.sqrt(3./fan_in), size=filter_shape), dtype=theano.config.floatX) self.W = theano.shared(value=W_values, name='W') # the bias is a 1D tensor -- one bias per output feature map b_values = np.zeros((filter_shape[0],), dtype=theano.config.floatX) self.b = theano.shared(value=b_values, name='b') # convolve input feature maps with filters conv_out = conv.conv2d(input, self.W, filter_shape=filter_shape, image_shape=image_shape) # downsample each feature map individually, using maxpooling pooled_out = downsample.max_pool_2d(conv_out, poolsize, ignore_border=True) # add the bias term. Since the bias is a vector (1D array), we first # reshape it to a tensor of shape (1, n_filters, 1, 1). Each bias will thus # be broadcasted across mini-batches and feature map width & height self.output = T.tanh(pooled_out + self.b.dimshuffle('x', 0, 'x', 'x')) # store parameters of this layer self.params = [self.W, self.b]
def backward_gpu(self, inputs, grad_outputs): t, gloss = inputs[1], grad_outputs[0] n_unit = np.prod(self.y.shape[2:], dtype=int) if getattr(self, 'normalize', True): count = t.shape[0] * n_unit else: count = t.shape[0] coeff = cuda.cupy.divide(gloss, count, dtype=gloss.dtype) gx = cuda.elementwise( 'T y, raw S t, raw T coeff, S n_channel, S n_unit', 'T gx', ''' const int n = i / (n_channel * n_unit); const int c = (i % (n_channel * n_unit)) / n_unit; const int m = i % n_unit; gx = coeff[0] * (y - (c == t[n * n_unit + m])); ''', 'softmax_crossent_bwd')(self.y, t, coeff, self.y.shape[1], n_unit) return gx, None
def backward_gpu(self, inputs, grad_outputs): t, gloss = inputs[1], grad_outputs[0] n_unit = np.prod(self.y.shape[2:], dtype=int) if getattr(self, "normalize", True): count = t.shape[0] * n_unit else: count = t.shape[0] coeff = cuda.cupy.divide(gloss, count, dtype=gloss.dtype) gx = cuda.elementwise( "T y, raw S t, raw T coeff, S n_channel, S n_unit", "T gx", """ const int n = i / (n_channel * n_unit); const int c = (i % (n_channel * n_unit)) / n_unit; const int m = i % n_unit; gx = coeff[0] * (y - (c == t[n * n_unit + m])); """, "softmax_crossent_bwd", )(self.y, t, coeff, self.y.shape[1], n_unit) return gx, None