Source code for pylissom.nn.modules.linear

import torch
from torch.nn import Linear, Module

from pylissom.nn.functional.functions import piecewise_sigmoid
from pylissom.nn.functional.weights import get_gaussian_weights, apply_circular_mask_to_weights


[docs]class GaussianLinear(Linear): """Applies a linear transformation to the incoming data: :math:`y = Ax + b` where A is a Gaussian matrix Parameters: - **sigma** - """ # ASSUMES SQUARE MAPS def __init__(self, in_features, out_features, sigma=1.0): super(GaussianLinear, self).__init__(in_features, out_features, bias=False) self.sigma = sigma self.weight = torch.nn.Parameter(get_gaussian_weights(in_features=in_features, out_features=out_features, sigma=sigma)) def __repr__(self): super_repr = super(GaussianLinear, self).__repr__()[:-1] return super_repr \ + ', ' + 'sigma=' + str(self.sigma) \ + ')'
[docs]class GaussianCloudLinear(GaussianLinear): """Applies a linear transformation to the incoming data: :math:`y = Ax + b` where A is a Gaussian matrix multiplied with Gaussian Noise Parameters: - **sigma** - """ # ASSUMES SQUARE MAPS def __init__(self, in_features, out_features, sigma=1.0): super(GaussianCloudLinear, self).__init__(in_features, out_features, sigma=sigma) uniform_noise = torch.FloatTensor(self.weight.data.size()).uniform_(0, 1) self.weight.data.mul_(uniform_noise)
[docs]class PiecewiseSigmoid(Module): r"""Applies a piecewise approximation of the sigmoid function :math:`f(x) = 1 / ( 1 + exp(-x))` The formula is as follows: TODO Parameters: - **min_theta** - - **max_theta** - """ def __init__(self, min_theta=0.0, max_theta=1.0): super(PiecewiseSigmoid, self).__init__() self.max_theta = max_theta self.min_theta = min_theta
[docs] def forward(self, input): # TODO: add inplace option return piecewise_sigmoid(min_theta=self.min_theta, max_theta=self.max_theta, inp=input)
def __repr__(self): return self.__class__.__name__ + ' (' \ + 'min_theta=' + str(self.min_theta) \ + ', ' + 'max_theta=' + str(self.max_theta) \ + ')'
# class AfferentNorm(Module): # def __init__(self, strength, radius): # super(AfferentNorm, self).__init__() # self.radius = radius # self.strength = strength # # def forward(self, afferent_input, activation): # # TODO: add inplace option # return afferent_normalize(strength=self.strength, # afferent_input=afferent_input, # activation=activation, # radius=self.radius) # # def __repr__(self): # return self.__class__.__name__ + ' (' \ # + 'radius=' + str(self.radius) \ # + ', ' + 'strength=' + str(self.strength) \ # + ')' # # # TODO: test, remove if not used # class CircularMask(Module): # def __init__(self, radius): # super(CircularMask, self).__init__() # self.radius = radius # # def forward(self, input): # # TODO: add inplace option # apply_circular_mask_to_weights(matrix=input, radius=self.radius) # # def __repr__(self): # return self.__class__.__name__ + ' (' \ # + 'radius=' + str(self.radius) \ # + ')'
[docs]class UnnormalizedDifferenceOfGaussiansLinear(Linear): r"""NOT USED, only for example in notebooks""" # Not used in lissom, only for example # ASSUMES SQUARE MAPS def __init__(self, in_features, out_features, on, sigma_surround, sigma_center=1.0): super(UnnormalizedDifferenceOfGaussiansLinear, self).__init__(in_features, out_features, bias=False) self.on = on self.sigma_surround = sigma_surround self.sigma_center = sigma_center sigma_center_weights_matrix = get_gaussian_weights(in_features, out_features, sigma_center) sigma_surround_weights_matrix = get_gaussian_weights(in_features, out_features, sigma_surround) if on: diff = sigma_center_weights_matrix - sigma_surround_weights_matrix else: diff = sigma_surround_weights_matrix - sigma_center_weights_matrix self.weight = torch.nn.Parameter(diff)