def train(self, environments, args, reg=0): n = environments[0][0].size(1) dim_x = environments[0][0].size(1) # self.phi = torch.nn.Parameter(torch.rand(dim_x, 1)) self.phi = torch.nn.Parameter(EmpiricalRiskMinimizer(environments, args).solution().view(dim_x, 1)) opt = torch.optim.Adam([self.phi], lr=args["lr"]) loss = torch.nn.MSELoss() for iteration in range(args["n_iterations"]): opt.zero_grad() error = torch.zeros(1) pen_mrg = torch.zeros(1) grad = [] for i, (x_e, y_e) in enumerate(environments): error_e = loss(x_e @ self.phi, y_e) #print('er', self.phi, error_e) grad_e = torch.autograd.grad(error_e, self.phi, retain_graph=True)[0] grad.append(grad_e) error += error_e grad = torch.cat(grad, dim=1) m = grad.mean(dim=1) p = grad.var(dim=1) # / (m * m + 1e-3) p_sum = (self.phi * self.phi * p).sum() #print(grad) assert not torch.isnan(p_sum).any() error_t = (1-self.alpha) * error + self.alpha * p_sum grad_p = torch.autograd.grad(p_sum, self.phi, retain_graph=True)[0] grad_ee = torch.autograd.grad(error, self.phi, retain_graph=True)[0] # print(error) error_t.backward() opt.step() if args["verbose"] and iteration % 1000 == 0: err_flt = (1-self.alpha) * float(error.detach()) p_flt = self.alpha * float(p_sum.detach()) w_str = pretty(self.solution()) p_str = pretty(p) print("{:05d} | {:.5f} | {:.5f} | {} | {}".format(iteration, err_flt, p_flt, w_str, p_str)) print('GRAD error', - grad) print('P', - p) print('uncentered', - grad.pow(2).sum(dim=1)) print('GRAD penalty', - grad_p) print('GRAD EE', - grad_ee) print(f'phi grad {pretty(self.phi.grad)}') print(f'm {pretty(m)} v {pretty(p)}')
def penalty(label, y): scale = torch.tensor(1.).cuda().requires_grad_() # loss = mean_nll(logits * scale, y) # real_traj = label * scale # fake_traj = y # loss_trajectory_x = trajectory_criterion(real_traj.view(opt.batch_size, 16,2)[:,:,0]*opt.max_dist, fake_traj.view(opt.batch_size, 16,2)[:,:,0]*opt.max_dist) # loss_trajectory_y = trajectory_criterion(real_traj.view(opt.batch_size, 16,2)[:,:,1]*opt.max_dist, fake_traj.view(opt.batch_size, 16,2)[:,:,1]*opt.max_dist) # loss_trajectory = (loss_trajectory_x + 5*loss_trajectory_y)#/2 # loss = loss_trajectory loss = trajectory_criterion(label * opt.max_dist, y * scale * opt.max_dist) grad = torch.autograd.grad(loss, [scale], create_graph=True)[0] return torch.sqrt(grad.pow(2).mean())
def compute_gradient_norm(output: Tensor, model: Module): """ Compute the norm of the gradient of an output (e.g a loss) with respect to a model parameters :param output: :param model: :return: """ ret = 0 output.backward(retain_graph=True) for parameter in model.parameters(): grad = parameter.grad ret += grad.pow(2).sum().cpu().detach().numpy() parameter.grad = None # Reset gradient accumulation return ret
def grad_penalty(loss, net): total_grad = 0 for param in net.parameters(): grad = torch.autograd.grad(loss, [param], create_graph=True)[0] total_grad += grad.pow(2).mean() return total_grad
def cal_norm_grad(grad_params): grad_norm = 0 for grad in grad_params: grad_norm += grad.pow(2).sum() grad_norm = grad_norm.sqrt() return grad_norm