Skip to content

Commit 86bef58

Browse files
committed
distribution matching
1 parent f074a0c commit 86bef58

File tree

15 files changed

+94
-95
lines changed

15 files changed

+94
-95
lines changed

libmoon/gan_tester/mooGAN.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
import os
77
import numpy as np
88

9-
109
def plot_figure(folder_name, generated_samples, sample1, sample2, pref):
1110
plt.scatter(generated_samples[:, 0], generated_samples[:, 1], label='Generated', s=50)
1211
plt.scatter(sample1[:, 0], sample1[:, 1], label='Sample 1', s=25, alpha=0.5)
1312
plt.scatter(sample2[:, 0], sample2[:, 1], label='Sample 2', s=25, alpha=0.5)
1413
if abs(pref[0]) < 1e-6:
1514
plt.legend(fontsize=20, loc='lower right')
16-
1715
plt.xlabel('$X_1$', fontsize=25)
1816
plt.ylabel('$X_2$', fontsize=25)
1917
plt.xticks(fontsize=20)

libmoon/gan_tester/prefgan.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import numpy as np
88
from torch.distributions.dirichlet import Dirichlet
99

10+
11+
1012
def plot_figure(folder_name, generated_samples, sample1, sample2, pref):
1113
plt.scatter(generated_samples[:, 0], generated_samples[:, 1], label='Generated', s=50)
1214
plt.scatter(sample1[:, 0], sample1[:, 1], label='Sample 1', s=25, alpha=0.5)

libmoon/model/policy_model.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import torch
22
from torch import nn
3-
43
import torch
54
import torch.nn as nn
65

7-
86
class Policy(nn.Module):
97
def __init__(self, state_space, action_space):
108
super(Policy, self).__init__()
@@ -27,7 +25,6 @@ def forward(self, state, stochastic=True):
2725

2826
# Convert logits to probabilities using a softmax function
2927
probabilities = torch.softmax(logits, dim=-1)
30-
3128
if stochastic:
3229
# Sample an action according to the action probabilities
3330
action = torch.multinomial(probabilities, num_samples=1)

libmoon/model/simple.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import torch
22
from torch import nn
33

4-
54
class SimplePSLModel(nn.Module):
65
def __init__(self, problem):
76
super().__init__()
@@ -45,8 +44,6 @@ def forward(self, pref):
4544
return mid
4645

4746

48-
49-
5047
class PFLModel(nn.Module):
5148
def __init__(self, n_obj):
5249
super(PFLModel, self).__init__()

libmoon/problem/synthetic/distribution.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,30 @@ def __init__(self, mu_arr=None, Sigma_arr=None):
1212
self.n_var = len(self.mu_arr[0])
1313
self.problem_name = "MOKL"
1414

