def __init__(self, rng, input, filter_shape, poolsize=(2, 2), name='layer1'): self.input = input self.W = theano.shared(numpy.asarray(rng.uniform(low=-0.5, high=0.5, size=filter_shape), dtype=theano.config.floatX), name=name + 'W') self.b = theano.shared(value=numpy.zeros((filter_shape[3], ), dtype=theano.config.floatX), name=name + 'b') self.transformer = Conv2D(self.W) conv_out = self.transformer.lmul(self.input) pooled_out = max_pool_c01b(c01b=conv_out, pool_shape=poolsize, pool_stride=poolsize) features = (pooled_out + self.b.dimshuffle(0, 'x', 'x', 'x')) self.output = T.tanh(features) # store parameters of this layer self.params = [self.W, self.b]
def set_input_space(self, space): """ Note: this resets parameters! """ setup_detector_layer_c01tb(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > detector_shape[idx]: if self.fix_pool_shape: assert detector_shape[idx] > 0 self.pool_shape[idx] = detector_shape[idx] else: raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1]) assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.pool_stride[0] > self.pool_shape[0]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_shape[0] assert isinstance(ps, py_integer_types) self.pool_stride = [ps, ps] else: raise ValueError("Stride too big.") assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) dummy_detector = sharedX(self.detector_space.get_origin_batch(2)[0:16,:,:,0,:]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) dummy_p = dummy_p.eval() if self.detector_space.sequence_length % (self.sequence_pool_shape) != 0: raise ValueError("The case where detector layer's sequence length doesn't divide sequene pool shape is not implmented") output_sequence_length = self.detector_space.sequence_length / self.sequence_pool_shape self.output_space = Conv3DSpace(shape=[dummy_p.shape[1], dummy_p.shape[2]], sequence_length = int(output_sequence_length), num_channels = self.num_channels, axes = ('c', 0, 1, 't', 'b') ) print "Output space shape: {}, sequence length: {}".format(self.output_space.shape, self.output_space.sequence_length)
def set_input_space(self, space): """ Note: this resets parameters! """ setup_detector_layer_c01b(layer=self, input_space=space, rng=self.mlp.rng) rng = self.mlp.rng detector_shape = self.detector_space.shape def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > detector_shape[idx]: if self.fix_pool_shape: assert detector_shape[idx] > 0 self.pool_shape[idx] = detector_shape[idx] else: raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1]) assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.pool_stride[0] > self.pool_shape[0]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_shape[0] assert isinstance(ps, py_integer_types) self.pool_stride = [ps, ps] else: raise ValueError("Stride too big.") assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) dummy_detector = sharedX(self.detector_space.get_origin_batch(2)[0:16, :, :, :]) dummy_p = max_pool_c01b( c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape, ) dummy_p = dummy_p.eval() self.output_space = Conv2DSpace( shape=[dummy_p.shape[1], dummy_p.shape[2]], num_channels=self.num_channels, axes=("c", 0, 1, "b") ) print "Output space: ", self.output_space.shape
def fprop(self, state_below): self.input_space.validate(state_below) return max_pool_c01b(c01b=state_below, pool_shape=self.pool_shape, pool_stride=self.pool_stride)
def fprop(self, state_below): check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # fft 3d covolution z = self.transformer.lmul(state_below) # bias addition if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x', 'x') else: b = self.b.dimshuffle('x', 0, 1, 2, 3) z = z + self.b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) #assert self.detector_space.num_channels % 16 == 0 #ReLUs z = T.maximum(z, 0) if self.output_space.num_channels % 16 != 0: raise NotImplementedError( "num channles should always be dvisible by 16") # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property # Pooling # permute axes ['b', 0, 1,'t','c'] -> ['c', 0, 1, 't', 'b'] (axes required for pooling ) z = z.dimshuffle(4, 1, 2, 3, 0) # spatial pooling x/y z_shape = z.shape z = z.reshape( (z_shape[0], z_shape[1], z_shape[2], z_shape[3] * z_shape[4])) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride) p_shape = p.shape p = p.reshape( (p_shape[0], p_shape[1], p_shape[2], z_shape[3], z_shape[4])) # temporal pooling with overlap (t) p_shape = p.shape #['c', 0, 1, 't', 'b'] -> ['c',0*1,'t','b'] ('c',0, 1,'b') for max_pool_c01b p = p.reshape( (p_shape[0], p_shape[1] * p_shape[2], p_shape[3], p_shape[4])) t = temporal_max_pool_c01b(c01b=p, pool_shape=self.pool_temporal_shape, pool_stride=self.pool_temporal_stride, image_shape=self.temp_pool_input_shape) t_shape = t.shape t = t.reshape( (t_shape[0], p_shape[1], p_shape[2], t_shape[2], t_shape[3])) # Permute back axes ['c', 0, 1, 't', 'b'] -> ['b', 0, 1, 't', 'c'] t = t.dimshuffle(4, 1, 2, 3, 0) self.output_space.validate(t) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: t = self.output_normalization(t) return t
def fprop(self, state_below): check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # fft 3d covolution z = self.transformer.lmul(state_below) # bias addition if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x', 'x') else: b = self.b.dimshuffle('x', 0, 1, 2, 3) z = z + self.b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) #assert self.detector_space.num_channels % 16 == 0 #ReLUs z = T.maximum(z, 0) if self.output_space.num_channels % 16 != 0: raise NotImplementedError("num channles should always be dvisible by 16") # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property # Pooling # permute axes ['b', 0, 1,'t','c'] -> ['c', 0, 1, 't', 'b'] (axes required for pooling ) z = z.dimshuffle(4, 1, 2, 3, 0) # spatial pooling x/y z_shape = z.shape z = z.reshape((z_shape[0], z_shape[1], z_shape[2], z_shape[3] * z_shape[4])) p = max_pool_c01b(c01b = z, pool_shape = self.pool_shape[0:2], pool_stride = self.pool_stride[0:2]) p = p.reshape((p.shape[0], p.shape[1], p.shape[2], z_shape[3], z_shape[4])) # temporal pooling with overlap (t) p_shape = p.shape #['c', 0, 1, 't', 'b'] -> ['c',0*1,'t','b'] ('c',0, 1,'b') for max_pool_c01b p = p.reshape((p_shape[0], p_shape[1] * p_shape[2], p_shape[3] , p_shape[4])) t = temporal_max_pool_c01b(c01b = p, pool_shape = [1, self.pool_shape[2]], pool_stride = [1, self.pool_stride[2]], image_shape = self.temp_pool_input_shape) t_shape = t.shape t = t.reshape((t_shape[0], p_shape[1] , p_shape[2], t_shape[2] , t_shape[3])) # Permute back axes ['c', 0, 1, 't', 'b'] -> ['b', 0, 1, 't', 'c'] t = t.dimshuffle(4, 1, 2, 3, 0) self.output_space.validate(t) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: t = self.output_normalization(t) return t
def set_input_space(self, space): """ Note: this resets parameters! """ # set up detector space and initialize transformer setup_detector_layer_b01tc(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape #def handle_pool_shape(idx): # if self.pool_shape[idx] < 1: # raise ValueError("bad pool shape: " + str(self.pool_shape)) # if self.pool_shape[idx] > detector_shape[idx]: # if self.fix_pool_shape: # assert detector_shape[idx] > 0 # self.pool_shape[idx] = detector_shape[idx] # else: # raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) #map(handle_pool_shape, [0, 1, 2]) ### Check some precondition assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) for i in xrange(0, 2): assert self.pool_stride[i] <= self.pool_shape[i] assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) dummy_shape = [self.input_space.shape[0], self.input_space.shape[1]] # added to find out output space shape after temporal and spatial pooling "max_pool_c01b" dummy_output_shape = [ int(np.ceil((i_sh + 2. * self.pad - k_sh) / float(k_st))) + 1 for i_sh, k_sh, k_st in zip(dummy_shape, self.kernel_shape, self.kernel_stride) ] dummy_output_shape = [dummy_output_shape[0], dummy_output_shape[1]] #print dummy_output_shape dummy_detector_space = Conv2DSpace(shape=dummy_output_shape, num_channels=self.detector_channels, axes=('c', 0, 1, 'b')) # picked only 16 channels and 1 image in order to do a fast dummy maxpooling (16 because Alex's code needs at least 16 channels) dummy_detector = sharedX( dummy_detector_space.get_origin_batch(2)[0:16, :, :, :]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride) dummy_p = dummy_p.eval() # set space after temporal pooling with overlap if self.pool_temporal_stride[1] > self.pool_temporal_shape[1]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_temporal_shape[1] assert isinstance(ps, py_integer_types) self.pool_stride = [1, ps] else: raise ValueError("Stride too big.") # (0*1,'t') dummy_temp_image = [(dummy_p.shape[1] * dummy_p.shape[2]), self.detector_space.shape[2]] #overlapped temporal max pooling image_shape self.temp_pool_input_shape = dummy_temp_image dummy_temp_space = Conv2DSpace(shape=dummy_temp_image, num_channels=self.detector_channels, axes=('c', 0, 1, 'b')) temp_input = sharedX( dummy_temp_space.get_origin_batch(2)[0:16, :, :, :]) dummy_temp_p = temporal_max_pool_c01b( c01b=temp_input, pool_shape=self.pool_temporal_shape, pool_stride=self.pool_temporal_stride, image_shape=dummy_temp_image) dummy_temp_p = dummy_temp_p.eval() self.output_space = Conv3DSpace( shape=[dummy_p.shape[1], dummy_p.shape[2], dummy_temp_p.shape[2]], num_channels=self.num_channels, axes=('b', 0, 1, 't', 'c')) # Print spaces print "Input shape: ", self.input_space.shape print "Detector space: ", self.detector_space.shape print "Output space: ", self.output_space.shape
def fprop(self, state_below): self.input_space.validate(state_below) state_below = self.input_space.format_as(state_below, self.desired_space) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate((state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t else: s = T.maximum(s, t) z = s p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) else: z = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t else: s = T.maximum(s, t) z = s p = z self.output_space.validate(p) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p
def set_input_space(self, space): """ Note: this resets parameters! """ # setup_detector_layer_bct01(layer=self, # input_space=space, # rng=self.mlp.rng, # irange=self.irange) # Use theano conv3d instead setup_detector_layer_b01tc(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > detector_shape[idx]: if self.fix_pool_shape: assert detector_shape[idx] > 0 self.pool_shape[idx] = detector_shape[idx] else: raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1, 2]) ### Check some precondition assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) for i in xrange(0, 2): assert self.pool_stride[i] <= self.pool_shape[i] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) # Find space shape after convolution dummy_output_shape = [int(np.ceil((i_sh + 2. * self.pad - k_sh) / float(k_st))) + 1 for i_sh, k_sh, k_st in zip(self.input_space.shape, self.kernel_shape, self.kernel_stride)] dummy_output_sequence_length = dummy_output_shape[2] ### Find the space shape after spatial pooling dummy_output_shape = [dummy_output_shape[0], dummy_output_shape[1]] dummy_detector_space = Conv2DSpace(shape=dummy_output_shape, num_channels = self.detector_channels, axes = ('c', 0, 1, 'b')) dummy_detector = sharedX(dummy_detector_space.get_origin_batch(2)[0:16, :, :, :]) dummy_p = max_pool_c01b(c01b = dummy_detector, pool_shape = self.pool_shape, pool_stride = self.pool_stride) dummy_p = dummy_p.eval() ### Find the space shape after temporal pooling # (0*1,'t') dummy_temp_image = [dummy_p.shape[1] * dummy_p.shape[2] , dummy_output_sequence_length] self.temp_pool_input_shape = dummy_temp_image dummy_temp_space = Conv2DSpace(shape=dummy_temp_image, num_channels = self.detector_channels, axes = ('c', 0, 1, 'b')) temp_input = sharedX(dummy_temp_space.get_origin_batch(2)[0:16,:,:,:]) dummy_temp_p = temporal_max_pool_c01b(c01b=temp_input, pool_shape = [1, self.pool_shape[2]], pool_stride = [1, self.pool_stride[2]], image_shape = dummy_temp_image) dummy_temp_p = dummy_temp_p.eval() self.output_space = Conv3DSpace(shape=[dummy_p.shape[1], dummy_p.shape[2], dummy_temp_p.shape[2]], num_channels = self.num_channels, axes = ('b', 0, 1,'t','c')) # Print spaces print "Input shape: ", self.input_space.shape print "Detector space: ", self.detector_space.shape print "Output space: ", self.output_space.shape
def fprop(self, state_below): check_cuda() self.input_space.validate(state_below) state_below = self.input_space.format_as(state_below, self.desired_space) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate((state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t else: s = T.maximum(s, t) z = s if self.detector_normalization: z = self.detector_normalization(z) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) else: if self.detector_normalization is not None: raise NotImplementedError("We can't normalize the detector " "layer because the detector layer never exists as a " "stage of processing in this implementation.") z = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t else: s = T.maximum(s, t) z = s p = z self.output_space.validate(p) if hasattr(self, 'min_zero') and self.min_zero: p = p * (p > 0.) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p
def set_input_space(self, space): """ Note: this resets parameters! """ # set up detector space and initialize transformer setup_detector_layer_b01tc(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape #def handle_pool_shape(idx): # if self.pool_shape[idx] < 1: # raise ValueError("bad pool shape: " + str(self.pool_shape)) # if self.pool_shape[idx] > detector_shape[idx]: # if self.fix_pool_shape: # assert detector_shape[idx] > 0 # self.pool_shape[idx] = detector_shape[idx] # else: # raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) #map(handle_pool_shape, [0, 1, 2]) ### Check some precondition assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) for i in xrange(0, 2): assert self.pool_stride[i] <= self.pool_shape[i] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) dummy_shape = [self.input_space.shape[0] , self.input_space.shape[1]] # added to find out output space shape after temporal and spatial pooling "max_pool_c01b" dummy_output_shape = [int(np.ceil((i_sh + 2. * self.pad - k_sh) / float(k_st))) + 1 for i_sh, k_sh, k_st in zip(dummy_shape, self.kernel_shape, self.kernel_stride)] dummy_output_shape = [dummy_output_shape[0], dummy_output_shape[1]] #print dummy_output_shape dummy_detector_space = Conv2DSpace(shape=dummy_output_shape, num_channels = self.detector_channels, axes = ('c', 0, 1, 'b')) # picked only 16 channels and 1 image in order to do a fast dummy maxpooling (16 because Alex's code needs at least 16 channels) dummy_detector = sharedX(dummy_detector_space.get_origin_batch(2)[0:16,:,:,:]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride) dummy_p = dummy_p.eval() # set space after temporal pooling with overlap if self.pool_temporal_stride[1] > self.pool_temporal_shape[1]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_temporal_shape[1] assert isinstance(ps, py_integer_types) self.pool_stride = [1, ps] else: raise ValueError("Stride too big.") # (0*1,'t') dummy_temp_image = [(dummy_p.shape[1]*dummy_p.shape[2]) , self.detector_space.shape[2]] #overlapped temporal max pooling image_shape self.temp_pool_input_shape = dummy_temp_image dummy_temp_space = Conv2DSpace(shape=dummy_temp_image, num_channels = self.detector_channels, axes = ('c', 0, 1, 'b')) temp_input = sharedX(dummy_temp_space.get_origin_batch(2)[0:16,:,:,:]) dummy_temp_p = temporal_max_pool_c01b(c01b=temp_input, pool_shape=self.pool_temporal_shape, pool_stride=self.pool_temporal_stride,image_shape=dummy_temp_image) dummy_temp_p = dummy_temp_p.eval() self.output_space = Conv3DSpace(shape=[dummy_p.shape[1], dummy_p.shape[2],dummy_temp_p.shape[2]],num_channels = self.num_channels,axes = ('b', 0, 1,'t','c')) # Print spaces print "Input shape: ", self.input_space.shape print "Detector space: ", self.detector_space.shape print "Output space: ", self.output_space.shape
def set_input_space(self, space): """ Note: this resets parameters! """ # setup_detector_layer_bct01(layer=self, # input_space=space, # rng=self.mlp.rng, # irange=self.irange) # Use theano conv3d instead setup_detector_layer_b01tc(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > detector_shape[idx]: if self.fix_pool_shape: assert detector_shape[idx] > 0 self.pool_shape[idx] = detector_shape[idx] else: raise ValueError( "Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1, 2]) ### Check some precondition assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) for i in xrange(0, 2): assert self.pool_stride[i] <= self.pool_shape[i] assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) # Find space shape after convolution dummy_output_shape = [ int(np.ceil((i_sh + 2. * self.pad - k_sh) / float(k_st))) + 1 for i_sh, k_sh, k_st in zip(self.input_space.shape, self.kernel_shape, self.kernel_stride) ] dummy_output_sequence_length = dummy_output_shape[2] ### Find the space shape after spatial pooling dummy_output_shape = [dummy_output_shape[0], dummy_output_shape[1]] dummy_detector_space = Conv2DSpace(shape=dummy_output_shape, num_channels=self.detector_channels, axes=('c', 0, 1, 'b')) dummy_detector = sharedX( dummy_detector_space.get_origin_batch(2)[0:16, :, :, :]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride) dummy_p = dummy_p.eval() ### Find the space shape after temporal pooling # (0*1,'t') dummy_temp_image = [ dummy_p.shape[1] * dummy_p.shape[2], dummy_output_sequence_length ] self.temp_pool_input_shape = dummy_temp_image dummy_temp_space = Conv2DSpace(shape=dummy_temp_image, num_channels=self.detector_channels, axes=('c', 0, 1, 'b')) temp_input = sharedX( dummy_temp_space.get_origin_batch(2)[0:16, :, :, :]) dummy_temp_p = temporal_max_pool_c01b( c01b=temp_input, pool_shape=[1, self.pool_shape[2]], pool_stride=[1, self.pool_stride[2]], image_shape=dummy_temp_image) dummy_temp_p = dummy_temp_p.eval() self.output_space = Conv3DSpace( shape=[dummy_p.shape[1], dummy_p.shape[2], dummy_temp_p.shape[2]], num_channels=self.num_channels, axes=('b', 0, 1, 't', 'c')) # Print spaces print "Input shape: ", self.input_space.shape print "Detector space: ", self.detector_space.shape print "Output space: ", self.output_space.shape
def fprop(self, state_below): check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, "input_normalization"): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, "dummy_channels"): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate( (state_below, T.zeros_like(state_below[0 : self.dummy_channels, :, :, :])), axis=0 ) z = self.transformer.lmul(state_below) if not hasattr(self, "tied_b"): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, "x", "x", "x") else: b = self.b.dimshuffle(0, 1, 2, "x") z = z + b if self.layer_name is not None: z.name = self.layer_name + "_z" self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i :: self.num_pieces, :, :, :] if s is None: s = t else: s = T.maximum(s, t) z = s if self.detector_normalization: z = self.detector_normalization(z) p = max_pool_c01b( c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape ) else: if self.detector_normalization is not None: raise NotImplementedError( "We can't normalize the detector " "layer because the detector layer never exists as a " "stage of processing in this implementation." ) z = max_pool_c01b( c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape ) if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i :: self.num_pieces, :, :, :] if s is None: s = t else: s = T.maximum(s, t) z = s p = z self.output_space.validate(p) if hasattr(self, "min_zero") and self.min_zero: p = p * (p > 0.0) if not hasattr(self, "output_normalization"): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p
def piece_prop(self, state_below): """ Note: this only reports pieces in terms of which channel wins, not which spatial location wins. Depending on the input size, it may report a piece map for either the pre-spatial pooling or the post-spatial pooling tensor. """ check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate( (state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property piece = None if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces, :, :, :] if s is None: s = t piece = T.zeros_like(t) else: s = T.maximum(s, t) mask = T.eq(s, t) piece = mask * i + (1 - mask) * piece z = s if self.detector_normalization: z = self.detector_normalization(z) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) else: if self.detector_normalization is not None: raise NotImplementedError( "We can't normalize the detector " "layer because the detector layer never exists as a " "stage of processing in this implementation.") z = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) if self.num_pieces != 1: s = None piece = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces, :, :, :] if s is None: s = t piece = T.zeros_like(t) else: s = T.maximum(s, t) mask = T.eq(s, t) piece = mask * i + (1 - mask) * piece z = s p = z self.output_space.validate(p) if hasattr(self, 'min_zero') and self.min_zero: p = p * (p > 0.) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p, piece
def fprop(self, state_below): check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate((state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x', 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t else: s = T.maximum(s, t) z = s # pool across sequences if self.sequence_pool_shape != 1: s = None for i in xrange(self.sequence_pool_shape): t = z[:,:,:,i::self.sequence_pool_shape,:] if s is None: s = t else: s = T.maximum(s, t) z = s if self.detector_normalization: z = self.detector_normalization(z) # spatial pooling z_shape = z.shape z = z.reshape((z_shape[0], z_shape[1], z_shape[2], z_shape[3] * z_shape[4])) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) p_shape = p.shape p = p.reshape((p_shape[0], p_shape[1], p_shape[2], z_shape[3], z_shape[4])) else: raise NotImplementedError("num channles should always be dvisible by 16") self.output_space.validate(p) if hasattr(self, 'min_zero') and self.min_zero: p = p * (p > 0.) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p
def set_input_space(self, space): """ Note: this resets parameters! """ setup_detector_layer_c01tb(layer=self, input_space=space, rng=self.mlp.rng, irange=self.irange) rng = self.mlp.rng detector_shape = self.detector_space.shape def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > detector_shape[idx]: if self.fix_pool_shape: assert detector_shape[idx] > 0 self.pool_shape[idx] = detector_shape[idx] else: raise ValueError( "Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1]) assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.pool_stride[0] > self.pool_shape[0]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_shape[0] assert isinstance(ps, py_integer_types) self.pool_stride = [ps, ps] else: raise ValueError("Stride too big.") assert all( isinstance(elem, py_integer_types) for elem in self.pool_stride) dummy_detector = sharedX( self.detector_space.get_origin_batch(2)[0:16, :, :, 0, :]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) dummy_p = dummy_p.eval() if self.detector_space.sequence_length % ( self.sequence_pool_shape) != 0: raise ValueError( "The case where detector layer's sequence length doesn't divide sequene pool shape is not implmented" ) output_sequence_length = self.detector_space.sequence_length / self.sequence_pool_shape self.output_space = Conv3DSpace( shape=[dummy_p.shape[1], dummy_p.shape[2]], sequence_length=int(output_sequence_length), num_channels=self.num_channels, axes=('c', 0, 1, 't', 'b')) print "Output space shape: {}, sequence length: {}".format( self.output_space.shape, self.output_space.sequence_length)
def piece_prop(self, state_below): """ Note: this only reports pieces in terms of which channel wins, not which spatial location wins. Depending on the input size, it may report a piece map for either the pre-spatial pooling or the post-spatial pooling tensor. """ check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate((state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property piece = None if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t piece = T.zeros_like(t) else: s = T.maximum(s, t) mask = T.eq(s, t) piece = mask * i + (1 - mask) * piece z = s if self.detector_normalization: z = self.detector_normalization(z) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) else: if self.detector_normalization is not None: raise NotImplementedError("We can't normalize the detector " "layer because the detector layer never exists as a " "stage of processing in this implementation.") z = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) if self.num_pieces != 1: s = None piece = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces,:,:,:] if s is None: s = t piece = T.zeros_like(t) else: s = T.maximum(s, t) mask = T.eq(s, t) piece = mask * i + (1- mask) * piece z = s p = z self.output_space.validate(p) if hasattr(self, 'min_zero') and self.min_zero: p = p * (p > 0.) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p, piece
def fprop(self, state_below): check_cuda(str(type(self))) self.input_space.validate(state_below) if not hasattr(self, 'input_normalization'): self.input_normalization = None if self.input_normalization: state_below = self.input_normalization(state_below) # Alex's code requires # input channels to be <= 3 or a multiple of 4 # so we add dummy channels if necessary if not hasattr(self, 'dummy_channels'): self.dummy_channels = 0 if self.dummy_channels > 0: state_below = T.concatenate( (state_below, T.zeros_like(state_below[0:self.dummy_channels, :, :, :, :])), axis=0) z = self.transformer.lmul(state_below) if not hasattr(self, 'tied_b'): self.tied_b = False if self.tied_b: b = self.b.dimshuffle(0, 'x', 'x', 'x', 'x') else: b = self.b.dimshuffle(0, 1, 2, 'x', 'x') z = z + b if self.layer_name is not None: z.name = self.layer_name + '_z' self.detector_space.validate(z) assert self.detector_space.num_channels % 16 == 0 if self.output_space.num_channels % 16 == 0: # alex's max pool op only works when the number of channels # is divisible by 16. we can only do the cross-channel pooling # first if the cross-channel pooling preserves that property if self.num_pieces != 1: s = None for i in xrange(self.num_pieces): t = z[i::self.num_pieces, :, :, :] if s is None: s = t else: s = T.maximum(s, t) z = s # pool across sequences if self.sequence_pool_shape != 1: s = None for i in xrange(self.sequence_pool_shape): t = z[:, :, :, i::self.sequence_pool_shape, :] if s is None: s = t else: s = T.maximum(s, t) z = s if self.detector_normalization: z = self.detector_normalization(z) # spatial pooling z_shape = z.shape z = z.reshape( (z_shape[0], z_shape[1], z_shape[2], z_shape[3] * z_shape[4])) p = max_pool_c01b(c01b=z, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) p_shape = p.shape p = p.reshape( (p_shape[0], p_shape[1], p_shape[2], z_shape[3], z_shape[4])) else: raise NotImplementedError( "num channles should always be dvisible by 16") self.output_space.validate(p) if hasattr(self, 'min_zero') and self.min_zero: p = p * (p > 0.) if not hasattr(self, 'output_normalization'): self.output_normalization = None if self.output_normalization: p = self.output_normalization(p) return p
def set_input_space(self, space): """ Note: this resets parameters! """ self.input_space = space if not isinstance(self.input_space, Conv2DSpace): raise TypeError( "The input to a convolutional layer should be a Conv2DSpace, " " but layer " + self.layer_name + " got " + str(type(self.input_space)) ) # note: I think the desired space thing is actually redundant, # since LinearTransform will also dimshuffle the axes if needed # It's not hurting anything to have it here but we could reduce # code complexity by removing it self.desired_space = Conv2DSpace(shape=space.shape, channels=space.num_channels, axes=("c", 0, 1, "b")) ch = self.desired_space.num_channels rem = ch % 4 if ch > 3 and rem != 0: self.dummy_channels = 4 - rem else: self.dummy_channels = 0 self.dummy_space = Conv2DSpace( shape=space.shape, channels=space.num_channels + self.dummy_channels, axes=("c", 0, 1, "b") ) rng = self.mlp.rng output_shape = [ self.input_space.shape[0] + 2 * self.pad - self.kernel_shape[0] + 1, self.input_space.shape[1] + 2 * self.pad - self.kernel_shape[1] + 1, ] def handle_kernel_shape(idx): if self.kernel_shape[idx] < 1: raise ValueError( "kernel must have strictly positive size on all axes but has shape: " + str(self.kernel_shape) ) if output_shape[idx] <= 0: if self.fix_kernel_shape: self.kernel_shape[idx] = self.input_space.shape[idx] + 2 * self.pad assert self.kernel_shape[idx] != 0 output_shape[idx] = 1 warnings.warn("Had to change the kernel shape to make network feasible") else: raise ValueError("kernel too big for input (even with zero padding)") map(handle_kernel_shape, [0, 1]) self.detector_space = Conv2DSpace( shape=output_shape, num_channels=self.detector_channels, axes=("c", 0, 1, "b") ) if self.pool_shape is not None: def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > output_shape[idx]: if self.fix_pool_shape: assert output_shape[idx] > 0 self.pool_shape[idx] = output_shape[idx] else: raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1]) assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.pool_stride[0] > self.pool_shape[0]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_shape[0] assert isinstance(ps, py_integer_types) self.pool_stride = [ps, ps] else: raise ValueError("Stride too big.") assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.irange is not None: self.transformer = local_c01b.make_random_local( input_groups=self.input_groups, irange=self.irange, input_axes=self.desired_space.axes, image_shape=self.desired_space.shape, output_axes=self.detector_space.axes, input_channels=self.dummy_space.num_channels, output_channels=self.detector_space.num_channels, kernel_shape=self.kernel_shape, kernel_stride=self.kernel_stride, pad=self.pad, partial_sum=self.partial_sum, rng=rng, ) W, = self.transformer.get_params() W.name = "W" if self.tied_b: self.b = sharedX(np.zeros((self.detector_space.num_channels)) + self.init_bias) else: self.b = sharedX(self.detector_space.get_origin() + self.init_bias) self.b.name = "b" print "Input shape: ", self.input_space.shape print "Detector space: ", self.detector_space.shape assert self.detector_space.num_channels >= 16 if self.pool_shape is None: self.output_space = Conv2DSpace( shape=self.detector_space.shape, num_channels=self.num_channels, axes=("c", 0, 1, "b") ) else: dummy_detector = sharedX(self.detector_space.get_origin_batch(2)[0:16, :, :, :]) dummy_p = max_pool_c01b( c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape, ) dummy_p = dummy_p.eval() self.output_space = Conv2DSpace( shape=[dummy_p.shape[1], dummy_p.shape[2]], num_channels=self.num_channels, axes=("c", 0, 1, "b") ) print "Output space: ", self.output_space.shape
def set_input_space(self, space): """ Note: this resets parameters! """ self.input_space = space if not isinstance(self.input_space, Conv2DSpace): raise TypeError("The input to a convolutional layer should be a Conv2DSpace, " " but layer " + self.layer_name + " got "+str(type(self.input_space))) # note: I think the desired space thing is actually redundant, # since LinearTransform will also dimshuffle the axes if needed # It's not hurting anything to have it here but we could reduce # code complexity by removing it self.desired_space = Conv2DSpace(shape=space.shape, channels=space.num_channels, axes=('c', 0, 1, 'b')) ch = self.desired_space.num_channels rem = ch % 4 if ch > 3 and rem != 0: self.dummy_channels = 4 - rem else: self.dummy_channels = 0 self.dummy_space = Conv2DSpace(shape=space.shape, channels=space.num_channels + self.dummy_channels, axes=('c', 0, 1, 'b')) rng = self.mlp.rng output_shape = [self.input_space.shape[0] + 2 * self.pad - self.kernel_shape[0] + 1, self.input_space.shape[1] + 2 * self.pad - self.kernel_shape[1] + 1] def handle_kernel_shape(idx): if self.kernel_shape[idx] < 1: raise ValueError("kernel must have strictly positive size on all axes but has shape: "+str(self.kernel_shape)) if output_shape[idx] <= 0: if self.fix_kernel_shape: self.kernel_shape[idx] = self.input_space.shape[idx] + 2 * self.pad assert self.kernel_shape[idx] != 0 output_shape[idx] = 1 warnings.warn("Had to change the kernel shape to make network feasible") else: raise ValueError("kernel too big for input (even with zero padding)") map(handle_kernel_shape, [0, 1]) self.detector_space = Conv2DSpace(shape=output_shape, num_channels = self.detector_channels, axes = ('c', 0, 1, 'b')) def handle_pool_shape(idx): if self.pool_shape[idx] < 1: raise ValueError("bad pool shape: " + str(self.pool_shape)) if self.pool_shape[idx] > output_shape[idx]: if self.fix_pool_shape: assert output_shape[idx] > 0 self.pool_shape[idx] = output_shape[idx] else: raise ValueError("Pool shape exceeds detector layer shape on axis %d" % idx) map(handle_pool_shape, [0, 1]) assert self.pool_shape[0] == self.pool_shape[1] assert self.pool_stride[0] == self.pool_stride[1] assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) if self.pool_stride[0] > self.pool_shape[0]: if self.fix_pool_stride: warnings.warn("Fixing the pool stride") ps = self.pool_shape[0] assert isinstance(ps, py_integer_types) self.pool_stride = [ps, ps] else: raise ValueError("Stride too big.") assert all(isinstance(elem, py_integer_types) for elem in self.pool_stride) check_cuda() if self.irange is not None: self.transformer = conv2d_c01b.make_random_conv2D( irange = self.irange, input_axes = self.desired_space.axes, output_axes = self.detector_space.axes, input_channels = self.dummy_space.num_channels, output_channels = self.detector_space.num_channels, kernel_shape = self.kernel_shape, subsample = (1,1), pad = self.pad, partial_sum = self.partial_sum, rng = rng) W, = self.transformer.get_params() W.name = 'W' if self.tied_b: self.b = sharedX(np.zeros((self.detector_space.num_channels)) + self.init_bias) else: self.b = sharedX(self.detector_space.get_origin() + self.init_bias) self.b.name = 'b' print 'Input shape: ', self.input_space.shape print 'Detector space: ', self.detector_space.shape assert self.detector_space.num_channels >= 16 dummy_detector = sharedX(self.detector_space.get_origin_batch(2)[0:16,:,:,:]) dummy_p = max_pool_c01b(c01b=dummy_detector, pool_shape=self.pool_shape, pool_stride=self.pool_stride, image_shape=self.detector_space.shape) dummy_p = dummy_p.eval() self.output_space = Conv2DSpace(shape=[dummy_p.shape[1], dummy_p.shape[2]], num_channels = self.num_channels, axes = ('c', 0, 1, 'b') ) print 'Output space: ', self.output_space.shape