def test_ProxTV(self): """...Test of ProxTV """ coeffs = self.coeffs.copy().astype(self.dtype) l_tv = 0.5 t = 1.7 out = np.array([ -0.40102846, -0.40102846, -0.40102846, -0.31364696, -0.31364696, 1.03937619, 1.03937619, 1.03937619, -0.21598253, -0.21598253 ]) prox = ProxTV(l_tv).astype(self.dtype) val = l_tv * np.abs(coeffs[1:] - coeffs[:-1]).sum() self.assertAlmostEqual(prox.value(coeffs), val, delta=self.delta) assert_almost_equal(prox.call(coeffs, step=t), out, decimal=7) coeffs = self.coeffs.copy().astype(self.dtype) out = np.array([ -0.86017247, -0.58127151, -0.6116414, 0.11135304, 0.11135304, 1.32270952, 1.32270952, 1.32270952, -0.27576309, -1.00620197 ]) prox = ProxTV(l_tv, (3, 8)).astype(self.dtype) val = l_tv * np.abs(coeffs[3:8][1:] - coeffs[3:8][:-1]).sum() self.assertAlmostEqual(prox.value(coeffs), val, delta=self.delta) assert_almost_equal(prox.call(coeffs, step=t), out, decimal=7) coeffs = self.coeffs.copy().astype(self.dtype) out = np.array([ -0.86017247, -0.58127151, -0.6116414, 0.11135304, 0.11135304, 1.32270952, 1.32270952, 1.32270952, -0.27576309, -1.00620197 ]) prox = ProxTV(l_tv, (3, 8), positive=True).astype(self.dtype) prox.call(coeffs, step=t) val = l_tv * np.abs(coeffs[3:8][1:] - coeffs[3:8][:-1]).sum() self.assertAlmostEqual(prox.value(coeffs), val, delta=self.delta) assert_almost_equal(prox.call(coeffs, step=t), out, decimal=7)
def test_prox_multi(self): """...Test of ProxMulti """ coeffs = self.coeffs.copy().astype(self.dtype) double_coeffs = np.concatenate([coeffs, coeffs]).astype(self.dtype) half_size = coeffs.shape[0] full_size = double_coeffs.shape[0] l_tv = 0.5 t = 1.7 prox_tv = ProxTV(strength=l_tv).astype(self.dtype) prox_tv_multi = ProxTV(strength=l_tv, range=(0, half_size)).astype(self.dtype) l_enet = 3e-2 ratio = .3 prox_enet = ProxElasticNet(l_enet, ratio=ratio).astype(self.dtype) prox_enet_multi = ProxElasticNet(l_enet, ratio=ratio, range=(half_size, full_size)).astype(self.dtype) prox_multi = ProxMulti((prox_tv_multi, prox_enet_multi)) # Test that the value of the prox is correct val_multi = prox_multi.value(double_coeffs) val_correct = prox_enet.value(coeffs) + prox_tv.value(coeffs) self.assertAlmostEqual(val_multi, val_correct, places=self.decimal_places) # Test that the prox is correct out1 = prox_tv.call(coeffs, step=t) out2 = prox_enet.call(coeffs, step=t) out_correct = np.concatenate([out1, out2]) out_multi = prox_multi.call(double_coeffs, step=t) np.testing.assert_almost_equal(out_multi, out_correct) # An example with overlapping coefficients start1 = 5 end1 = 13 start2 = 10 end2 = 17 prox_tv = ProxTV(strength=l_tv, range=(start1, end1)).astype(self.dtype) prox_enet = ProxElasticNet(strength=l_enet, ratio=ratio, range=(start2, end2)).astype(self.dtype) prox_multi = ProxMulti((prox_tv, prox_enet)) val_correct = prox_tv.value(double_coeffs) val_correct += prox_enet.value(double_coeffs) val_multi = prox_multi.value(double_coeffs) self.assertAlmostEqual(val_multi, val_correct) out_correct = prox_tv.call(double_coeffs) out_correct = prox_enet.call(out_correct) out_multi = prox_multi.call(double_coeffs) np.testing.assert_almost_equal(out_multi, out_correct)
def test_dense_and_sparse_match(self): """...Test in SVRG that dense and sparse code matches in all possible settings """ variance_reductions = ['last', 'rand'] rand_types = ['perm', 'unif'] seed = 123 tol = 0. max_iter = 50 n_samples = 500 n_features = 20 # Crazy prox examples proxs = [ ProxTV(strength=1e-2, range=(5, 13), positive=True).astype(self.dtype), ProxElasticNet(strength=1e-2, ratio=0.9).astype(self.dtype), ProxEquality(range=(0, n_features)).astype(self.dtype), ProxL1(strength=1e-3, range=(5, 17)).astype(self.dtype), ProxL1w(strength=1e-3, weights=np.arange(5, 17, dtype=np.double), range=(5, 17)).astype(self.dtype), ] for intercept in [-1, None]: X, y = self.simu_linreg_data(dtype=self.dtype, interc=intercept, n_features=n_features, n_samples=n_samples) fit_intercept = intercept is not None model_dense, model_spars = self.get_dense_and_sparse_linreg_model( X, y, dtype=self.dtype, fit_intercept=fit_intercept) step = 1 / model_spars.get_lip_max() for variance_reduction, rand_type, prox in product( variance_reductions, rand_types, proxs): solver_sparse = SVRG(step=step, tol=tol, max_iter=max_iter, verbose=False, variance_reduction=variance_reduction, rand_type=rand_type, seed=seed) solver_sparse.set_model(model_spars).set_prox(prox) solver_dense = SVRG(step=step, tol=tol, max_iter=max_iter, verbose=False, variance_reduction=variance_reduction, rand_type=rand_type, seed=seed) solver_dense.set_model(model_dense).set_prox(prox) solver_sparse.solve() solver_dense.solve() places = 7 if self.dtype is "float32": places = 3 np.testing.assert_array_almost_equal(solver_sparse.solution, solver_dense.solution, decimal=places)
def _construct_prox_obj(self, coeffs=None, project=False): n_penalized_features = len(self.penalized_features) \ if self.penalized_features is not None else 0 if project: # project future _coeffs on the support of given _coeffs if all(self.n_lags == 0): proxs = [ProxZero()] elif coeffs is not None: prox_ranges = self._detect_support(coeffs) proxs = [ProxEquality(0, range=r) for r in prox_ranges] else: raise ValueError("Coeffs are None. " + "Equality penalty cannot infer the " "coefficients support.") elif n_penalized_features > 0 and self._C_tv is not None or \ self._C_group_l1 is not None: # TV and GroupLasso penalties blocks_start = np.zeros(n_penalized_features) blocks_end = np.zeros(n_penalized_features) proxs = [] for i in self.penalized_features: start = int(self._features_offset[i]) blocks_start[i] = start end = int(blocks_start[i] + self._n_lags[i] + 1) blocks_end[i] = end if self._C_tv is not None: proxs.append(ProxTV(1 / self._C_tv, range=(start, end))) if self._C_group_l1 is not None: blocks_size = blocks_end - blocks_start proxs.append( ProxGroupL1(1 / self._C_group_l1, blocks_start.tolist(), blocks_size.tolist())) else: # Default prox: does nothing proxs = [ProxZero()] prox_obj = ProxMulti(tuple(proxs)) return prox_obj
import numpy as np import matplotlib.pyplot as plt from tick.prox import ProxL1, ProxTV, ProxMulti s = 0.4 prox = ProxMulti( proxs=( ProxTV(strength=s, range=(0, 20)), ProxL1(strength=2 * s, range=(20, 50)) ) ) x = np.random.randn(50) a, b = x.min() - 1e-1, x.max() + 1e-1 plt.figure(figsize=(8, 4)) plt.subplot(1, 2, 1) plt.stem(x) plt.title("original vector", fontsize=16) plt.xlim((-1, 51)) plt.ylim((a, b)) plt.subplot(1, 2, 2) plt.stem(prox.call(x)) plt.title("ProxMulti: TV and L1", fontsize=16) plt.xlim((-1, 51)) plt.ylim((a, b)) plt.vlines(20, a, b, linestyles='dashed') plt.tight_layout() plt.show()
ProxPositive, ProxSlope, ProxTV, ProxZero, ProxBinarsity, ProxGroupL1, \ ProxEquality, ProxL1w np.random.seed(12) x = np.random.randn(50) a, b = x.min() - 1e-1, x.max() + 1e-1 s = 0.4 proxs = [ ProxZero(), ProxPositive(), ProxL2Sq(strength=s), ProxL1(strength=s), ProxElasticNet(strength=s, ratio=0.5), ProxSlope(strength=s), ProxTV(strength=s), ProxEquality(range=(25, 40)), ProxL1w(strength=s, weights=0.1 * np.arange(50, dtype=np.double)), ProxGroupL1(strength=2 * s, blocks_start=np.arange(0, 50, 10), blocks_length=10 * np.ones((5, ))), ProxBinarsity(strength=s, blocks_start=np.arange(0, 50, 10), blocks_length=10 * np.ones((5, ))) ] fig, _ = plt.subplots(3, 4, figsize=(16, 12), sharey=True, sharex=True) fig.axes[0].stem(x) fig.axes[0].set_title("original vector", fontsize=16) fig.axes[0].set_xlim((-1, 51)) fig.axes[0].set_ylim((a, b))
def test_serializing_solvers(self): """...Test serialization of solvers """ ratio = 0.5 l_enet = 1e-2 sd = ratio * l_enet proxes = [ ProxZero(), ProxTV(2), ProxL1(2), ProxGroupL1(strength=1, blocks_start=[0, 3, 8], blocks_length=[3, 5, 2]) ] solvers = [ AdaGrad(step=1e-3, max_iter=100, verbose=False, tol=0), SGD(step=1e-3, max_iter=100, verbose=False, tol=0), SDCA(l_l2sq=sd, max_iter=100, verbose=False, tol=0), SAGA(step=1e-3, max_iter=100, verbose=False, tol=0), SVRG(step=1e-3, max_iter=100, verbose=False, tol=0) ] model_map = { ModelLinReg: SimuLinReg, ModelLogReg: SimuLogReg, ModelPoisReg: SimuPoisReg, ModelHinge: SimuLogReg, ModelQuadraticHinge: SimuLogReg, ModelSmoothedHinge: SimuLogReg, ModelAbsoluteRegression: SimuLinReg, ModelEpsilonInsensitive: SimuLinReg, ModelHuber: SimuLinReg, ModelLinRegWithIntercepts: SimuLinReg, ModelModifiedHuber: SimuLogReg } for solver in solvers: for mod in model_map: for prox in proxes: np.random.seed(12) n_samples, n_features = 100, 5 w0 = np.random.randn(n_features) intercept0 = 50 * weights_sparse_gauss(n_weights=n_samples, nnz=30) c0 = None X, y = SimuLinReg(w0, c0, n_samples=n_samples, verbose=False, seed=2038).simulate() if mod == ModelLinRegWithIntercepts: y += intercept0 model = mod(fit_intercept=False).fit(X, y) # prox = ProxZero() #(2.) solver.set_model(model) solver.set_prox(prox) pickled = pickle.loads(pickle.dumps(solver)) self.assertTrue(solver._solver.compare(pickled._solver)) self.assertTrue( solver.model._model.compare(pickled.model._model)) self.assertTrue(solver.prox._prox.compare(pickled.prox._prox)) if mod == ModelLinRegWithIntercepts: test_vector = np.hstack((X[0], np.ones(n_samples))) self.assertEqual( model.loss(test_vector), solver.model.loss(test_vector)) else: self.assertEqual(model.loss(X[0]), solver.model.loss(X[0]))