1+ import tensorflow as tf
2+ from tensorflow .python .ops import array_ops
3+
4+ slim = tf .contrib .slim
5+
6+ def focal_loss (onehot_labels , cls_preds ,
7+ alpha = 0.25 , gamma = 2.0 , name = None , scope = None ):
8+ """Compute softmax focal loss between logits and onehot labels
9+ logits and onehot_labels must have same shape [batchsize, num_classes] and
10+ the same data type (float16, 32, 64)
11+ Args:
12+ onehot_labels: Each row labels[i] must be a valid probability distribution
13+ cls_preds: Unscaled log probabilities
14+ alpha: The hyperparameter for adjusting biased samples, default is 0.25
15+ gamma: The hyperparameter for penalizing the easy labeled samples
16+ name: A name for the operation (optional)
17+ Returns:
18+ A 1-D tensor of length batch_size of same type as logits with softmax focal loss
19+ """
20+ with tf .name_scope (scope , 'focal_loss' , [cls_preds , onehot_labels ]) as sc :
21+ logits = tf .convert_to_tensor (cls_preds )
22+ onehot_labels = tf .convert_to_tensor (onehot_labels )
23+
24+ precise_logits = tf .cast (logits , tf .float32 ) if (
25+ logits .dtype == tf .float16 ) else logits
26+ onehot_labels = tf .cast (onehot_labels , precise_logits .dtype )
27+ predictions = tf .nn .sigmoid (logits )
28+ predictions_pt = tf .where (tf .equal (onehot_labels , 1 ), predictions , 1. - predictions )
29+ # add small value to avoid 0
30+ epsilon = 1e-8
31+ alpha_t = tf .scalar_mul (alpha , tf .ones_like (onehot_labels , dtype = tf .float32 ))
32+ alpha_t = tf .where (tf .equal (onehot_labels , 1.0 ), alpha_t , 1 - alpha_t )
33+ losses = tf .reduce_sum (- alpha_t * tf .pow (1. - predictions_pt , gamma ) * onehot_labels * tf .log (predictions_pt + epsilon ),
34+ name = name , axis = 1 )
35+ return losses
36+
37+
38+ def focal_loss2 (prediction_tensor , target_tensor , weights = None , alpha = 0.25 , gamma = 2 ):
39+ r"""Compute focal loss for predictions.
40+ Multi-labels Focal loss formula:
41+ FL = -alpha * (z-p)^gamma * log(p) -(1-alpha) * p^gamma * log(1-p)
42+ ,which alpha = 0.25, gamma = 2, p = sigmoid(x), z = target_tensor.
43+ Args:
44+ prediction_tensor: A float tensor of shape [batch_size, num_anchors,
45+ num_classes] representing the predicted logits for each class
46+ target_tensor: A float tensor of shape [batch_size, num_anchors,
47+ num_classes] representing one-hot encoded classification targets
48+ weights: A float tensor of shape [batch_size, num_anchors]
49+ alpha: A scalar tensor for focal loss alpha hyper-parameter
50+ gamma: A scalar tensor for focal loss gamma hyper-parameter
51+ Returns:
52+ loss: A (scalar) tensor representing the value of the loss function
53+ """
54+ sigmoid_p = tf .nn .sigmoid (prediction_tensor )
55+ zeros = array_ops .zeros_like (sigmoid_p , dtype = sigmoid_p .dtype )
56+ pos_p_sub = array_ops .where (target_tensor >= sigmoid_p , target_tensor - sigmoid_p , zeros )
57+ neg_p_sub = array_ops .where (target_tensor > zeros , zeros , sigmoid_p )
58+ per_entry_cross_ent = - alpha * (pos_p_sub ** gamma ) * tf .log (tf .clip_by_value (sigmoid_p , 1e-8 , 1.0 )) \
59+ - (1 - alpha ) * (neg_p_sub ** gamma ) * tf .log (tf .clip_by_value (1.0 - sigmoid_p , 1e-8 , 1.0 ))
60+ return tf .reduce_mean (per_entry_cross_ent , axis = 1 )
61+
62+
63+ def focal_loss3 (cls_score , label , num_classes ):
64+ alpha_scale = 0.25
65+ gamma = 2
66+ epsilon = 1e-8
67+ label = tf .one_hot (label , depth = num_classes )
68+ cls_pred = tf .nn .sigmoid (cls_score )
69+ predictions_pt = tf .where (tf .equal (label , 1 ), cls_pred , 1 - cls_pred )
70+ alpha_t = tf .ones_like (label , dtype = tf .float32 )
71+ alpha_t = tf .scalar_mul (alpha_scale , alpha_t )
72+ alpha_t = tf .where (tf .equal (label , 1.0 ), alpha_t , 1. - alpha_t )
73+ losses = tf .reduce_mean (- alpha_t * tf .pow (1 - predictions_pt , gamma ) * tf .log (predictions_pt + epsilon ), axis = 1 )
74+ return losses
75+
76+
77+ def regression_loss (pred_boxes , gt_boxes , weights ):
78+ """
79+ Regression loss (Smooth L1 loss: also known as huber loss)
80+ Args:
81+ pred_boxes: [# anchors, 4]
82+ gt_boxes: [# anchors, 4]
83+ weights: Tensor of weights multiplied by loss with shape [# anchors]
84+ """
85+ loss = tf .losses .huber_loss (predictions = pred_boxes , labels = gt_boxes ,
86+ weights = weights , scope = 'box_loss' )
87+ return loss
88+
89+
90+ def test ():
91+ logits = tf .convert_to_tensor ([[0.2 , 0.3 , 0.4 , 0.5 ], [0.5 , 0.4 , 0.3 , 0.2 ]])
92+ logits_sigmoid = tf .nn .sigmoid (logits )
93+ labels = slim .one_hot_encoding ([1 , 2 ], 4 )
94+ labels_vector = tf .constant ([1 , 2 ])
95+ bbox = tf .ones_like (logits )
96+ with tf .Session () as sess :
97+ print (sess .run (logits ))
98+ print (sess .run (logits_sigmoid ))
99+ print (sess .run (focal_loss (onehot_labels = labels , cls_preds = logits )))
100+ print (sess .run (focal_loss2 (target_tensor = labels , prediction_tensor = logits )))
101+ print (sess .run (focal_loss3 (cls_score = logits , label = labels_vector , num_classes = 4 )))
102+ print (sess .run (regression_loss (logits , bbox , tf .expand_dims (1. / tf .convert_to_tensor ([2 , 3 ], dtype = tf .float32 ), 1 ))))
103+ sess .close ()
104+
105+ test ()
0 commit comments