Add a test showing how to implement scipy's 'soft_l1' loss in minimize.least_squares
PiperOrigin-RevId: 718649580 Change-Id: I5cec0e2850c805301407c9eb543ab3ba69d42e79
This commit is contained in:
committed by
Copybara-Service
parent
21d97902ee
commit
f9fd2e4ba4
@@ -292,6 +292,34 @@ class MinimizeTest(absltest.TestCase):
|
|||||||
check_derivatives=True,
|
check_derivatives=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_soft_l1_norm(self) -> None:
|
||||||
|
def residual(x):
|
||||||
|
return np.stack([1 - x[0, :], 10 * (x[1, :] - x[0, :] ** 2)])
|
||||||
|
|
||||||
|
class SoftL1(minimize.Norm):
|
||||||
|
"""Implementation of the loss called 'soft_l1' in scipy least_squares."""
|
||||||
|
|
||||||
|
def value(self, r):
|
||||||
|
return np.sum(np.sqrt(r**2 + 1) - 1)
|
||||||
|
|
||||||
|
def grad_hess(self, r, proj):
|
||||||
|
s = np.sqrt(r**2 + 1)
|
||||||
|
y_r = r / s
|
||||||
|
grad = proj.T @ y_r
|
||||||
|
y_rr = (1 - y_r ** 2) / s
|
||||||
|
hess = proj.T @ (y_rr * proj)
|
||||||
|
return grad, hess
|
||||||
|
|
||||||
|
out = io.StringIO()
|
||||||
|
x0 = np.array((0.0, 0.0))
|
||||||
|
x, _ = minimize.least_squares(
|
||||||
|
x0, residual, norm=SoftL1(), output=out, check_derivatives=True
|
||||||
|
)
|
||||||
|
expected_x = np.array((1.0, 1.0))
|
||||||
|
np.testing.assert_array_almost_equal(x, expected_x)
|
||||||
|
self.assertIn('User-provided norm gradient matches', out.getvalue())
|
||||||
|
self.assertIn('User-provided norm Hessian matches', out.getvalue())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
absltest.main()
|
absltest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user