def check(*input_dim): sbn = SpatialBatchNormalization(input_dim) sbn.initialize() x = theano.tensor.TensorType(theano.config.floatX, [False] * (len(input_dim) + 1))() y = sbn.apply(x) rng = numpy.random.RandomState((2015, 12, 17)) input_ = random_unif(rng, (11,) + input_dim) assert_equal(y.eval({x: input_}), input_)
class ResidualConvolutional(Initializable): @lazy(allocation=['filter_size', 'num_filters', 'num_channels']) def __init__(self, filter_size, num_filters, num_channels, batch_size=None, mid_noise=False, out_noise=False, tied_noise=False, tied_sigma=False, noise_rate=None, noise_batch_size=None, prior_noise_level=None, image_size=(None, None), step=(1, 1), **kwargs): self.filter_size = filter_size self.num_filters = num_filters self.batch_size = batch_size self.num_channels = num_channels self.image_size = image_size self.mid_noise = mid_noise self.noise_batch_size = noise_batch_size self.noise_rate = noise_rate self.step = step self.border_mode = 'half' self.tied_biases = True depth = 2 self.b0 = SpatialBatchNormalization(name='b0') self.r0 = Rectifier(name='r0') self.n0 = (SpatialNoise(name='n0', noise_rate=self.noise_rate, tied_noise=tied_noise, tied_sigma=tied_sigma, prior_noise_level=prior_noise_level) if mid_noise else None) self.c0 = Convolutional(name='c0') self.b1 = SpatialBatchNormalization(name='b1') self.r1 = Rectifier(name='r1') self.n1 = (SpatialNoise(name='n1', noise_rate=self.noise_rate, tied_noise=tied_noise, tied_sigma=tied_sigma, prior_noise_level=prior_noise_level) if out_noise else None) self.c1 = Convolutional(name='c1') kwargs.setdefault('children', []).extend([c for c in [ self.c0, self.b0, self.r0, self.n0, self.c1, self.b1, self.r1, self.n1] if c is not None]) super(ResidualConvolutional, self).__init__(**kwargs) def get_dim(self, name): if name == 'input_': return ((self.num_channels,) + self.image_size) if name == 'output': return self.c1.get_dim(name) return super(ResidualConvolutionalUnit, self).get_dim(name) @property def num_output_channels(self): return self.num_filters def _push_allocation_config(self): self.b0.input_dim = self.get_dim('input_') self.b0.push_allocation_config() if self.r0: self.r0.push_allocation_config() if self.n0: self.n0.noise_batch_size = self.noise_batch_size self.n0.num_channels = self.num_channels self.n0.image_size = self.image_size self.c0.filter_size = self.filter_size self.c0.batch_size = self.batch_size self.c0.num_channels = self.num_channels self.c0.num_filters = self.num_filters self.c0.border_mode = self.border_mode self.c0.image_size = self.image_size self.c0.step = self.step self.c0.use_bias = False self.c0.push_allocation_config() c0_shape = self.c0.get_dim('output') self.b1.input_dim = c0_shape self.b1.push_allocation_config() self.r1.push_allocation_config() if self.n1: self.n1.noise_batch_size = self.noise_batch_size self.n1.num_channels = self.num_filters self.n1.image_size = c0_shape[1:] self.c1.filter_size = self.filter_size self.c1.batch_size = self.batch_size self.c1.num_channels = self.num_filters self.c1.num_filters = self.num_filters self.c1.border_mode = self.border_mode self.c1.image_size = c0_shape[1:] self.c1.step = (1, 1) self.c1.use_bias = False self.c1.push_allocation_config() @application(inputs=['input_'], outputs=['output']) def apply(self, input_): shortcut = input_ # Batchnorm, then Relu, then Convolution first_conv = self.b0.apply(input_) first_conv = self.r0.apply(first_conv) if self.n0: first_conv = self.n0.apply(first_conv) first_conv = self.c0.apply(first_conv) # Batchnorm, then Relu, then Convolution (second time) second_conv = self.b1.apply(first_conv) second_conv = self.r1.apply(second_conv) if self.n1: second_conv = self.n1.apply(second_conv) residual = second_conv # Apply stride and zero-padding to match shortcut to output if self.step and self.step != (1, 1): shortcut = shortcut[:,:,::self.step[0],::self.step[1]] if self.num_filters > self.num_channels: padshape = (residual.shape[0], self.num_filters - self.num_channels, residual.shape[2], residual.shape[3]) shortcut = tensor.concatenate( [shortcut, tensor.zeros(padshape, dtype=residual.dtype)], axis=1) elif self.num_filters < self.num_channels: shortcut = shortcut[:,:self.num_channels,:,:] response = shortcut + residual return response
class ResidualConvolutional(Initializable): @lazy(allocation=['filter_size', 'num_filters', 'num_channels']) def __init__(self, filter_size, num_filters, num_channels, batch_size=None, mid_noise=False, out_noise=False, tied_noise=False, tied_sigma=False, noise_rate=None, noise_batch_size=None, prior_noise_level=None, image_size=(None, None), step=(1, 1), **kwargs): self.filter_size = filter_size self.num_filters = num_filters self.batch_size = batch_size self.num_channels = num_channels self.image_size = image_size self.mid_noise = mid_noise self.noise_batch_size = noise_batch_size self.noise_rate = noise_rate self.step = step self.border_mode = 'half' self.tied_biases = True depth = 2 self.b0 = SpatialBatchNormalization(name='b0') self.r0 = Rectifier(name='r0') self.n0 = (SpatialNoise(name='n0', noise_rate=self.noise_rate, tied_noise=tied_noise, tied_sigma=tied_sigma, prior_noise_level=prior_noise_level) if mid_noise else None) self.c0 = Convolutional(name='c0') self.b1 = SpatialBatchNormalization(name='b1') self.r1 = Rectifier(name='r1') self.n1 = (SpatialNoise(name='n1', noise_rate=self.noise_rate, tied_noise=tied_noise, tied_sigma=tied_sigma, prior_noise_level=prior_noise_level) if out_noise else None) self.c1 = Convolutional(name='c1') kwargs.setdefault('children', []).extend([ c for c in [ self.c0, self.b0, self.r0, self.n0, self.c1, self.b1, self.r1, self.n1 ] if c is not None ]) super(ResidualConvolutional, self).__init__(**kwargs) def get_dim(self, name): if name == 'input_': return ((self.num_channels, ) + self.image_size) if name == 'output': return self.c1.get_dim(name) return super(ResidualConvolutionalUnit, self).get_dim(name) @property def num_output_channels(self): return self.num_filters def _push_allocation_config(self): self.b0.input_dim = self.get_dim('input_') self.b0.push_allocation_config() if self.r0: self.r0.push_allocation_config() if self.n0: self.n0.noise_batch_size = self.noise_batch_size self.n0.num_channels = self.num_channels self.n0.image_size = self.image_size self.c0.filter_size = self.filter_size self.c0.batch_size = self.batch_size self.c0.num_channels = self.num_channels self.c0.num_filters = self.num_filters self.c0.border_mode = self.border_mode self.c0.image_size = self.image_size self.c0.step = self.step self.c0.use_bias = False self.c0.push_allocation_config() c0_shape = self.c0.get_dim('output') self.b1.input_dim = c0_shape self.b1.push_allocation_config() self.r1.push_allocation_config() if self.n1: self.n1.noise_batch_size = self.noise_batch_size self.n1.num_channels = self.num_filters self.n1.image_size = c0_shape[1:] self.c1.filter_size = self.filter_size self.c1.batch_size = self.batch_size self.c1.num_channels = self.num_filters self.c1.num_filters = self.num_filters self.c1.border_mode = self.border_mode self.c1.image_size = c0_shape[1:] self.c1.step = (1, 1) self.c1.use_bias = False self.c1.push_allocation_config() @application(inputs=['input_'], outputs=['output']) def apply(self, input_): shortcut = input_ # Batchnorm, then Relu, then Convolution first_conv = self.b0.apply(input_) first_conv = self.r0.apply(first_conv) if self.n0: first_conv = self.n0.apply(first_conv) first_conv = self.c0.apply(first_conv) # Batchnorm, then Relu, then Convolution (second time) second_conv = self.b1.apply(first_conv) second_conv = self.r1.apply(second_conv) if self.n1: second_conv = self.n1.apply(second_conv) residual = second_conv # Apply stride and zero-padding to match shortcut to output if self.step and self.step != (1, 1): shortcut = shortcut[:, :, ::self.step[0], ::self.step[1]] if self.num_filters > self.num_channels: padshape = (residual.shape[0], self.num_filters - self.num_channels, residual.shape[2], residual.shape[3]) shortcut = tensor.concatenate( [shortcut, tensor.zeros(padshape, dtype=residual.dtype)], axis=1) elif self.num_filters < self.num_channels: shortcut = shortcut[:, :self.num_channels, :, :] response = shortcut + residual return response