forked from optuna/optuna-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
skimage_lbp_simple.py
112 lines (83 loc) · 3.1 KB
/
skimage_lbp_simple.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
"""
Optuna example that optimizes a configuration for Olivetti faces dataset using
skimage.
In this example, we optimize a classifier configuration for Olivetti faces dataset.
We optimize parameters of local_binary_pattern function in skimage and the
choice of distance metric classes.
"""
import numpy as np
import optuna
import skimage.feature as ft
from sklearn.datasets import fetch_olivetti_faces
import sklearn.metrics
def load_data():
rng = np.random.RandomState(0)
dataset = fetch_olivetti_faces(shuffle=True, random_state=rng)
faces = dataset.images
target = dataset.target
classes = np.unique(target)
classes.sort()
ref_index = np.argmax(target == classes[:, None], axis=1)
valid_index = np.delete(np.arange(len(faces)), ref_index)
x_ref = faces[ref_index]
y_ref = target[ref_index]
x_valid = faces[valid_index]
y_valid = target[valid_index]
return x_ref, x_valid, y_ref, y_valid
def get_lbp_hist(img, P, R, method):
lbp = ft.local_binary_pattern(img, P, R, method)
if method == "uniform":
bin_max = P + 3
range_max = P + 2
elif method == "default":
bin_max = 2**P
range_max = 2**P - 1
hist, _ = np.histogram(
lbp.ravel(), density=True, bins=np.arange(0, bin_max), range=(0, range_max)
)
return hist
def img2hist(imgs, P, R, method):
hists = [get_lbp_hist(img, P, R, method) for img in imgs]
return np.array(hists)
def log2matrix(p):
return np.where(p != 0, np.log2(p), 0)
def calc_kl_dist(p, q):
dist = np.matmul(p * log2matrix(p), np.where(q != 0, 1, 0).T) - np.matmul(p, log2matrix(q).T)
return dist.T
def calc_euc_dist(p, q):
p_norm = np.diag(np.dot(p, p.T))
q_norm = np.vstack(np.diag(np.dot(q, q.T)))
dist = np.sqrt(-2 * np.matmul(q, p.T) + p_norm + q_norm)
return dist
def calc_cos_dist(p, q):
p_norm = np.diag(np.dot(p, p.T))
q_norm = np.vstack(np.diag(np.dot(q, q.T)))
dist = 1 - np.matmul(q, p.T) / (np.sqrt(p_norm) * np.sqrt(q_norm))
return dist
def calc_dist(p, q, metric):
if metric == "kl":
dist = calc_kl_dist(p, q)
elif metric == "cos":
dist = calc_cos_dist(p, q)
elif metric == "euc":
dist = calc_euc_dist(p, q)
return dist
def objective(trial):
# Get Olivetti faces dataset.
x_ref, x_valid, y_ref, y_valid = load_data()
# We optimize parameters of local_binary_pattern function in skimage
# and the choice of distance metric classes.
P = trial.suggest_int("P", 1, 15)
R = trial.suggest_float("R", 1, 10)
method = trial.suggest_categorical("method", ["default", "uniform"])
metric = trial.suggest_categorical("metric", ["kl", "cos", "euc"])
x_ref_hist = img2hist(x_ref, P, R, method)
x_valid_hist = img2hist(x_valid, P, R, method)
dist = calc_dist(x_ref_hist, x_valid_hist, metric)
y_pred = np.argmin(dist, axis=1)
accuracy = sklearn.metrics.accuracy_score(y_valid, y_pred)
return accuracy
if __name__ == "__main__":
study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=50, timeout=600)
print(study.best_trial)