def compute_curvature_dmat_sub(dmat,N,idx): K = [] for i in idx: L0 = dmat[N[i][:,0],i]**2 L1 = dmat[N[i][:,1],i]**2 D = dmat[N[i][:,0],N[i][:,1]]**2 c1 = (L0+L1-D)/(2*F.sqrt(L0*L1)) arg = 2*np.pi-F.sum(F.arccos(c1)) K.append(arg) return(K)
def loss(self, logits, labels): xp = chainer.cuda.get_array_module(logits) # add margin z = 1 - 1e-6 theta = F.arccos(F.clip(logits, -z, z)) target_logits = F.cos(theta + self.m) one_hot = xp.eye(self.class_num)[labels] output = logits * (1 - one_hot) + target_logits * one_hot # feature re-scale output *= self.s loss = F.softmax_cross_entropy(output, labels) return loss
def compute_curvature(vert,face,xp): # Obsolite: replaced with compute_curvature_sub which is more efficient K = Variable(xp.full((len(vert),), 2*xp.pi)) for f in face: n = len(f) id_p = xp.array([f[(i-1)%n] for i in range(n+1)]) id = xp.array([f[i%n] for i in range(n+1)]) id_n = xp.array([f[(i+1)%n] for i in range(n)]) L = F.sum((vert[id_p] - vert[id])**2, axis=1) D = F.sum((vert[id_n] - vert[ id_p[:-1] ])**2, axis=1) c1 = (L[:n]+L[1:]-D)/(2*F.sqrt(L[:n]*L[1:])) K = F.scatter_add(K,f,-F.arccos(c1)) return K
def loss(self, logits, labels): xp = chainer.cuda.get_array_module(logits) # add margin z = 1 - 1e-6 theta = F.arccos(F.clip(logits, -z, z)) one_hot = xp.eye(self.class_num)[labels] B_avg = xp.where(one_hot < 1, xp.clip(xp.exp(self.s * logits.data), -z, z), xp.zeros_like(logits.data)) B_avg = xp.sum(B_avg) / logits.shape[0] theta_med = xp.asarray(np.median(to_cpu(theta.data[one_hot == 1]))) self.s = math.log(B_avg) / math.cos(min([math.pi/4, theta_med])) output = self.s * logits loss = F.softmax_cross_entropy(output, labels) return loss
def compute_curvature_sub(vert,N,idx,force_upward=False,verbose=False): K = [] for i in idx: L0 = F.sum((vert[N[i][:,0]] - vert[i])**2, axis=1) L1 = F.sum((vert[N[i][:,1]] - vert[i])**2, axis=1) D = F.sum((vert[N[i][:,1]] - vert[N[i][:,0]])**2, axis=1) c1 = (L0+L1-D)/(2*F.sqrt(L0*L1)) arg = 2*np.pi-F.sum(F.arccos(c1)) if force_upward: up = F.sum(vert[i]-vert[N[i][:,0]],axis=0) fn = [0,0,0] for k in range(len(N[i])): q = cross(vert[N[i][k,1]] - vert[i], vert[N[i][k,0]] - vert[i]) fn[0] += q[0] fn[1] += q[1] fn[2] += q[2] s = F.sign(inprod(fn,up)) if verbose and s.array<0: print(i,s) arg *= F.sign(inprod(fn,up)) K.append(arg) return(K)
def arccos(self, x): return F.arccos(x)
def forward(self, x): y1 = F.arccos(x) return y1
def forward(self, *args, **kwargs): if 'train' in kwargs.keys(): self.train = kwargs['train'] del kwargs['train'] if 'epoch' in kwargs.keys(): if self.target_epoch is not None: self.margin = kwargs[ 'epoch'] / self.target_epoch * self.final_margin self.scale = 1 + kwargs['epoch'] / self.target_epoch * ( self.final_scale - 1) del kwargs['epoch'] if isinstance(self.label_key, int): if not (-len(args) <= self.label_key < len(args)): msg = 'Label key %d is out of bounds' % self.label_key raise ValueError(msg) t = args[self.label_key] if self.label_key == -1: args = args[:-1] else: args = args[:self.label_key] + args[self.label_key + 1:] elif isinstance(self.label_key, str): if self.label_key not in kwargs: msg = 'Label key "%s" is not found' % self.label_key raise ValueError(msg) t = kwargs[self.label_key] del kwargs[self.label_key] self.y = None self.hidden_feature = None self.loss = None self.accuracy = None self.hidden_feature = self.predictor(*args, **kwargs) self.y = self.cosine_similarity(self.hidden_feature) if self.train: xp = chainer.backend.cuda.get_array_module(self.y) if self.method == 'sphereface': penalty = xp.zeros_like(self.y) rows = xp.arange(t.size) penalty[rows, t] = (F.cos(F.arccos(self.y[rows, t]) * self.margin) - self.y[rows, t]).data self.y += penalty elif self.method == 'arcface': penalty = xp.zeros_like(self.y) rows = xp.arange(t.size) penalty[rows, t] = (F.cos(F.arccos(self.y[rows, t]) + self.margin) - self.y[rows, t]).data self.y += penalty elif self.method == 'cosface': self.y[xp.arange(t.size), t] -= self.margin else: raise NotImplementedError self.y *= self.scale self.loss = self.lossfun(self.y, t) reporter.report({'loss': self.loss}, self) if self.compute_accuracy: self.accuracy = self.accfun(self.y, t) reporter.report({'accuracy': self.accuracy}, self) return self.loss