wuxing0105's picture
Upload folder using huggingface_hub (part 2)
53ebf66 verified
Raw
History Blame Contribute Delete
3.11 kB
import os
import torch
from torch import nn
import numpy as np
def softmax(x):
"""
one dimensional softmax designed for numpy array
"""
e_x = np.exp(x)
out = e_x / e_x.sum()
return out
class Dynamic_Weight_Averaging():
def __init__(self,tasks,tau,init_weight):
"""
Dynamic Weight Averaging implementation
"""
# number of tasks
self.N = len(tasks)
# self.loss_list = np.array([loss_dict[t+'_loss'].detach().cpu().item() for t in tasks])
self.step = 0
self.omega = np.array([init_weight]*self.N ) # the weight , \omega_i(t)
self.tau = tau # † : a value to adjust the soft-max
def _magnitude_adjust(self):
"""
automatic adjustment of loss magnitude
"""
self.relative_magnitude = self.loss_list.min() / self.loss_list
def _update(self,loss_dict):
# update r with L_i(t-1)
self.step += 1
if self.step < 2:
self.loss_list = np.array([loss_dict[t+'_loss'].detach().cpu().item() for t in self.tasks])
return self.init_weight
else:
self._magnitude_adjust()
last_loss = self.loss_list
self.loss_list = np.array([loss_dict[t+'_loss'].detach().cpu().item() for t in self.tasks])
# computing DWA
r_t = np.divide(self.loss_list,last_loss) / self.tau
self.omega = self.N * softmax(r_t)
weight_t = np.multiply(self.relative_magnitude,self.omega)
return {self.tasks[i]:weight_t[i] for i in range(len(self.tasks))}
class Dynamic_Task_Priority(object):
def __init__(self,tasks,gamma,init_weight):
"""
Dynamic Task Priority (DTP) wish to weight more on tasks with lower KPI
In our cases, we take accuracy as the KPI
"""
self.gamma = np.array([gamma[t] for t in tasks]) if type(gamma) == dict else gamma # an adjustment param
self.tasks = tasks
# self.kappa = [loss_dict[t+'_Acc'] for t in tasks]
self.omega = init_weight
self.init_weight = init_weight
self.step = 0
def _magnitude_adjust(self):
"""
automatic adjustment of loss magnitude
"""
# TODO : test this effectiveness
self.relative_magnitude = self.kappa.min() / (self.kappa+1e-8)
if np.any(self.kappa==1):
self.kappa[np.where(self.kappa==1)[0]] -= 1e-8
def _update(self,loss_dict):
"""
weight is updated like belowing
`math` : w_i(t) = -(1-\kappa_i(t))^{\gamma_i} log \kappa_i(t)
"""
self.step += 1
self.kappa = np.array([loss_dict[t+'_Acc'] for t in self.tasks])
self._magnitude_adjust()
self.omega = -1 * np.multiply(np.power(1 - self.kappa,self.gamma),np.log(self.kappa+1e-8))
if self.step < 2:
return self.init_weight
else:
weight_t = np.multiply(self.relative_magnitude,self.omega)
return {self.tasks[i]:weight_t[i] for i in range(len(self.tasks))}