[fb2ce2]: / src / custom_loss.py

Download this file

84 lines (58 with data), 2.6 kB

 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
# Loss functions taken/inspired from Akensert's kaggle kernel
import numpy as np
import tensorflow as tf
from tensorflow import keras as K
def weighted_log_loss(y_true, y_pred):
"""
Can be used as the loss function in model.compile()
---------------------------------------------------
"""
# class_weights = np.array([1., 1., 1., 1., 1., 2.])
class_weights = np.array([1.])
eps = K.backend.epsilon()
y_pred = K.backend.clip(y_pred, eps, 1.0-eps)
out = -( y_true * K.backend.log( y_pred) * class_weights
+ (1.0 - y_true) * K.backend.log(1.0 - y_pred) * class_weights)
return K.backend.mean(out, axis=-1)
def _normalized_weighted_average(arr, weights=None):
"""
A simple Keras implementation that mimics that of
numpy.average(), specifically for the this competition
"""
if weights is not None:
scl = K.backend.sum(weights)
weights = K.backend.expand_dims(weights, axis=1)
return K.backend.sum(K.backend.dot(arr, weights), axis=1) / scl
return K.backend.mean(arr, axis=1)
def weighted_loss(y_true, y_pred):
"""
Will be used as the metric in model.compile()
---------------------------------------------
Similar to the custom loss function 'weighted_log_loss()' above
but with normalized weights, which should be very similar
to the official competition metric:
https://www.kaggle.com/kambarakun/lb-probe-weights-n-of-positives-scoring
and hence:
sklearn.metrics.log_loss with sample weights
"""
# class_weights = K.backend.variable([1., 1., 1., 1., 1. ,2.])
class_weights = K.backend.variable([1.])
eps = K.backend.epsilon()
y_pred = K.backend.clip(y_pred, eps, 1.0-eps)
loss = -( y_true * K.backend.log( y_pred)
+ (1.0 - y_true) * K.backend.log(1.0 - y_pred))
loss_samples = _normalized_weighted_average(loss, class_weights)
return K.backend.mean(loss_samples)
def weighted_log_loss_metric(trues, preds):
"""
Will be used to calculate the log loss
of the validation set in PredictionCheckpoint()
------------------------------------------
"""
# class_weights = [1., 1., 1., 1., 1., 2.]
class_weights = [1.]
epsilon = 1e-7
preds = np.clip(preds, epsilon, 1-epsilon)
loss = trues * np.log(preds) + (1 - trues) * np.log(1 - preds)
loss_samples = np.average(loss, axis=1, weights=class_weights)
return - loss_samples.mean()