shreyasvaidya's picture
Upload folder using huggingface_hub
01bb3bb verified
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import torch
import numpy as np
import cv2
import torch.nn as nn
from torch.autograd import Variable
def normalize_adj(A, type="AD"):
if type == "DAD":
A = A + np.eye(A.shape[0]) # A=A+I
d = np.sum(A, axis=0)
d_inv = np.power(d, -0.5).flatten()
d_inv[np.isinf(d_inv)] = 0.0
d_inv = np.diag(d_inv)
G = A.dot(d_inv).transpose().dot(d_inv) # L = D^-1/2 A D^-1/2
G = torch.from_numpy(G)
elif type == "AD":
A = A + np.eye(A.shape[0]) # A=A+I
A = torch.from_numpy(A)
D = A.sum(1, keepdim=True)
G = A.div(D) # L= A/D
else:
A = A + np.eye(A.shape[0]) # A=A+I
D = A.sum(1, keepdim=True)
D = np.diag(D)
G = torch.from_numpy(D - A) # L = D-A
return G
def np_to_variable(x, is_cuda=True, dtype=torch.FloatTensor):
v = Variable(torch.from_numpy(x).type(dtype))
if is_cuda:
v = v.cuda()
return v
def set_trainable(model, requires_grad):
for param in model.parameters():
param.requires_grad = requires_grad
def weights_normal_init(model, dev=0.01):
if isinstance(model, list):
for m in model:
weights_normal_init(m, dev)
else:
for m in model.modules():
if isinstance(m, nn.Conv2d):
m.weight.data.normal_(0.0, dev)
elif isinstance(m, nn.Linear):
m.weight.data.normal_(0.0, dev)
def clip_gradient(model, clip_norm):
"""Computes a gradient clipping coefficient based on gradient norm."""
totalnorm = 0
for p in model.parameters():
if p.requires_grad:
modulenorm = p.grad.data.norm()
totalnorm += modulenorm ** 2
totalnorm = np.sqrt(totalnorm)
norm = clip_norm / max(totalnorm, clip_norm)
for p in model.parameters():
if p.requires_grad:
p.grad.mul_(norm)
def EuclideanDistances(A, B):
BT = B.transpose()
vecProd = np.dot(A,BT)
SqA = A**2
sumSqA = np.matrix(np.sum(SqA, axis=1))
sumSqAEx = np.tile(sumSqA.transpose(), (1, vecProd.shape[1]))
SqB = B**2
sumSqB = np.sum(SqB, axis=1)
sumSqBEx = np.tile(sumSqB, (vecProd.shape[0], 1))
SqED = sumSqBEx + sumSqAEx - 2*vecProd
SqED[SqED<0]=0.0
ED = np.sqrt(SqED)
return ED
def get_center_feature(cnn_feature, img_poly, ind, h, w):
batch_size = cnn_feature.size(0)
for i in range(batch_size):
poly = img_poly[ind == i].cpu().numpy()
mask = np.zeros((h, w), dtype=np.uint8)
cv2.fillPoly(mask, poly.astype(np.int32), color=(1,))
return None
def get_node_feature(cnn_feature, img_poly, ind, h, w):
img_poly = img_poly.clone().float()
img_poly[..., 0] = img_poly[..., 0] / (w / 2.) - 1
img_poly[..., 1] = img_poly[..., 1] / (h / 2.) - 1
batch_size = cnn_feature.size(0)
gcn_feature = torch.zeros([img_poly.size(0), cnn_feature.size(1), img_poly.size(1)]).to(img_poly.device)
for i in range(batch_size):
poly = img_poly[ind == i].unsqueeze(0)
gcn_feature[ind == i] = torch.nn.functional.grid_sample(cnn_feature[i:i + 1], poly)[0].permute(1, 0, 2)
return gcn_feature
def get_adj_mat(n_adj, n_nodes):
a = np.zeros([n_nodes, n_nodes], dtype=np.float)
for i in range(n_nodes):
for j in range(-n_adj // 2, n_adj // 2 + 1):
if j != 0:
a[i][(i + j) % n_nodes] = 1
a[(i + j) % n_nodes][i] = 1
return a
def get_adj_ind(n_adj, n_nodes, device):
ind = torch.tensor([i for i in range(-n_adj // 2, n_adj // 2 + 1) if i != 0]).long()
ind = (torch.arange(n_nodes)[:, None] + ind[None]) % n_nodes
return ind.to(device)
def coord_embedding(b, w, h, device):
x_range = torch.linspace(0, 1, w, device=device)
y_range = torch.linspace(0, 1, h, device=device)
y, x = torch.meshgrid(y_range, x_range)
y = y.expand([b, 1, -1, -1])
x = x.expand([b, 1, -1, -1])
coord_map = torch.cat([x, y], 1)
return coord_map
def img_poly_to_can_poly(img_poly):
if len(img_poly) == 0:
return torch.zeros_like(img_poly)
x_min = torch.min(img_poly[..., 0], dim=-1)[0]
y_min = torch.min(img_poly[..., 1], dim=-1)[0]
can_poly = img_poly.clone()
can_poly[..., 0] = can_poly[..., 0] - x_min[..., None]
can_poly[..., 1] = can_poly[..., 1] - y_min[..., None]
# x_max = torch.max(img_poly[..., 0], dim=-1)[0]
# y_max = torch.max(img_poly[..., 1], dim=-1)[0]
# h, w = y_max - y_min + 1, x_max - x_min + 1
# long_side = torch.max(h, w)
# can_poly = can_poly / long_side[..., None, None]
return can_poly