To implement RMSNorm in a ConvPool-CNN-C architecture using Lasagne:
- Clone the weight_norm repository.
- Add the
RMSNormLayer class and the rms_norm helper function to nn.py. - Update
train.py to handle the rms_norm type:elif args.norm_type=='rms_norm':
normalizer = lambda l: nn.rms_norm(l)
- Download the CIFAR-10 dataset and update the paths in
train.py. - Train using the following command:
GPUARRAY_FORCE_CUDA_DRIVER_LOAD=True THEANO_FLAGS=mode=FAST_RUN,floatX=float32,device=$device,gpuarray.preallocate=0.4 python train.py --norm_type rms_norm --learning_rate 0.003
class RMSNormLayer(lasagne.layers.Layer):
def __init__(self, incoming, b=lasagne.init.Constant(0.), g=lasagne.init.Constant(1.),
W=lasagne.init.Normal(0.05), nonlinearity=relu, **kwargs):
super(RMSNormLayer, self).__init__(incoming, **kwargs)
self.nonlinearity = nonlinearity
k = self.input_shape[1]
if b is not None:
self.b = self.add_param(b, (k,), name="b", regularizable=False)
if g is not None:
self.g = self.add_param(g, (k,), name="g")
if len(self.input_shape)==4:
self.axes_to_sum = (2,3)
self.dimshuffle_args = ['x',0,'x','x']
else:
self.axes_to_sum = 1
self.dimshuffle_args = ['x',0]
def get_output_for(self, input, **kwargs):
meanS = T.mean(input ** 2,axis=self.axes_to_sum,keepdims=True)
norm_input = input / T.sqrt(meanS + 1e-6)
if hasattr(self, 'g'):
activation = norm_input*self.g.dimshuffle(*self.dimshuffle_args)
else:
activation = norm_input
if hasattr(self, 'b'):
activation += self.b.dimshuffle(*self.dimshuffle_args)
return self.nonlinearity(activation)
def rms_norm(layer, b=lasagne.init.Constant(0.), g=lasagne.init.Constant(1.), **kwargs):
nonlinearity = getattr(layer, 'nonlinearity', None)
if nonlinearity is not None:
layer.nonlinearity = lasagne.nonlinearities.identity
if hasattr(layer, 'b'):
del layer.params[layer.b]
layer.b = None
return RMSNormLayer(layer, b, g, nonlinearity=nonlinearity, **kwargs)