15-
def _evaluate_torch(self, prefs: torch.Tensor):
15+
16+
def _evaluate_torch(self, prefs_arr: torch.Tensor):
1617
# prefs are the coefficients.
17-
mu_arr_arr = [p * mu for p, mu in zip(prefs, self.mu_arr)]
18-
Sigma_arr_arr = [p * Sigma for p, Sigma in zip(prefs, self.Sigma_arr)]
19-
mu = torch.sum( torch.stack(mu_arr_arr), axis=0)
20-
Sigma = torch.sum( torch.stack(Sigma_arr_arr), axis=0)
21-
22-
f_arr = []
23-
for obj_idx in range(self.n_obj):
24-
mu_i = self.mu_arr[obj_idx]
25-
Sigma_i = self.Sigma_arr[obj_idx]
26-
27-
term1 = torch.log(torch.det(Sigma_i)) - torch.log(torch.det(Sigma_i))
28-
term2 = (mu - mu_i) @ torch.inverse(Sigma_i) @ (mu - mu_i)
29-
term3 = torch.trace(torch.inverse(Sigma_i) @ Sigma)
30-
fi = 0.5 * (term1 + term2 + term3 - self.n_var)
31-
f_arr.append(fi)
32-
return torch.stack(f_arr)
18+
f_arr_all = []
19+
for prefs in prefs_arr:
20+
Sigma_inverse_arr_arr = [p * torch.inverse(Sigma_) for p, Sigma_ in zip(prefs, self.Sigma_arr)]
21+
Sigma = torch.inverse(torch.sum( torch.stack(Sigma_inverse_arr_arr), axis=0))
22+
23+
mu_arr_arr = [p * torch.inverse(Sigma_) @ mu
24+
for p, mu, Sigma_ in zip(prefs, self.mu_arr, self.Sigma_arr)]
25+
mu = Sigma @ torch.sum( torch.stack(mu_arr_arr), axis=0)
26+
f_arr = []
27+
28+
for obj_idx in range(self.n_obj):
29+
mu_i = self.mu_arr[obj_idx]
30+
Sigma_i = self.Sigma_arr[obj_idx]
31+
term1 = torch.log(torch.det(Sigma_i)) - torch.log(torch.det(Sigma))
32+
term2 = (mu - mu_i) @ torch.inverse(Sigma_i) @ (mu - mu_i)
33+
term3 = torch.trace(torch.inverse(Sigma_i) @ Sigma)
34+
fi = 0.5 * (term1 + term2 + term3 - self.n_var)
35+
f_arr.append(fi)
36+
f_arr = torch.stack(f_arr)
37+
f_arr_all.append(f_arr)
38+
return torch.stack(f_arr_all)
3339

3440

3541
if __name__ == '__main__':

libmoon/problem/synthetic/re_problem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from libmoon.problem.synthetic.mop import BaseMOP
55
from numpy import array
66

7+
78
class RE21(BaseMOP):
89
def __init__(self, n_var=4, n_obj=2, lbound=np.zeros(4), ubound=np.ones(4)):
910
self.problem_name = 'RE21'
@@ -25,7 +26,6 @@ def __init__(self, n_var=4, n_obj=2, lbound=np.zeros(4), ubound=np.ones(4)):
2526

2627
def _evaluate_numpy(self, x):
2728
n_sub = len(x)
28-
2929
x1 = x[:,0]
3030
x2 = x[:,1]
3131
x3 = x[:,2]

libmoon/problem/synthetic/reinforcement.py

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,3 @@
1-
# from libmoon.solver.gradient.methods.base_solver import GradAggSolver
2-
# from libmoon.solver.gradient.methods.mgda_solver import MGDAUBSolver
3-
# from libmoon.solver.gradient.methods.gradhv import GradHVSolver
4-
# from libmoon.solver.gradient.methods.pmtl import PMTLSolver
5-
# from libmoon.solver.gradient.methods.epo_solver import EPOSolver
6-
# from libmoon.solver.gradient.methods.moosvgd import MOOSVGDSolver
7-
# from libmoon.solver.gradient.methods.pmgda_solver import PMGDASolver
8-
# from libmoon.solver.gradient.methods.uniform_solver import UniformSolver
9-
# from libmoon.solver.gradient.methods.core.core_solver_bk import CoreAgg, CoreMGDA, CoreEPO, CoreMOOSVGD, CoreHVGrad
10-
# def get_core_solver(args, pref=None):
11-
# if args.solver == 'agg':
12-
# return CoreAgg(pref=pref, agg_mtd=args.agg_mtd)
13-
# elif args.solver == 'mgda':
14-
# return CoreMGDA()
15-
# elif args.solver == 'epo':
16-
# return CoreEPO(pref=pref)
17-
# elif args.solver == 'moosvgd':
18-
# return CoreMOOSVGD(args=args)
19-
# elif args.solver == 'hvgrad':
20-
# return CoreHVGrad(args=args)
21-
# else:
22-
# assert False, 'not implemented'
23-
24-
251
from libmoon.solver.gradient.methods.mgda_solver import MGDAUBSolver
262
from libmoon.solver.gradient.methods.epo_solver import EPOSolver
273
from libmoon.solver.gradient.methods.random_solver import RandomSolver

