-
Jon Almazan authoredJon Almazan authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
common.py 7.20 KiB
import os
import sys
import pdb
import shutil
from collections import OrderedDict
import numpy as np
import sklearn.decomposition
import torch
import torch.nn.functional as F
try:
import torch
import torch.nn as nn
except ImportError:
pass
def typename(x):
return type(x).__module__
def tonumpy(x):
if typename(x) == torch.__name__:
return x.cpu().numpy()
else:
return x
def matmul(A, B):
if typename(A) == np.__name__:
B = tonumpy(B)
scores = np.dot(A, B.T)
elif typename(B) == torch.__name__:
scores = torch.matmul(A, B.t()).cpu().numpy()
else:
raise TypeError("matrices must be either numpy or torch type")
return scores
def pool(x, pooling='mean', gemp=3):
if len(x) == 1:
return x[0]
x = torch.stack(x, dim=0)
if pooling == 'mean':
return torch.mean(x, dim=0)
elif pooling == 'gem':
def sympow(x, p, eps=1e-6):
s = torch.sign(x)
return (x*s).clamp(min=eps).pow(p) * s
x = sympow(x, gemp)
x = torch.mean(x, dim=0)
return sympow(x, 1/gemp)
else:
raise ValueError("Bad pooling mode: "+str(pooling))
def torch_set_gpu(gpus, seed=None, randomize=True):
if type(gpus) is int:
gpus = [gpus]
assert gpus, 'error: empty gpu list, use --gpu N N ...'
cuda = all(gpu >= 0 for gpu in gpus)
if cuda:
if any(gpu >= 1000 for gpu in gpus):
visible_gpus = [int(gpu) for gpu in os.environ['CUDA_VISIBLE_DEVICES'].split(',')]
os.environ['CUDA_VISIBLE_DEVICES'] = ','.join([str(visible_gpus[gpu-1000]) for gpu in gpus])
else:
os.environ['CUDA_VISIBLE_DEVICES'] = ','.join([str(gpu) for gpu in gpus])
assert cuda and torch.cuda.is_available(), "%s has GPUs %s unavailable" % (
os.environ['HOSTNAME'], os.environ['CUDA_VISIBLE_DEVICES'])
torch.backends.cudnn.benchmark = True
torch.backends.cudnn.fastest = True
print('Launching on GPUs ' + os.environ['CUDA_VISIBLE_DEVICES'])
else:
print('Launching on >> CPU <<')
torch_set_seed(seed, cuda, randomize=randomize)
return cuda
def torch_set_seed(seed, cuda, randomize=True):
if seed:
# this makes it 3x SLOWER but deterministic
torch.backends.cudnn.enabled = False
if randomize and not seed:
import time
seed = int(np.uint32(hash(time.time())))
if seed:
np.random.seed(seed)
torch.manual_seed(seed)
if cuda:
torch.cuda.manual_seed(seed)
def save_checkpoint(state, is_best, filename):
try:
dirs = os.path.split(filename)[0]
if not os.path.isdir(dirs):
os.makedirs(dirs)
torch.save(state, filename)
if is_best:
filenamebest = filename+'.best'
shutil.copyfile(filename, filenamebest)
filename = filenamebest
print("saving to "+filename)
except:
print("Error: Could not save checkpoint at %s, skipping" % filename)
def load_checkpoint(filename, iscuda=False):
if not filename:
return None
assert os.path.isfile(filename), "=> no checkpoint found at '%s'" % filename
checkpoint = torch.load(filename, map_location=lambda storage, loc: storage)
print("=> loading checkpoint '%s'" % filename, end='')
for key in ['epoch', 'iter', 'current_iter']:
if key in checkpoint:
print(" (%s %d)" % (key, checkpoint[key]), end='')
print()
new_dict = OrderedDict()
for k, v in list(checkpoint['state_dict'].items()):
if k.startswith('module.'):
k = k[7:]
new_dict[k] = v
checkpoint['state_dict'] = new_dict
if iscuda and 'optimizer' in checkpoint:
try:
for state in checkpoint['optimizer']['state'].values():
for k, v in state.items():
if iscuda and torch.is_tensor(v):
state[k] = v.cuda()
except RuntimeError as e:
print("RuntimeError:", e, "(machine %s, GPU %s)" % (
os.environ['HOSTNAME'], os.environ['CUDA_VISIBLE_DEVICES']),
file=sys.stderr)
sys.exit(1)
return checkpoint
def switch_model_to_cuda(model, iscuda=True, checkpoint=None):
if iscuda:
if checkpoint:
checkpoint['state_dict'] = {'module.' + k: v for k, v in checkpoint['state_dict'].items()}
try:
model = torch.nn.DataParallel(model)
# copy attributes automatically
for var in dir(model.module):
if var.startswith('_'):
continue
val = getattr(model.module, var)
if isinstance(val, (bool, int, float, str, dict)) or \
(callable(val) and var.startswith('get_')):
setattr(model, var, val)
model.cuda()
model.isasync = True
except RuntimeError as e:
print("RuntimeError:", e, "(machine %s, GPU %s)" % (
os.environ['HOSTNAME'], os.environ['CUDA_VISIBLE_DEVICES']),
file=sys.stderr)
sys.exit(1)
model.iscuda = iscuda
return model
def model_size(model):
''' Computes the number of parameters of the model
'''
size = 0
for weights in model.state_dict().values():
size += np.prod(weights.shape)
return size
def freeze_batch_norm(model, freeze=True, only_running=False):
model.freeze_bn = bool(freeze)
if not freeze:
return
for m in model.modules():
if isinstance(m, nn.BatchNorm2d):
# Eval mode freezes the running mean and std
m.eval()
for param in m.named_parameters():
if only_running:
# Weight and bias can be updated
param[1].requires_grad = True
else:
# Freeze the weight and bias
param[1].requires_grad = False
def variables(inputs, iscuda, not_on_gpu=[]):
''' convert several Tensors to cuda.Variables
Tensor whose index are in not_on_gpu stays on cpu.
'''
inputs_var = []
for i, x in enumerate(inputs):
if i not in not_on_gpu and not isinstance(x, (tuple, list)):
if iscuda:
x = x.cuda(non_blocking=True)
x = torch.autograd.Variable(x)
inputs_var.append(x)
return inputs_var
def transform(pca, X, whitenp=0.5, whitenv=None, whitenm=1.0, use_sklearn=True):
if use_sklearn:
# https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/decomposition/base.py#L99
if pca.mean_ is not None:
X = X - pca.mean_
X_transformed = np.dot(X, pca.components_[:whitenv].T)
if pca.whiten:
X_transformed /= whitenm * np.power(pca.explained_variance_[:whitenv], whitenp)
else:
X = X - pca['means']
X_transformed = np.dot(X, pca['W'])
return X_transformed
def whiten_features(X, pca, l2norm=True, whitenp=0.5, whitenv=None, whitenm=1.0, use_sklearn=True):
res = transform(pca, X, whitenp=whitenp, whitenv=whitenv, whitenm=whitenm, use_sklearn=use_sklearn)
if l2norm:
res = res / np.expand_dims(np.linalg.norm(res, axis=1), axis=1)
return res