forked from lucasb-eyer/BiternionNet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
train_vgg_towncentre_old.py
119 lines (84 loc) · 4.25 KB
/
train_vgg_towncentre_old.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
import numpy as np
import pickle, gzip
import DeepFried2 as df
from lbtoolbox.thutil import count_params
from lbtoolbox.augmentation import AugmentationPipeline, Cropper
from training_utils import dotrain, dostats, dopred
from models.vgg_theano import mknet_cpu, mknet_gpu, Flatten
from utils.towncentre import split_dataset
def ensemble_degrees(angles):
return np.arctan2(np.mean(np.sin(np.deg2rad(angles)), axis=0), np.mean(np.cos(np.deg2rad(angles)), axis=0))
def dopred_deg(model, aug, X, batchsize=100):
return np.rad2deg(dopred(model, aug, X, ensembling=ensemble_degrees, output2preds=lambda x: x, batchsize=batchsize))
def maad_from_deg(preds, reals):
return np.rad2deg(np.abs(np.arctan2(np.sin(np.deg2rad(reals-preds)), np.cos(np.deg2rad(reals-preds)))))
def show_errs_deg(preds, reals, epoch=-1):
errs = maad_from_deg(preds, reals)
mean_errs = np.mean(errs, axis=1)
std_errs = np.std(errs, axis=1)
print("Error: {:5.2f}°±{:5.2f}°".format(np.mean(mean_errs), np.mean(std_errs)))
print("Stdev: {:5.2f}°±{:5.2f}°".format(np.std(mean_errs), np.std(std_errs)))
class VonMisesCriterion(df.Criterion):
def __init__(self, kappa, radians=True):
df.Criterion.__init__(self)
self.kappa = kappa
self.torad = 1 if radians else 0.0174532925
def symb_forward(self, symb_in, symb_tgt):
delta_rad = self.torad * (symb_in - symb_tgt)
C = np.exp(2*self.kappa)
return df.T.mean(C - df.T.exp(self.kappa * (1+df.T.cos(delta_rad))))
class Biternion(df.Module):
def symb_forward(self, symb_in):
return symb_in / df.T.sqrt((symb_in**2).sum(axis=1, keepdims=True))
def deg2bit(angles_deg):
angles_rad = np.deg2rad(angles_deg)
return np.array([np.cos(angles_rad), np.sin(angles_rad)]).T
def bit2deg(angles_bit):
return (np.rad2deg(np.arctan2(angles_bit[:,1], angles_bit[:,0])) + 360) % 360
class CosineCriterion(df.Criterion):
def symb_forward(self, symb_in, symb_tgt):
# For normalized `p_t_given_x` and `t`, dot-product (batched)
# outputs a cosine value, i.e. between -1 (worst) and 1 (best)
cos_angles = df.T.batched_dot(symb_in, symb_tgt)
# Rescale to a cost going from 2 (worst) to 0 (best) each, then take mean.
return df.T.mean(1 - cos_angles)
class VonMisesBiternionCriterion(df.Criterion):
def __init__(self, kappa):
df.Criterion.__init__(self)
self.kappa = kappa
def symb_forward(self, symb_in, symb_tgt):
cos_angles = df.T.batched_dot(symb_in, symb_tgt)
# This is the only difference to the pure `CosineCriterion`.
# Obviously, they could be in the same class, but I separate them here for narration.
cos_angles = df.T.exp(self.kappa * (cos_angles - 1))
return df.T.mean(1 - cos_angles)
def main():
X, y, n = pickle.load(gzip.open('data/TownCentre.pkl.gz', 'rb'))
(Xtr, ytr, ntr), (Xte, yte, nte) = split_dataset(X, y, n, split=0.9)
Xtr, ytr = Xtr.astype(df.floatX)/255, ytr.astype(df.floatX)
Xte, yte = Xte.astype(df.floatX)/255, yte.astype(df.floatX)
aug = AugmentationPipeline(Xtr, ytr, Cropper((46, 46)))
print("Trainset: {}".format(len(Xtr)))
print("Testset: {}".format(len(Xte)))
# Naive deep regression
# net = mknet_gpu(df.Linear(512, 1, initW=df.init.const(0)))
# dotrain(net, df.MADCriterion(), aug, Xtr, ytr[:, None])
# dostats(net, aug, Xtr, batchsize=1000)
# y_preds = np.squeeze(dopred_deg(net, aug, Xte))
# Biternion deep regression with cosine criterion
# net = mknet_gpu(df.Linear(512, 2, initW=df.init.normal(0.01)), Biternion())
# dotrain(net, CosineCriterion(), aug, Xtr, deg2bit(ytr))
# dostats(net, aug, Xtr, batchsize=1000)
# y_preds = bit2deg(np.squeeze(dopred_deg(net, aug, Xte)))
# Biternion deep regression with Von-Mises criterion
net = mknet_gpu(df.Linear(512, 2, initW=df.init.normal(0.01)), Biternion())
dotrain(net, VonMisesBiternionCriterion(1), aug, Xtr, deg2bit(ytr))
dostats(net, aug, Xtr, batchsize=1000)
y_preds = bit2deg(np.squeeze(dopred_deg(net, aug, Xte)))
loss = maad_from_deg(y_preds, yte)
mean_loss = np.mean(loss)
std_loss = np.std(loss)
print("MAAD error (test) : %f ± %f" % (mean_loss, std_loss))
return
if __name__ == '__main__':
main()