| import future |
| import builtins |
| import past |
| import six |
| import inspect |
| import os |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| import torch.optim as optim |
| import numpy as np |
| import argparse |
| import decimal |
| import PIL |
| from torchvision import datasets, transforms |
| from datetime import datetime |
|
|
| from forbiddenfruit import curse |
| |
|
|
| from timeit import default_timer as timer |
|
|
| class Timer: |
| def __init__(self, activity = None, units = 1, shouldPrint = True, f = None): |
| self.activity = activity |
| self.units = units |
| self.shouldPrint = shouldPrint |
| self.f = f |
| def __enter__(self): |
| self.start = timer() |
| return self |
| def getUnitTime(self): |
| return (self.end - self.start) / self.units |
|
|
| def __str__(self): |
| return "Avg time to " + self.activity + ": "+str(self.getUnitTime()) |
|
|
| def __exit__(self, *args): |
| self.end = timer() |
| if self.shouldPrint: |
| printBoth(self, f = self.f) |
| |
| def cudify(x): |
| if use_cuda: |
| return x.cuda(async=True) |
| return x |
|
|
| def pyval(a, **kargs): |
| return dten([a], **kargs) |
|
|
| def ifThenElse(cond, a, b): |
| cond = cond.to_dtype() |
| return cond * a + (1 - cond) * b |
|
|
| def ifThenElseL(cond, a, b): |
| return cond * a + (1 - cond) * b |
|
|
| def product(it): |
| if isinstance(it,int): |
| return it |
| product = 1 |
| for x in it: |
| if x >= 0: |
| product *= x |
| return product |
|
|
| def getEi(batches, num_elem): |
| return eye(num_elem).expand(batches, num_elem,num_elem).permute(1,0,2) |
|
|
| def one_hot(batch,d): |
| bs = batch.size()[0] |
| indexes = [ list(range(bs)), batch] |
| values = [ 1 for _ in range(bs) ] |
| return cudify(torch.sparse.FloatTensor(ltenCPU(indexes), ftenCPU(values), torch.Size([bs,d]))) |
|
|
| def seye(n, m = None): |
| if m is None: |
| m = n |
| mn = n if n < m else m |
| indexes = [[ i for i in range(mn) ], [ i for i in range(mn) ] ] |
| values = [1 for i in range(mn) ] |
| return cudify(torch.sparse.ByteTensor(ltenCPU(indexes), dtenCPU(values), torch.Size([n,m]))) |
|
|
| dtype = torch.float32 |
| ftype = torch.float32 |
| ltype = torch.int64 |
| btype = torch.uint8 |
|
|
| torch.set_default_dtype(dtype) |
|
|
| cpu = torch.device("cpu") |
|
|
| cuda_async = True |
|
|
| ftenCPU = lambda *args, **kargs: torch.tensor(*args, dtype=ftype, device=cpu, **kargs) |
| dtenCPU = lambda *args, **kargs: torch.tensor(*args, dtype=dtype, device=cpu, **kargs) |
| ltenCPU = lambda *args, **kargs: torch.tensor(*args, dtype=ltype, device=cpu, **kargs) |
| btenCPU = lambda *args, **kargs: torch.tensor(*args, dtype=btype, device=cpu, **kargs) |
|
|
| if torch.cuda.is_available() and not 'NOCUDA' in os.environ: |
| print("using cuda") |
| device = torch.device("cuda") |
| ften = lambda *args, **kargs: torch.tensor(*args, dtype=ftype, device=device, **kargs).cuda(non_blocking=cuda_async) |
| dten = lambda *args, **kargs: torch.tensor(*args, dtype=dtype, device=device, **kargs).cuda(non_blocking=cuda_async) |
| lten = lambda *args, **kargs: torch.tensor(*args, dtype=ltype, device=device, **kargs).cuda(non_blocking=cuda_async) |
| bten = lambda *args, **kargs: torch.tensor(*args, dtype=btype, device=device, **kargs).cuda(non_blocking=cuda_async) |
| ones = lambda *args, **cargs: torch.ones(*args, **cargs).cuda(non_blocking=cuda_async) |
| zeros = lambda *args, **cargs: torch.zeros(*args, **cargs).cuda(non_blocking=cuda_async) |
| eye = lambda *args, **cargs: torch.eye(*args, **cargs).cuda(non_blocking=cuda_async) |
| use_cuda = True |
| print("set up cuda") |
| else: |
| print("not using cuda") |
| ften = ftenCPU |
| dten = dtenCPU |
| lten = ltenCPU |
| bten = btenCPU |
| ones = torch.ones |
| zeros = torch.zeros |
| eye = torch.eye |
| use_cuda = False |
| device = cpu |
|
|
| def smoothmax(x, alpha, dim = 0): |
| return x.mul(F.softmax(x * alpha, dim)).sum(dim + 1) |
|
|
|
|
| def str2bool(v): |
| if v.lower() in ('yes', 'true', 't', 'y', '1'): |
| return True |
| elif v.lower() in ('no', 'false', 'f', 'n', '0'): |
| return False |
| else: |
| raise argparse.ArgumentTypeError('Boolean value expected.') |
|
|
|
|
|
|
| def flat(lst): |
| lst_ = [] |
| for l in lst: |
| lst_ += l |
| return lst_ |
|
|
|
|
| def printBoth(*st, f = None): |
| print(*st) |
| if not f is None: |
| print(*st, file=f) |
|
|
|
|
| def hasMethod(cl, mt): |
| return callable(getattr(cl, mt, None)) |
|
|
| def getMethodNames(Foo): |
| return [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")] |
|
|
| def getMethods(Foo): |
| return [getattr(Foo, m) for m in getMethodNames(Foo)] |
|
|
| max_c_for_norm = 10000 |
|
|
| def numel(arr): |
| return product(arr.size()) |
|
|
| def chunks(l, n): |
| """Yield successive n-sized chunks from l.""" |
| for i in range(0, len(l), n): |
| yield l[i:i + n] |
|
|
|
|
| def loadDataset(dataset, batch_size, train, transform = True): |
| oargs = {} |
| if dataset in ["MNIST", "CIFAR10", "CIFAR100", "FashionMNIST", "PhotoTour"]: |
| oargs['train'] = train |
| elif dataset in ["STL10", "SVHN"] : |
| oargs['split'] = 'train' if train else 'test' |
| elif dataset in ["LSUN"]: |
| oargs['classes'] = 'train' if train else 'test' |
| elif dataset in ["Imagenet12"]: |
| pass |
| else: |
| raise Exception(dataset + " is not yet supported") |
|
|
| if dataset in ["MNIST"]: |
| transformer = transforms.Compose([ transforms.ToTensor()] |
| + ([transforms.Normalize((0.1307,), (0.3081,))] if transform else [])) |
| elif dataset in ["CIFAR10", "CIFAR100"]: |
| transformer = transforms.Compose(([ |
| transforms.RandomAffine(0, (0.125, 0.125), resample=PIL.Image.BICUBIC) , |
| transforms.RandomHorizontalFlip(), |
| |
| ] if train else []) |
| + [transforms.ToTensor()] |
| + ([transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))] if transform else [])) |
| elif dataset in ["SVHN"]: |
| transformer = transforms.Compose([ |
| transforms.RandomHorizontalFlip(), |
| transforms.ToTensor(), |
| transforms.Normalize((0.5,0.5,0.5), (0.2,0.2,0.2))]) |
| else: |
| transformer = transforms.ToTensor() |
|
|
| if dataset in ["Imagenet12"]: |
| |
| train_set = datasets.ImageFolder( |
| '../data/Imagenet12/train' if train else '../data/Imagenet12/val', |
| transforms.Compose([ |
| transforms.RandomResizedCrop(224), |
| transforms.RandomHorizontalFlip(), |
| normalize, |
| ])) |
| else: |
| train_set = getattr(datasets, dataset)('../data', download=True, transform=transformer, **oargs) |
| return torch.utils.data.DataLoader( |
| train_set |
| , batch_size=batch_size |
| , shuffle=True, |
| **({'num_workers': 1, 'pin_memory': True} if use_cuda else {})) |
|
|
|
|
| def variable(Pt): |
| class Point: |
| def isSafe(self,target): |
| pred = self.max(1, keepdim=True)[1] |
| return pred.eq(target.data.view_as(pred)) |
|
|
| def isPoint(self): |
| return True |
|
|
| def labels(self): |
| return [self[0].max(1)[1]] |
| |
| def softplus(self): |
| return F.softplus(self) |
|
|
| def elu(self): |
| return F.elu(self) |
|
|
| def selu(self): |
| return F.selu(self) |
|
|
| def sigm(self): |
| return F.sigmoid(self) |
| |
| def conv3d(self, *args, **kargs): |
| return F.conv3d(self, *args, **kargs) |
| def conv2d(self, *args, **kargs): |
| return F.conv2d(self, *args, **kargs) |
| def conv1d(self, *args, **kargs): |
| return F.conv1d(self, *args, **kargs) |
|
|
| def conv_transpose3d(self, *args, **kargs): |
| return F.conv_transpose3d(self, *args, **kargs) |
| def conv_transpose2d(self, *args, **kargs): |
| return F.conv_transpose2d(self, *args, **kargs) |
| def conv_transpose1d(self, *args, **kargs): |
| return F.conv_transpose1d(self, *args, **kargs) |
|
|
| def max_pool2d(self, *args, **kargs): |
| return F.max_pool2d(self, *args, **kargs) |
|
|
| def avg_pool2d(self, *args, **kargs): |
| return F.avg_pool2d(self, *args, **kargs) |
|
|
| def adaptive_avg_pool2d(self, *args, **kargs): |
| return F.adaptive_avg_pool2d(self, *args, **kargs) |
|
|
|
|
| def cat(self, other, dim = 0, **kargs): |
| return torch.cat((self, other), dim = dim, **kargs) |
|
|
| def addPar(self, a, b): |
| return a + b |
|
|
| def abstractApplyLeaf(self, foo, *args, **kargs): |
| return self |
| |
| def diameter(self): |
| return pyval(0) |
|
|
| def to_dtype(self): |
| return self.type(dtype=dtype, non_blocking=cuda_async) |
|
|
| def loss(self, target, **kargs): |
| if torch.__version__[0] == "0": |
| return F.cross_entropy(self, target, reduce = False) |
| else: |
| return F.cross_entropy(self, target, reduction='none') |
|
|
| def deep_loss(self, *args, **kargs): |
| return 0 |
|
|
| def merge(self, *args, **kargs): |
| return self |
|
|
| def splitRelu(self, *args, **kargs): |
| return self |
|
|
| def lb(self): |
| return self |
| def vanillaTensorPart(self): |
| return self |
| def center(self): |
| return self |
| def ub(self): |
| return self |
|
|
| def cudify(self, cuda_async = True): |
| return self.cuda(non_blocking=cuda_async) if use_cuda else self |
| |
| def log_softmax(self, *args, dim = 1, **kargs): |
| return F.log_softmax(self, *args,dim = dim, **kargs) |
|
|
| if torch.__version__[0] == "0" and torch.__version__ != "0.4.1": |
| Point.log_softmax = log_softmax |
|
|
|
|
| def log_softmax(self, *args, dim = 1, **kargs): |
| return F.log_softmax(self, *args,dim = dim, **kargs) |
|
|
| if torch.__version__[0] == "0" and torch.__version__ != "0.4.1": |
| Point.log_softmax = log_softmax |
|
|
| for nm in getMethodNames(Point): |
| curse(Pt, nm, getattr(Point, nm)) |
|
|
| variable(torch.autograd.Variable) |
| variable(torch.cuda.DoubleTensor) |
| variable(torch.DoubleTensor) |
| variable(torch.cuda.FloatTensor) |
| variable(torch.FloatTensor) |
| variable(torch.ByteTensor) |
| variable(torch.Tensor) |
|
|
|
|
| def default(dic, nm, d): |
| if dic is not None and nm in dic: |
| return dic[nm] |
| return d |
|
|
|
|
|
|
|
|
| def softmaxBatchNP(x, epsilon, subtract = False): |
| """Compute softmax values for each sets of scores in x.""" |
| x = x.astype(np.float64) |
| ex = x / epsilon if epsilon is not None else x |
| if subtract: |
| ex -= ex.max(axis=1)[:,np.newaxis] |
| e_x = np.exp(ex) |
| sm = (e_x / e_x.sum(axis=1)[:,np.newaxis]) |
| am = np.argmax(x, axis=1) |
| bads = np.logical_not(np.isfinite(sm.sum(axis = 1))) |
|
|
| if epsilon is None: |
| sm[bads] = 0 |
| sm[bads, am[bads]] = 1 |
| else: |
| epsilon *= (x.shape[1] - 1) / x.shape[1] |
| sm[bads] = epsilon / (x.shape[1] - 1) |
| sm[bads, am[bads]] = 1 - epsilon |
|
|
| sm /= sm.sum(axis=1)[:,np.newaxis] |
| return sm |
|
|
|
|
| def cadd(a,b): |
| both = a.cat(b) |
| a, b = both.split(a.size()[0]) |
| return a + b |
|
|
| def msum(a,b, l): |
| if a is None: |
| return b |
| if b is None: |
| return a |
| return l(a,b) |
|
|
| class SubAct(argparse.Action): |
| def __init__(self, sub_choices, *args, **kargs): |
| super(SubAct,self).__init__(*args, nargs='+', **kargs) |
| self.sub_choices = sub_choices |
| self.sub_choices_names = None if sub_choices is None else getMethodNames(sub_choices) |
|
|
| def __call__(self, parser, namespace, values, option_string=None): |
| if self.sub_choices_names is not None and not values[0] in self.sub_choices_names: |
| msg = 'invalid choice: %r (choose from %s)' % (values[0], self.sub_choices_names) |
| raise argparse.ArgumentError(self, msg) |
|
|
| prev = getattr(namespace, self.dest) |
| setattr(namespace, self.dest, prev + [values]) |
|
|
| def catLists(val): |
| if isinstance(val, list): |
| v = [] |
| for i in val: |
| v += catLists(i) |
| return v |
| return [val] |
|
|
| def sumStr(val): |
| s = "" |
| for v in val: |
| s += v |
| return s |
|
|
| def catStrs(val): |
| s = val[0] |
| if len(val) > 1: |
| s += "(" |
| for v in val[1:2]: |
| s += v |
| for v in val[2:]: |
| s += ", "+v |
| if len(val) > 1: |
| s += ")" |
| return s |
|
|
| def printNumpy(x): |
| return "[" + sumStr([decimal.Decimal(float(v)).__format__("f") + ", " for v in x.data.cpu().numpy()])[:-2]+"]" |
|
|
| def printStrList(x): |
| return "[" + sumStr(v + ", " for v in x)[:-2]+"]" |
|
|
| def printListsNumpy(val): |
| if isinstance(val, list): |
| return printStrList(printListsNumpy(v) for v in val) |
| return printNumpy(val) |
|
|
| def parseValues(values, methods, *others): |
| if len(values) == 1 and values[0]: |
| x = eval(values[0], dict(pair for l in ([methods] + list(others)) for pair in l.__dict__.items()) ) |
|
|
| return x() if inspect.isclass(x) else x |
| args = [] |
| kargs = {} |
| for arg in values[1:]: |
| if '=' in arg: |
| k = arg.split('=')[0] |
| v = arg[len(k)+1:] |
| try: |
| kargs[k] = eval(v) |
| except: |
| kargs[k] = v |
| else: |
| args += [eval(arg)] |
| return getattr(methods, values[0])(*args, **kargs) |
|
|
| def preDomRes(outDom, target): |
| t = one_hot(target.long(), outDom.size()[1]).to_dense().to_dtype() |
| tmat = t.unsqueeze(2).matmul(t.unsqueeze(1)) |
|
|
| tl = t.unsqueeze(2).expand(-1, -1, tmat.size()[1]) |
|
|
| inv_t = eye(tmat.size()[1]).expand(tmat.size()[0], -1, -1) |
| inv_t = inv_t - tmat |
|
|
| tl = tl.bmm(inv_t) |
|
|
| fst = outDom.unsqueeze(1).matmul(tl).squeeze(1) |
| snd = outDom.unsqueeze(1).matmul(inv_t).squeeze(1) |
| |
| return (fst - snd) + t |
|
|
| def mopen(shouldnt, *args, **kargs): |
| if shouldnt: |
| import contextlib |
| return contextlib.suppress() |
| return open(*args, **kargs) |
| |
| def file_timestamp(): |
| return str(datetime.now()).replace(":","").replace(" ", "") |
|
|
| def prepareDomainNameForFile(s): |
| return s.replace(" ", "_").replace(",", "").replace("(", "_").replace(")", "_").replace("=", "_") |
|
|
| |
| def callCC(foo): |
| class RV(BaseException): |
| def __init__(self, v): |
| self.v = v |
|
|
| def cc(x): |
| raise RV(x) |
|
|
| try: |
| return foo(cc) |
| except RV as rv: |
| return rv.v |
|
|