libmoon/solver/gradient/methods/base_solver.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from libmoon.metrics.metrics import compute_lmin
1313
from torch import Tensor
1414
criterion = torch.nn.MSELoss()
15+
from tqdm import tqdm
1516

1617
def umod_train_pfl_model(folder_name, update_idx, pfl_model, pfl_optimizer,
1718
criterion, prefs, y, pfl_epoch=2000):
@@ -94,15 +95,19 @@ def solve(self, problem, x, prefs):
9495
self.pfl_optimizer = torch.optim.Adam(self.pfl_model.parameters(), lr=1e-3)
9596

9697
self.n_prob, self.n_obj = prefs.shape[0], prefs.shape[1]
97-
9898
xs_var = Variable(x, requires_grad=True)
9999
optimizer = Adam([xs_var], lr=self.step_size)
100-
ind = HV( ref_point=get_hv_ref(problem.problem_name) )
100+
ind = HV(ref_point=get_hv_ref(problem.problem_name))
101101
hv_arr, y_arr = [], []
102+
102103
# For UMOD solver, we need to store (pref, y) pairs.
103104
pref_y_pairs = []
105+
if self.verbose:
106+
iteration_container = tqdm(range(self.epoch))
107+
else:
108+
iteration_container = range(self.epoch)
104109

105-
for epoch_idx in range(self.epoch):
110+
for epoch_idx in iteration_container:
106111
fs_var = problem.evaluate(xs_var)
107112
y_np = fs_var.detach().numpy()
108113
y_arr.append(y_np)
@@ -134,10 +139,19 @@ def solve(self, problem, x, prefs):
134139
torch.sum(alpha_array * fs_var).backward()
135140

136141
optimizer.step()
142+
143+
144+
137145
if 'lbound' in dir(problem):
138146
x.data = torch.clamp(x.data, torch.Tensor(problem.lbound) + solution_eps,
139147
torch.Tensor(problem.ubound) - solution_eps)
140148

149+
if problem.problem_name in ['MOKL']:
150+
x.data = torch.clamp(x.data, min=0)
151+
x.data = x.data / torch.sum(x.data, dim=1, keepdim=True)
152+
# print('x.data', x.data)
153+
# assert False
154+
141155
if self.solver_name == 'UMOD':
142156
if epoch_idx % self.pfl_train_epoch == 0 and epoch_idx != 0:
143157
pref_y_pairs.append((prefs, y_np))

libmoon/solver/gradient/methods/epo_solver.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@
22
import cvxpy as cp
33
import cvxopt
44
from libmoon.solver.gradient.methods.base_solver import GradBaseSolver
5-
from torch.autograd import Variable
6-
from tqdm import tqdm
75
import torch
8-
from torch.optim import SGD
9-
from numpy import array
10-
from pymoo.indicators.hv import HV
116
import warnings
127
warnings.filterwarnings("ignore")
13-
from libmoon.util.constant import solution_eps, get_hv_ref
14-
from libmoon.util.gradient import get_moo_Jacobian
158
from libmoon.problem.synthetic.zdt import ZDT1
169
from matplotlib import pyplot as plt
1710

1811

19-
2012
class EPO_LP(object):
21-
# Paper: https://proceedings.mlr.press/v119/mahapatra20a.html, https://arxiv.org/abs/2010.06313
13+
# Paper:
14+
# https://proceedings.mlr.press/v119/mahapatra20a.html,
15+
# https://arxiv.org/abs/2010.06313
2216
def __init__(self, m, n, r, eps=1e-4):
2317
cvxopt.glpk.options["msg_lev"] = "GLP_MSG_OFF"
2418
self.m = m

0 commit comments

Comments
 (0)