-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloss_function.py
executable file
·78 lines (58 loc) · 1.92 KB
/
loss_function.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
# -*-coding: utf-8 -*-
"""
Created on April 8, 2016
"""
import numpy
import scipy
from six import add_metaclass
from zope.interface import implementer, Interface
from mapped_object_registry import MappedObjectsRegistry
class ILossFunction(Interface):
def get_loss_grad():
"""
Calculates dE/dy, where E(y) - loss function, y - prediction
"""
def get_loss():
"""
Calculates average loss for one minibatch, given target and prediction
"""
class LossFunctionsRegistry(MappedObjectsRegistry):
mapping = "loss_functions"
@add_metaclass(LossFunctionsRegistry)
class BaseLossFunction(object):
epsilon = 1e-15
def __init__(self, target, prediction, **kwargs):
self.target = target
self.prediction = prediction
@implementer(ILossFunction)
class LogLossFunction(BaseLossFunction):
MAPPING = "log"
def get_loss(self):
prediction = scipy.maximum(self.epsilon, self.prediction)
prediction = scipy.minimum(1 - self.epsilon, prediction)
loss = sum(
self.target * scipy.log(prediction) +
scipy.subtract(1, self.target) *
scipy.log(scipy.subtract(1, prediction)))
loss = loss * - 1.0/self.target.shape[0]
return loss
def get_loss_grad(self):
# TODO: add get_loss_grad for log loss
pass
@implementer(ILossFunction)
class HingeLossFunction(BaseLossFunction):
MAPPING = "hinge"
"""
E(y) = max(0, 1 - t * y), t - target, y - prediction
"""
def get_loss(self):
loss = 0
count = self.target.shape[0]
for index in range(count):
loss += max(0, 1 - self.target[index] * self.prediction[index])
return loss / count
def get_loss_grad(self):
if numpy.dot(numpy.transpose(self.target), self.prediction)[0][0] >= 1:
return numpy.zeros_like(self.target)
else:
return - self.target