From de0cb1a4e3dbad42950ec713f128ca36d450dbfc Mon Sep 17 00:00:00 2001 From: ltcptgeneral Date: Mon, 30 Sep 2019 16:02:32 -0500 Subject: [PATCH] analysis.py v 1.1.2.000, quick fixes --- .../__pycache__/analysis.cpython-37.pyc | Bin 15694 -> 15912 bytes data analysis/analysis/analysis.py | 237 +++++++++++++++++- data analysis/analysis/regression.py | 2 +- 3 files changed, 232 insertions(+), 7 deletions(-) diff --git a/data analysis/analysis/__pycache__/analysis.cpython-37.pyc b/data analysis/analysis/__pycache__/analysis.cpython-37.pyc index 85ffa6867fd506ed97aec7a09b8bb44996d9a14e..e608752d4b625da3c53b615fa6a69e3cd3105f14 100644 GIT binary patch delta 3101 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", - "Jacob Levine ", + "Arthur Lu ", + "Jacob Levine ", ) __all__ = [ @@ -148,6 +153,7 @@ __all__ = [ 'r_squared', 'mse', 'rms', + 'regression' # all statistics functions left out due to integration in other functions ] @@ -160,7 +166,6 @@ import numba from numba import jit import numpy as np import math -from analysis import regression from sklearn import metrics from sklearn import preprocessing import torch @@ -322,4 +327,224 @@ def stdev(data): @jit(nopython=True) def variance(data): - return np.var(data) \ No newline at end of file + return np.var(data) + +class regression: + + # Titan Robotics Team 2022: CUDA-based Regressions Module + # Written by Arthur Lu & Jacob Levine + # Notes: + # this module has been automatically inegrated into analysis.py, and should be callable as a class from the package + # this module is cuda-optimized and vectorized (except for one small part) + # setup: + + __version__ = "1.0.0.002" + + # changelog should be viewed using print(analysis.regression.__changelog__) + __changelog__ = """ + 1.0.0.002: + -Added more parameters to log, exponential, polynomial + -Added SigmoidalRegKernelArthur, because Arthur apparently needs + to train the scaling and shifting of sigmoids + + 1.0.0.001: + -initial release, with linear, log, exponential, polynomial, and sigmoid kernels + -already vectorized (except for polynomial generation) and CUDA-optimized + """ + + __author__ = ( + "Jacob Levine ", + "Arthur Lu " + ) + + __all__ = [ + 'factorial', + 'take_all_pwrs', + 'num_poly_terms', + 'set_device', + 'LinearRegKernel', + 'SigmoidalRegKernel', + 'LogRegKernel', + 'PolyRegKernel', + 'ExpRegKernel', + 'SigmoidalRegKernelArthur', + 'SGDTrain', + 'CustomTrain' + ] + + + # imports (just one for now): + + import torch + + device = "cuda:0" if torch.torch.cuda.is_available() else "cpu" + + #todo: document completely + + def factorial(n): + if n==0: + return 1 + else: + return n*factorial(n-1) + def num_poly_terms(num_vars, power): + if power == 0: + return 0 + return int(factorial(num_vars+power-1) / factorial(power) / factorial(num_vars-1)) + num_poly_terms(num_vars, power-1) + + def take_all_pwrs(vec,pwr): + #todo: vectorize (kinda) + combins=torch.combinations(vec, r=pwr, with_replacement=True) + out=torch.ones(combins.size()[0]) + for i in torch.t(combins): + out *= i + return torch.cat(out,take_all_pwrs(vec, pwr-1)) + + def set_device(new_device): + global device + device=new_device + + class LinearRegKernel(): + parameters= [] + weights=None + bias=None + def __init__(self, num_vars): + self.weights=torch.rand(num_vars, requires_grad=True, device=device) + self.bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.bias] + def forward(self,mtx): + long_bias=self.bias.repeat([1,mtx.size()[1]]) + return torch.matmul(self.weights,mtx)+long_bias + + class SigmoidalRegKernel(): + parameters= [] + weights=None + bias=None + sigmoid=torch.nn.Sigmoid() + def __init__(self, num_vars): + self.weights=torch.rand(num_vars, requires_grad=True, device=device) + self.bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.bias] + def forward(self,mtx): + long_bias=self.bias.repeat([1,mtx.size()[1]]) + return self.sigmoid(torch.matmul(self.weights,mtx)+long_bias) + + class SigmoidalRegKernelArthur(): + parameters= [] + weights=None + in_bias=None + scal_mult=None + out_bias=None + sigmoid=torch.nn.Sigmoid() + def __init__(self, num_vars): + self.weights=torch.rand(num_vars, requires_grad=True, device=device) + self.in_bias=torch.rand(1, requires_grad=True, device=device) + self.scal_mult=torch.rand(1, requires_grad=True, device=device) + self.out_bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.in_bias, self.scal_mult, self.out_bias] + def forward(self,mtx): + long_in_bias=self.in_bias.repeat([1,mtx.size()[1]]) + long_out_bias=self.out_bias.repeat([1,mtx.size()[1]]) + return (self.scal_mult*self.sigmoid(torch.matmul(self.weights,mtx)+long_in_bias))+long_out_bias + + class LogRegKernel(): + parameters= [] + weights=None + in_bias=None + scal_mult=None + out_bias=None + def __init__(self, num_vars): + self.weights=torch.rand(num_vars, requires_grad=True, device=device) + self.in_bias=torch.rand(1, requires_grad=True, device=device) + self.scal_mult=torch.rand(1, requires_grad=True, device=device) + self.out_bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.in_bias, self.scal_mult, self.out_bias] + def forward(self,mtx): + long_in_bias=self.in_bias.repeat([1,mtx.size()[1]]) + long_out_bias=self.out_bias.repeat([1,mtx.size()[1]]) + return (self.scal_mult*torch.log(torch.matmul(self.weights,mtx)+long_in_bias))+long_out_bias + + class ExpRegKernel(): + parameters= [] + weights=None + in_bias=None + scal_mult=None + out_bias=None + def __init__(self, num_vars): + self.weights=torch.rand(num_vars, requires_grad=True, device=device) + self.in_bias=torch.rand(1, requires_grad=True, device=device) + self.scal_mult=torch.rand(1, requires_grad=True, device=device) + self.out_bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.in_bias, self.scal_mult, self.out_bias] + def forward(self,mtx): + long_in_bias=self.in_bias.repeat([1,mtx.size()[1]]) + long_out_bias=self.out_bias.repeat([1,mtx.size()[1]]) + return (self.scal_mult*torch.exp(torch.matmul(self.weights,mtx)+long_in_bias))+long_out_bias + + class PolyRegKernel(): + parameters= [] + weights=None + bias=None + power=None + def __init__(self, num_vars, power): + self.power=power + num_terms=num_poly_terms(num_vars, power) + self.weights=torch.rand(num_terms, requires_grad=True, device=device) + self.bias=torch.rand(1, requires_grad=True, device=device) + self.parameters=[self.weights,self.bias] + def forward(self,mtx): + #TODO: Vectorize the last part + cols=[] + for i in torch.t(mtx): + cols.append(take_all_pwrs(i,self.power)) + new_mtx=torch.t(torch.stack(cols)) + long_bias=self.bias.repeat([1,mtx.size()[1]]) + return torch.matmul(self.weights,new_mtx)+long_bias + + def SGDTrain(kernel, data, ground, loss=torch.nn.MSELoss(), iterations=1000, learning_rate=.1, return_losses=False): + optim=torch.optim.SGD(kernel.parameters, lr=learning_rate) + data_cuda=data.to(device) + ground_cuda=ground.to(device) + if (return_losses): + losses=[] + for i in range(iterations): + with torch.set_grad_enabled(True): + optim.zero_grad() + pred=kernel.forward(data_cuda) + ls=loss(pred,ground_cuda) + losses.append(ls.item()) + ls.backward() + optim.step() + return [kernel,losses] + else: + for i in range(iterations): + with torch.set_grad_enabled(True): + optim.zero_grad() + pred=kernel.forward(data_cuda) + ls=loss(pred,ground_cuda) + ls.backward() + optim.step() + return kernel + + def CustomTrain(kernel, optim, data, ground, loss=torch.nn.MSELoss(), iterations=1000, return_losses=False): + data_cuda=data.to(device) + ground_cuda=ground.to(device) + if (return_losses): + losses=[] + for i in range(iterations): + with torch.set_grad_enabled(True): + optim.zero_grad() + pred=kernel.forward(data) + ls=loss(pred,ground) + losses.append(ls.item()) + ls.backward() + optim.step() + return [kernel,losses] + else: + for i in range(iterations): + with torch.set_grad_enabled(True): + optim.zero_grad() + pred=kernel.forward(data_cuda) + ls=loss(pred,ground_cuda) + ls.backward() + optim.step() + return kernel \ No newline at end of file diff --git a/data analysis/analysis/regression.py b/data analysis/analysis/regression.py index f01d04d3..35893f50 100644 --- a/data analysis/analysis/regression.py +++ b/data analysis/analysis/regression.py @@ -8,7 +8,7 @@ __version__ = "1.0.0.002" -# changelog should be viewed using print(cudaregress.__changelog__) +# changelog should be viewed using print(regression.__changelog__) __changelog__ = """ 1.0.0.002: -Added more parameters to log, exponential, polynomial