-
-
Notifications
You must be signed in to change notification settings - Fork 601
/
Copy pathLossFunction.jl
122 lines (102 loc) · 2.81 KB
/
LossFunction.jl
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
120
121
122
function sigmoid(x)
return 1./(1+exp.(-x))
end
abstract type LossFunction end
type SquareLoss <: LossFunction
obj::Function
gradient::Function
function obj(y::Array, y_pred::Array)
return 0.5 * sum(abs2, y - y_pred)
end
function gradient(y::Array, y_pred::Array)
return (y_pred - y)
end
function SquareLoss()
loss = new(obj, gradient)
return loss
end
end
type AbsLoss <: LossFunction
obj::Function
gradient::Function
function obj(y::Array, y_pred::Array)
return sum(abs, y - y_pred)
end
function gradient(y::Array, y_pred::Array)
return sign.(y_pred - y)
end
function AbsLoss()
loss = new(obj, gradient)
return loss
end
end
type HuberLoss <: LossFunction
obj::Function
gradient::Function
function obj(y::Array, y_pred::Array; alpha::Float64 = 0.2)
delta = quantile(abs.(y-y_pred), alpha)
res = ones(size(y, 1))
for i=1:size(y,1)
if (abs(y[i]-y_pred[i]) < delta)
res[i] = abs2(y[i]-y_pred[i])
else
res[i] = 2*delta*abs(y[i]-y_pred[i])-abs2(delta)
end
end
return sum(res)
end
function gradient(y::Array, y_pred::Array; alpha::Float64=0.2)
delta = quantile(abs.(y-y_pred), alpha)
res = ones(size(y, 1))
for i = 1:size(y, 1)
if (abs(y[i]-y_pred[i]) < delta)
res[i] = y_pred[i]-y[i]
else
res[i] = delta*sign(y_pred[i]-y[i])
end
end
return res
end
function HuberLoss()
loss = new(obj, gradient)
return loss
end
end
type LogisticLoss <: LossFunction
obj::Function
gradient::Function
function obj(y::Array, y_pred::Array)
logistic_pred = sigmoid(y_pred)
l = - y .* log.(logistic_pred)
r = - (1-y) .* log.(1-logistic_pred)
loss = sum(l+r)
return loss
end
function gradient(y::Array, y_pred::Array)
p = sigmoid(y_pred)
return (p - y)./(p.*(1-p))
end
function LogisticLoss()
loss = new(obj, gradient)
return loss
end
end
## test
x = randn(3)
y = randn(3)
println("## square loss")
s = SquareLoss()
sg = s.gradient(x, y)
@printf("val = %.6f; gradient = [%.6f, %.6f, %.6f]\n", s.obj(x, y), sg[1], sg[2], sg[3])
println("## abs loss")
a = AbsLoss()
ag = a.gradient(x, y)
@printf("val = %.6f; gradient = [%.6f, %.6f, %.6f]\n", a.obj(x, y), ag[1], ag[2], ag[3])
println("## huber loss")
h = HuberLoss()
hg = h.gradient(x, y)
@printf("val = %.6f; gradient = [%.6f, %.6f, %.6f]\n", h.obj(x, y), hg[1], hg[2], hg[3])
println("## logit loss")
l = LogisticLoss()
lg = l.gradient(x, y)
@printf("val = %.6f; gradient = [%.6f, %.6f, %.6f]\n", l.obj(x, y), lg[1], lg[2], lg[3])