-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrun_synthmix.py
156 lines (127 loc) · 4.9 KB
/
run_synthmix.py
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
from mixclass import MixClass
from synthmix import SynthMix
from endmember_class import spec_lib
from unmix import inftyNorm_unmix, FCLS_unmix, LASSO_unmix, pNorm_unmix
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import random
import copy
import os
import datetime
now = datetime.datetime.now()
# experiment parameters
seed = 1
K = 1000
sigma = 2.5e-4
min_endmemb = 0.01
thresh = 0.01
run_FCLS = True
run_infty = True
run_LASSO = True
run_pnorm = True
# algorithm hyperparameters
lam_LASSO = 1e-6
lam_infty = 3e-6
lam_pnorm = 1e-2
p = 0.999
# start from a random seed
np.random.seed(seed)
random.seed(seed)
# Define metrics, computed for all algorithms using this function
def Metrics(x, mixture, mixture_noisy, em_spec, idx_pos_truth):
x_presence = np.zeros(x.shape)
x_presence[np.nonzero(x >= thresh)] = 1
precision = sum(mixture.presence[idx_pos_truth] == x_presence[idx_pos_truth]) / sum(x_presence)
recall = sum(mixture.presence[idx_pos_truth] == x_presence[idx_pos_truth]) / sum(mixture.presence)
metrics = {"RMS_noisy": ((1.0 / N) * sum((mixture_noisy.spectra - em_spec @ x) ** 2)).item(),
"RMS_true": ((1.0 / N) * sum((mixture.spectra - em_spec@x) ** 2)).item(),
"Error_L1": (sum(abs((x - mixture.proportions.transpose())))).item(),
"Error_L2": np.sqrt(sum((x - mixture.proportions.transpose()) ** 2)).item(),
"accuracy": sum(mixture.presence == x_presence) / len(mixture.presence),
"precision": precision,
"recall": recall}
return metrics
# save metrics
def saveListOfDicts(metrics, name, result_path, today, i):
"""
:param metrics: list[dict1, dict2, ...]
:param method: string, name of method
:return:
"""
metrics = pd.DataFrame(metrics)
print(name)
print(metrics.mean())
metrics.to_csv(result_path + today + "_%s%s.csv" % (name, i))
#import endmembers
endmembs = spec_lib("asu",
ascii_spectra="input/endmemb_libs/rogers_tes73.txt",
meta_csv="input/endmemb_libs/rogers_meta.csv")
# initialize some objects
synth = SynthMix(thresh=min_endmemb)
metrics_FCLS = []
metrics_inftyNorm = []
metrics_LASSO = []
metrics_pnorm = []
N = endmembs.spectra.shape[0] # number of spectral channels
M = endmembs.spectra.shape[1] # number of endmembers
# iterate over K mixtures
for i in range(K):
# create synthetic mixture
mixture = synth.mars_mix(endmembs)
idx_pos_truth = np.nonzero(mixture.presence > 0)[0]
idx_neg_truth = np.nonzero(mixture.presence == 0)[0]
mixture_noisy = mixture.perturb(method="gauss", deviation=sigma)
if run_infty:
# SFCLS prediction
x = inftyNorm_unmix(endmembs.spectra, mixture_noisy.spectra, lam=lam_infty)
metrics_inftyNorm.append(Metrics(x, mixture, mixture_noisy, endmembs.spectra, idx_pos_truth))
if run_FCLS:
# FCLS prediction
x = FCLS_unmix(endmembs.spectra, mixture_noisy.spectra)
metrics_FCLS.append(Metrics(x, mixture, mixture_noisy, endmembs.spectra, idx_pos_truth))
if run_LASSO:
# LASSO prediction
x = LASSO_unmix(endmembs.spectra, mixture_noisy.spectra, lam=lam_LASSO)
x = x/sum(x)
metrics_LASSO.append(Metrics(x, mixture, mixture_noisy, endmembs.spectra, idx_pos_truth))
if run_pnorm:
# p-norm prediction
x = pNorm_unmix(endmembs.spectra, mixture_noisy.spectra, lam=lam_pnorm, p=p)
metrics_pnorm.append(Metrics(x, mixture, mixture_noisy, endmembs.spectra, idx_pos_truth))
# create directory for today's date
today = now.strftime("%Y-%m-%d")
todays_results = "results/" + today
try:
os.mkdir(todays_results)
except OSError:
print("Creation of the directory %s failed" % todays_results)
else:
print("Successfully created the directory %s " % todays_results)
result_path = todays_results + "/"
# create experiment index
i = 0
while os.path.exists(result_path + today + "_params%d.csv" % i):
i += 1
# store experiment parameters to export with results
experiment_params = [{"seed": seed,
"K": K,
"sigma": sigma,
"min_endmemb": min_endmemb,
"thresh": thresh,
"run_FCLS": run_infty,
"run_LASSO": run_LASSO,
"run_pnorm": run_pnorm,
"lam_LASSO": lam_LASSO,
"lam_pnorm": lam_pnorm,
"p": p}]
saveListOfDicts(experiment_params, "synthmix_params", result_path, today, i)
# save results of experiments
if run_infty:
saveListOfDicts(metrics_inftyNorm, "synthmix_infty", result_path, today, i)
if run_FCLS:
saveListOfDicts(metrics_FCLS, "synthmix_FCLS", result_path, today, i)
if run_LASSO:
saveListOfDicts(metrics_LASSO, "synthmix_LASSO", result_path, today, i)
if run_pnorm:
saveListOfDicts(metrics_pnorm, "synthmix_pnorm", result_path, today, i)