10000 MNT Cleaner cythn cdef loss function in SGD (#17191) · scikit-learn/scikit-learn@4b92a77 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4b92a77

Browse files
author
Christian Lorentzen
authored
MNT Cleaner cythn cdef loss function in SGD (#17191)
1 parent d40d993 commit 4b92a77

File tree

4 files changed

+31
-29
lines changed

4 files changed

+31
-29
lines changed

sklearn/linear_model/_sag_fast.pyx.tp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ cdef class MultinomialLogLoss{{name}}:
152152
loss = (logsumexp_prediction - prediction[int(y)]) * sample_weight
153153
return loss
154154

155-
cdef void _dloss(self, {{c_type}}* prediction, {{c_type}} y, int n_classes,
155+
cdef void dloss(self, {{c_type}}* prediction, {{c_type}} y, int n_classes,
156156
{{c_type}} sample_weight, {{c_type}}* gradient_ptr) nogil:
157157
r"""Multinomial Logistic regression gradient of the loss.
158158

@@ -419,10 +419,10 @@ def sag{{name}}(SequentialDataset{{name}} dataset,
419419

420420
# compute the gradient for this sample, given the prediction
421421
if multinomial:
422-
multiloss._dloss(prediction, y, n_classes, sample_weight,
422+
multiloss.dloss(prediction, y, n_classes, sample_weight,
423423
gradient)
424424
else:
425-
gradient[0] = loss._dloss(prediction[0], y) * sample_weight
425+
gradient[0] = loss.dloss(prediction[0], y) * sample_weight
426426

427427
# L2 regularization by simply rescaling the weights
428428
wscale *= wscale_update
@@ -783,7 +783,7 @@ def _multinomial_grad_loss_all_samples(
783783
intercept, prediction, n_classes)
784784

785785
# compute the gradient for this sample, given the prediction
786-
multiloss._dloss(prediction, y, n_classes, sample_weight, gradient)
786+
multiloss.dloss(prediction, y, n_classes, sample_weight, gradient)
787787

788788
# compute the loss for this sample, given the prediction
789789
sum_loss += multiloss._loss(prediction, y, n_classes, sample_weight)

sklearn/linear_model/_sgd_fast.pxd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33

44
cdef class LossFunction:
55
cdef double loss(self, double p, double y) nogil
6-
cdef double _dloss(self, double p, double y) nogil
6+
cdef double dloss(self, double p, double y) nogil
77

88

99
cdef class Regression(LossFunction):
1010
cdef double loss(self, double p, double y) nogil
11-
cdef double _dloss(self, double p, double y) nogil
11+
cdef double dloss(self, double p, double y) nogil
1212

1313

1414
cdef class Classification(LossFunction):
1515
cdef double loss(self, double p, double y) nogil
16-
cdef double _dloss(self, double p, double y) nogil
16+
cdef double dloss(self, double p, double y) nogil
1717

1818

1919
cdef class Log(Classification):
2020
cdef double loss(self, double p, double y) nogil
21-
cdef double _dloss(self, double p, double y) nogil
21+
cdef double dloss(self, double p, double y) nogil
2222

2323

2424
cdef class SquaredLoss(Regression):
2525
cdef double loss(self, double p, double y) nogil
26-
cdef double _dloss(self, double p, double y) nogil
26+
cdef double dloss(self, double p, double y) nogil

sklearn/linear_model/_sgd_fast.pyx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ cdef class LossFunction:
6666
"""
6767
return 0.
6868

69-
def dloss(self, double p, double y):
69+
def py_dloss(self, double p, double y):
70+
"""Python version of `dloss` for testing.
71+
72+
Pytest needs a python function and can't use cdef functions.
73+
"""
74+
return self.dloss(p, y)
75+
76+
cdef double dloss(self, double p, double y) nogil:
7077
"""Evaluate the derivative of the loss function with respect to
7178
the prediction `p`.
7279
@@ -81,11 +88,6 @@ cdef class LossFunction:
8188
double
8289
The derivative of the loss function with regards to `p`.
8390
"""
84-
return self._dloss(p, y)
85-
86-
cdef double _dloss(self, double p, double y) nogil:
87-
# Implementation of dloss; separate function because cpdef and nogil
88-
# can't be combined.
8991
return 0.
9092

9193

@@ -95,7 +97,7 @@ cdef class Regression(LossFunction):
9597
cdef double loss(self, double p, double y) nogil:
9698
return 0.
9799

98-
cdef double _dloss(self, double p, double y) nogil:
100+
cdef double dloss(self, double p, double y) nogil:
99101
return 0.
100102

101103

@@ -105,7 +107,7 @@ cdef class Classification(LossFunction):
105107
cdef double loss(self, double p, double y) nogil:
106108
return 0.
107109

108-
cdef double _dloss(self, double p, double y) nogil:
110+
cdef double dloss(self, double p, double y) nogil:
109111
return 0.
110112

111113

@@ -126,7 +128,7 @@ cdef class ModifiedHuber(Classification):
126128
else:
127129
return -4.0 * z
128130

129-
cdef double _dloss(self, double p, double y) nogil:
131+
cdef double dloss(self, double p, double y) nogil:
130132
cdef double z = p * y
131133
if z >= 1.0:
132134
return 0.0
@@ -161,7 +163,7 @@ cdef class Hinge(Classification):
161163
return self.threshold - z
162164
return 0.0
163165

164-
cdef double _dloss(self, double p, double y) nogil:
166+
cdef double dloss(self, double p, double y) nogil:
165167
cdef double z = p * y
166168
if z <= self.threshold:
167169
return -y
@@ -193,7 +195,7 @@ cdef class SquaredHinge(Classification):
193195
return z * z
194196
return 0.0
195197

196-
cdef double _dloss(self, double p, double y) nogil:
198+
cdef double dloss(self, double p, double y) nogil:
197199
cdef double z = self.threshold - p * y
198200
if z > 0:
199201
return -2 * y * z
@@ -215,7 +217,7 @@ cdef class Log(Classification):
215217
return -z
216218
return log(1.0 + exp(-z))
217219

218-
cdef double _dloss(self, double p, double y) nogil:
220+
cdef double dloss(self, double p, double y) nogil:
219221
cdef double z = p * y
220222
# approximately equal and saves the computation of the log
221223
if z > 18.0:
@@ -233,7 +235,7 @@ cdef class SquaredLoss(Regression):
233235
cdef double loss(self, double p, double y) nogil:
234236
return 0.5 * (p - y) * (p - y)
235237

236-
cdef double _dloss(self, double p, double y) nogil:
238+
cdef double dloss(self, double p, double y) nogil:
237239
return p - y
238240

239241
def __reduce__(self):
@@ -262,7 +264,7 @@ cdef class Huber(Regression):
262264
else:
263265
return self.c * abs_r - (0.5 * self.c * self.c)
264266

265-
cdef double _dloss(self, double p, double y) nogil:
267+
cdef double dloss(self, double p, double y) nogil:
266268
cdef double r = p - y
267269
cdef double abs_r = fabs(r)
268270
if abs_r <= self.c:
@@ -291,7 +293,7 @@ cdef class EpsilonInsensitive(Regression):
291293
cdef double ret = fabs(y - p) - self.epsilon
292294
return ret if ret > 0 else 0
293295

294-
cdef double _dloss(self, double p, double y) nogil:
296+
cdef double dloss(self, double p, double y) nogil:
295297
if y - p > self.epsilon:
296298
return -1
297299
elif p - y > self.epsilon:
@@ -318,7 +320,7 @@ cdef class SquaredEpsilonInsensitive(Regression):
318320
cdef double ret = fabs(y - p) - self.epsilon
319321
return ret * ret if ret > 0 else 0
320322

321-
cdef double _dloss(self, double p, double y) nogil:
323+
cdef double dloss(self, double p, double y) nogil:
322324
cdef double z
323325
z = y - p
324326
if z > self.epsilon:
@@ -542,7 +544,7 @@ def _plain_sgd(np.ndarray[double, ndim=1, mode='c'] weights,
542544
update = sqnorm(x_data_ptr, x_ind_ptr, xnnz)
543545
update = loss.loss(p, y) / (update + 0.5 / C)
544546
else:
545-
dloss = loss._dloss(p, y)
547+
dloss = loss.dloss(p, y)
546548
# clip dloss with large values to avoid numerical
547549
# instabilities
548550
if dloss < -MAX_DLOSS:

sklearn/linear_model/tests/test_sgd.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,7 @@ def _test_gradient_common(loss_function, cases):
14381438
# Test gradient of different loss functions
14391439
# cases is a list of (p, y, expected)
14401440
for p, y, expected in cases:
1441-
assert_almost_equal(loss_function.dloss(p, y), expected)
1441+
assert_almost_equal(loss_function.py_dloss(p, y), expected)
14421442

14431443

14441444
def test_gradient_hinge():
@@ -1488,8 +1488,8 @@ def test_gradient_log():
14881488
(17.9, -1.0, 1.0), (-17.9, 1.0, -1.0),
14891489
]
14901490
_test_gradient_common(loss, cases)
1491-
assert_almost_equal(loss.dloss(18.1, 1.0), np.exp(-18.1) * -1.0, 16)
1492-
assert_almost_equal(loss.dloss(-18.1, -1.0), np.exp(-18.1) * 1.0, 16)
1491+
assert_almost_equal(loss.py_dloss(18.1, 1.0), np.exp(-18.1) * -1.0, 16)
1492+
assert_almost_equal(loss.py_dloss(-18.1, -1.0), np.exp(-18.1) * 1.0, 16)
14931493

14941494

14951495
def test_gradient_squared_loss():

0 commit comments

Comments
 (0)
0