-
Notifications
You must be signed in to change notification settings - Fork 178
/
skimage_lbp_simple.py
99 lines (74 loc) · 2.77 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
"""
Optuna example that optimizes a configuration for hand-written digits dataset using
skimage.
In this example, we optimize a classifier configuration for hand-written digits 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 load_digits
import sklearn.metrics
from sklearn.metrics.pairwise import cosine_distances
from sklearn.metrics.pairwise import euclidean_distances
def load_data():
dataset = load_digits()
digits = dataset.images.astype(np.uint8)
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(digits)), ref_index)
x_ref = digits[ref_index]
y_ref = target[ref_index]
x_valid = digits[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
def calc_dist(p, q, metric):
if metric == "kl":
dist = calc_kl_dist(p, q)
elif metric == "cos":
dist = cosine_distances(p, q)
elif metric == "euc":
dist = euclidean_distances(p, q)
return dist
def objective(trial):
# Get digits dataset.
x_ref, x_valid, _, 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=0)
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)