< Tensorflow > How to implement the larget margin softmax loss in tensorflow.

There is my implementation of the Large Margin Softmax Loss in TF.

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

MARGIN = 4
c_m_n = lambda m, n: math.factorial(n) / math.factorial(m) / math.factorial(n-m)
c_map = []
for i in range(MARGIN+1):
c_map.append(c_m_n(i, MARGIN))

def find_k_multi(cos_t):

cos_t = tf.cast(cos_t, dtype = tf.float64)
i = tf.constant(0, dtype = tf.float64)

def l_cond(i):
tf_pi = tf.constant(math.pi ,tf.float64)
left_range = tf.cast(tf.cos(tf_pi*(i+1)/MARGIN), dtype = tf.float64)
right_range = tf.cast(tf.cos(tf_pi*i/MARGIN), dtype = tf.float64)
logic = tf.logical_or(tf.greater(cos_t, right_range), tf.less(cos_t, left_range))

return logic
def l_body(i):
return tf.add(i, 1)
k = tf.while_loop(l_cond, l_body, [i])
k = tf.cast(k, dtype = tf.int32)
return k, k

def L_softmax(feature, labels, softmax_w, softmax_b , batch_size, labmda = 100):

f_feature = []
l_softmax_loss = []
c_v = []
o_v = []
for sample_index in range(batch_size):

sample_feature = tf.slice(feature, [sample_index, 0], [1, 512])
label = tf.squeeze(tf.slice(labels, [sample_index],[1]))


label = tf.cast(label, tf.int32)
w_label = tf.slice(softmax_w, [0, label], [512, 1])
b_label = tf.squeeze(tf.slice(softmax_b, [label], [1]))

wx = tf.squeeze(tf.matmul(sample_feature, w_label))

w_label_mod = tf.sqrt(2 * tf.nn.l2_loss(w_label))
b_label_mod = tf.sqrt(2 * tf.nn.l2_loss(tf.squeeze(b_label)))
sample_feature_mod = tf.sqrt(2 * tf.nn.l2_loss(tf.squeeze(sample_feature)))

cos_theta = wx/(w_label_mod * sample_feature_mod)

sin_theta_t = 1 - cos_theta * cos_theta

cos_m_theta = 0
flag = -1
for loop in range(int(MARGIN/2) + 1):
flag *= -1
cos_m_theta += flag * c_map[2 * loop] * tf.pow(cos_theta, MARGIN - 2 *loop) * tf.pow(sin_theta_t, loop)

k, log = find_k_multi(cos_theta)
phi_theta = tf.to_float(tf.pow(tf.constant(-1), k)) * cos_m_theta - 2 * tf.to_float(k)
label_value = (labmda * (w_label_mod * sample_feature_mod * cos_theta + b_label_mod) + \
(w_label_mod * sample_feature_mod * phi_theta + b_label_mod))/(1.0 + labmda)


# label_value = tf.to_float(tf.pow(-1, k)) * w_label_mod * sample_feature_mod * cos_m_theta - \
# 2 * tf.to_float(k) * w_label_mod * sample_feature_mod


other_value = tf.squeeze(tf.matmul(sample_feature, softmax_w) + softmax_b)
old_value = tf.slice(other_value, [label], [1])
to_substract_1 = tf.sparse_to_dense(label, other_value.get_shape(), old_value, default_value=0.)
to_substract_2 = tf.sparse_to_dense(label, other_value.get_shape(), label_value, default_value=0.)

l_feature = other_value - to_substract_1 + to_substract_2
f_feature.append(l_feature)

c_v.append(cos_theta)
o_v.append(k)

out_value = [c_v, o_v]
all_batch_feature = tf.stack(f_feature)
return all_batch_feature, out_value

< Tensorflow > How to implement the larget margin softmax loss in tensorflow.

https://zhengtq.github.io/2018/12/30/tf-lsoftmax/

Author

Billy

Posted on

2018-12-30

Updated on

2021-03-13

Licensed under

Comments