-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_codes.py
More file actions
52 lines (38 loc) · 1.54 KB
/
example_codes.py
File metadata and controls
52 lines (38 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# Example codes generated by KL minimization. Used to develop active learning methods
import numpy as np
import cvxpy as cp
from scipy.optimize import minimize, LinearConstraint
from scipy.stats import entropy
def min_kl_cvxpy(ps, Cs, C0, direction='forward', return_lagrange=False):
""" solve for KL optimal probability vector """
n = ps.shape[0]
qs = cp.Variable(n)
if direction == 'forward':
objective_fn = cp.sum(cp.rel_entr(ps, qs))
if direction == 'reverse':
objective_fn = cp.sum(cp.rel_entr(qs, ps))
constraints = [
cp.sum(qs) == 1,
qs @ Cs == C0
]
prob = cp.Problem(cp.Minimize(objective_fn), constraints)
optimal = prob.solve()
if optimal == float('inf') or optimal == -float('inf'):
raise Exception("Unsolved optimization")
if return_lagrange:
return qs.value, (constraints[0].dual_value, constraints[1].dual_value)
return qs.value
def min_kl_scipy(ps, Cs, C0, direction='forward'):
""" solve for KL optimal probability vector
scipy solvers don't seem to perform as well as cvxpy
"""
n = ps.shape[0]
if direction == 'forward':
to_minimize = lambda qs: entropy(ps, qs)
if direction == 'reverse':
to_minimize = lambda qs: entropy(qs, ps)
constraints = LinearConstraint([Cs, np.ones(n)], [C0, 1], [C0, 1])
initial_guess = np.ones(n) / n
res = minimize(to_minimize, initial_guess, method='trust-constr',
constraints=constraints)
return res