diffumatch / utils /utils_legacy.py
daidedou
first_try
458efe2
import sys
import os
import time
import torch
import hashlib
import numpy as np
import scipy
def read_lines(file_path):
with open(file_path, 'r') as fin:
lines = [line.strip() for line in fin.readlines() if len(line.strip()) > 0]
return lines
# == Pytorch things
def toNP(x):
"""
Really, definitely convert a torch tensor to a numpy array
"""
return x.detach().to(torch.device('cpu')).numpy()
def label_smoothing_log_loss(pred, labels, smoothing=0.0):
n_class = pred.shape[-1]
one_hot = torch.zeros_like(pred)
one_hot[labels] = 1.
one_hot = one_hot * (1 - smoothing) + (1 - one_hot) * smoothing / (n_class - 1)
loss = -(one_hot * pred).sum(dim=-1).mean()
return loss
# Randomly rotate points.
# Torch in, torch out
# Note fornow, builds rotation matrix on CPU.
def random_rotate_points(pts, randgen=None):
R = random_rotation_matrix(randgen)
R = torch.from_numpy(R).to(device=pts.device, dtype=pts.dtype)
return torch.matmul(pts, R)
def random_rotate_points_y(pts):
angles = torch.rand(1, device=pts.device, dtype=pts.dtype) * (2. * np.pi)
rot_mats = torch.zeros(3, 3, device=pts.device, dtype=pts.dtype)
rot_mats[0, 0] = torch.cos(angles)
rot_mats[0, 2] = torch.sin(angles)
rot_mats[2, 0] = -torch.sin(angles)
rot_mats[2, 2] = torch.cos(angles)
rot_mats[1, 1] = 1.
pts = torch.matmul(pts, rot_mats)
return pts
# Numpy things
# Numpy sparse matrix to pytorch
def sparse_np_to_torch(A):
Acoo = A.tocoo()
values = Acoo.data
indices = np.vstack((Acoo.row, Acoo.col))
shape = Acoo.shape
return torch.sparse_coo_tensor(torch.LongTensor(indices), torch.FloatTensor(values), torch.Size(shape), dtype=torch.float32).coalesce()
# Pytorch sparse to numpy csc matrix
def sparse_torch_to_np(A):
if len(A.shape) != 2:
raise RuntimeError("should be a matrix-shaped type; dim is : " + str(A.shape))
indices = toNP(A.indices())
values = toNP(A.values())
mat = scipy.sparse.coo_matrix((values, indices), shape=A.shape).tocsc()
return mat
# Hash a list of numpy arrays
def hash_arrays(arrs):
running_hash = hashlib.sha1()
for arr in arrs:
binarr = arr.view(np.uint8)
running_hash.update(binarr)
return running_hash.hexdigest()
def random_rotation_matrix(randgen=None):
"""
Creates a random rotation matrix.
randgen: if given, a np.random.RandomState instance used for random numbers (for reproducibility)
"""
# adapted from http://www.realtimerendering.com/resources/GraphicsGems/gemsiii/rand_rotation.c
if randgen is None:
randgen = np.random.RandomState()
theta, phi, z = tuple(randgen.rand(3).tolist())
theta = theta * 2.0 * np.pi # Rotation about the pole (Z).
phi = phi * 2.0 * np.pi # For direction of pole deflection.
z = z * 2.0 # For magnitude of pole deflection.
# Compute a vector V used for distributing points over the sphere
# via the reflection I - V Transpose(V). This formulation of V
# will guarantee that if x[1] and x[2] are uniformly distributed,
# the reflected points will be uniform on the sphere. Note that V
# has length sqrt(2) to eliminate the 2 in the Householder matrix.
r = np.sqrt(z)
Vx, Vy, Vz = V = (np.sin(phi) * r, np.cos(phi) * r, np.sqrt(2.0 - z))
st = np.sin(theta)
ct = np.cos(theta)
R = np.array(((ct, st, 0), (-st, ct, 0), (0, 0, 1)))
# Construct the rotation matrix ( V Transpose(V) - I ) R.
M = (np.outer(V, V) - np.eye(3)).dot(R)
return M
# Python string/file utilities
def ensure_dir_exists(d):
if not os.path.exists(d):
os.makedirs(d)