def test_gradient(self): """Unittests for gradient() function.""" multiclass = CClassifierMulticlassOVA(classifier=CClassifierSVM, class_weight='balanced') i = 5 # Sample to test self.logger.info("Testing with dense data...") ds = self.dataset.todense() multiclass.fit(ds.X, ds.Y) pattern = ds.X[i, :] # Compare with numerical gradient grads_d = self._test_gradient_numerical(multiclass, pattern) # Check if we can return the i_th classifier for i in range(multiclass.num_classifiers): ova_grad = multiclass._binary_classifiers[i].grad_f_x(pattern, y=1) gradient = multiclass.grad_f_x(pattern, y=i) self.logger.info( "Gradient of {:}^th sub-clf is:\n{:}".format(i, gradient)) self.assert_array_equal(gradient, ova_grad) self.logger.info("Testing with sparse data...") ds = self.dataset.tosparse() multiclass.fit(ds.X, ds.Y) pattern = ds.X[i, :] # Compare with numerical gradient grads_s = self._test_gradient_numerical(multiclass, pattern) # Compare dense gradients with sparse gradients for grad_i, grad in enumerate(grads_d): self.assert_array_almost_equal( grad.atleast_2d(), grads_s[grad_i]) # Test error raise with self.assertRaises(ValueError): multiclass.grad_f_x(pattern, y=-1) with self.assertRaises(ValueError): multiclass.grad_f_x(pattern, y=100)
def test_aspreprocess(self): """Test for normalizer used as preprocess.""" from secml.ml.classifiers import CClassifierSVM from secml.ml.classifiers.multiclass import CClassifierMulticlassOVA model = mlp(input_dims=20, hidden_dims=(40,), output_dims=3) loss = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=1e-1) net = CClassifierPyTorch(model=model, loss=loss, optimizer=optimizer, random_state=0, epochs=10, preprocess='min-max') net.fit(self.ds.X, self.ds.Y) norm = CNormalizerDNN(net=net) clf = CClassifierMulticlassOVA( classifier=CClassifierSVM, preprocess=norm) self.logger.info("Testing last layer") clf.fit(self.ds.X, self.ds.Y) y_pred, scores = clf.predict( self.ds.X, return_decision_function=True) self.logger.info("TRUE:\n{:}".format(self.ds.Y.tolist())) self.logger.info("Predictions:\n{:}".format(y_pred.tolist())) self.logger.info("Scores:\n{:}".format(scores)) x = self.ds.X[0, :] self.logger.info("Testing last layer gradient") for c in self.ds.classes: self.logger.info("Gradient w.r.t. class {:}".format(c)) grad = clf.grad_f_x(x, y=c) self.logger.info("Output of grad_f_x:\n{:}".format(grad)) check_grad_val = CFunction( clf.decision_function, clf.grad_f_x).check_grad( x, y=c, epsilon=1e-1) self.logger.info( "norm(grad - num_grad): %s", str(check_grad_val)) self.assertLess(check_grad_val, 1e-3) self.assertTrue(grad.is_vector_like) self.assertEqual(x.size, grad.size) layer = 'linear1' norm.out_layer = layer self.logger.info("Testing layer {:}".format(norm.out_layer)) clf.fit(self.ds.X, self.ds.Y) y_pred, scores = clf.predict( self.ds.X, return_decision_function=True) self.logger.info("TRUE:\n{:}".format(self.ds.Y.tolist())) self.logger.info("Predictions:\n{:}".format(y_pred.tolist())) self.logger.info("Scores:\n{:}".format(scores)) self.logger.info("Testing 'linear1' layer gradient") grad = clf.grad_f_x(x, y=0) # y is required for multiclassova self.logger.info("Output of grad_f_x:\n{:}".format(grad)) self.assertTrue(grad.is_vector_like) self.assertEqual(x.size, grad.size)