-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathSoftMaxLoss.h
114 lines (94 loc) · 3.04 KB
/
SoftMaxLoss.h
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
#ifndef _SOFTMAXLOSS_H_
#define _SOFTMAXLOSS_H_
#include "MyLib.h"
#include "Metric.h"
#include "Node.h"
class SoftMaxLoss {
public:
inline dtype loss(PNode x, const vector<dtype> &answer, Metric& eval, int batchsize = 1) {
int nDim = x->dim;
int labelsize = answer.size();
if (labelsize != nDim) {
std::cerr << "softmax_loss error: dim size invalid" << std::endl;
return -1.0;
}
NRVec<dtype> scores(nDim);
dtype cost = 0.0;
int optLabel = -1;
for (int i = 0; i < nDim; ++i) {
if (answer[i] >= 0) {
if (optLabel < 0 || x->val[i] > x->val[optLabel])
optLabel = i;
}
}
dtype sum1 = 0, sum2 = 0, maxScore = x->val[optLabel];
for (int i = 0; i < nDim; ++i) {
scores[i] = -1e10;
if (answer[i] >= 0) {
scores[i] = exp(x->val[i] - maxScore);
if (answer[i] == 1)
sum1 += scores[i];
sum2 += scores[i];
}
}
cost += (log(sum2) - log(sum1)) / batchsize;
if (answer[optLabel] == 1)
eval.correct_label_count++;
eval.overall_label_count++;
for (int i = 0; i < nDim; ++i) {
if (answer[i] >= 0) {
x->loss[i] = (scores[i] / sum2 - answer[i]) / batchsize;
}
}
return cost;
}
inline dtype predict(PNode x, int& y) {
int nDim = x->dim;
int optLabel = -1;
for (int i = 0; i < nDim; ++i) {
if (optLabel < 0 || x->val[i] > x->val[optLabel])
optLabel = i;
}
dtype prob = 0.0;
dtype sum = 0.0;
NRVec<dtype> scores(nDim);
dtype maxScore = x->val[optLabel];
for (int i = 0; i < nDim; ++i) {
scores[i] = exp(x->val[i] - maxScore);
sum += scores[i];
}
prob = scores[optLabel] / sum;
y = optLabel;
return prob;
}
inline dtype cost(PNode x, const vector<dtype> &answer, int batchsize = 1) {
int nDim = x->dim;
int labelsize = answer.size();
if (labelsize != nDim) {
std::cerr << "softmax_loss error: dim size invalid" << std::endl;
return -1.0;
}
NRVec<dtype> scores(nDim);
dtype cost = 0.0;
int optLabel = -1;
for (int i = 0; i < nDim; ++i) {
if (answer[i] >= 0) {
if (optLabel < 0 || x->val[i] > x->val[optLabel])
optLabel = i;
}
}
dtype sum1 = 0, sum2 = 0, maxScore = x->val[optLabel];
for (int i = 0; i < nDim; ++i) {
scores[i] = -1e10;
if (answer[i] >= 0) {
scores[i] = exp(x->val[i] - maxScore);
if (answer[i] == 1)
sum1 += scores[i];
sum2 += scores[i];
}
}
cost += (log(sum2) - log(sum1)) / batchsize;
return cost;
}
};
#endif /* _SOFTMAXLOSS_H_ */