Closed aldahdooh closed 4 years ago
Hi @ahmedomer6 Thank you very much for using ART and raising this question! The current version of KerasClassifier
does not support custom loss functions, only part of the loss functions defined by Keras. The other classifiers in ART like TensorFlowV2Classifier
are more flexible in terms of loss functions.
Hi @ahmedomer6 Thank you very much for using ART and raising this question! The current version of
KerasClassifier
does not support custom loss functions, only part of the loss functions defined by Keras. The other classifiers in ART likeTensorFlowV2Classifier
are more flexible in terms of loss functions.
Many thanks for your reply @beat-buesser . I am not using TensorFlowV2Classifier since when I am saving a callable model and then load it again I couldn't generate attacks with generate function. It says not callable. Hence, I moved to Keras.
@ahmedomer6 Did you try making your model callable? ART's example/get_started_tensorflow_v2.py shows how to use a callable model.
@beat-buesser Yes, I did the same. it works fine. But if the model in the example saved and loaded again, you cannot generate attacks.
How did you save the model and why can it not run a new attack?
@ I used the following steps 1-create KerasModel() 2-train it 3-save weights 4-create new KerasModel() 5-load weights
Thank you. What is the error message that you receive after running an attack on the new model after step 5?
I tracked the error below. It comes from loss object since i defined my own loss function
The error art/classifiers/tensorflow.py", line 947, in loss_gradient loss = self._loss_object(y, predictions) TypeError: 'list' object is not callable
Would it be possible for you to post a code example with a small model form the ART examples that reproduces this error? I would be interested to find out why this is happening.
I am building a model with two outputs with custom loss function. Then I am trying to apply an attack on the model using KerasClassifier. but I have the following error (I guess that Kera wrapper coudn't recognize the the loss type/name).
To Reproduce
import keras import numpy as np import pickle import json import os import yaml from keras import backend as K from keras import optimizers from keras import regularizers from keras.datasets import cifar10 from keras.engine.topology import Layer from keras.layers import Conv2D, MaxPooling2D, BatchNormalization, Concatenate from keras.layers import Dense, Dropout, Activation, Flatten, Input from keras.layers import Lambda from keras.models import Model from keras.models import Sequential from keras.preprocessing.image import ImageDataGenerator from art.classifiers import KerasClassifier from art.attacks import FastGradientMethod import matplotlib.pyplot as plt
function
def normalize(X_train, X_test): X_train = X_train / 255.0 X_test = X_test / 255.0 return X_train, X_test
function
def load_cifar10_data(): num_classes = 10 (x_train, y_train), (x_test, y_test_label) = cifar10.load_data() x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train, x_test = normalize(x_train, x_test)
function
def build_cifar10_model(input_shape): weight_decay = 0.0005 input = Input(shape=input_shape) num_classes = 10
function
def loss_fun(y_true, y_pred): num_classes = 10 loss = K.categorical_crossentropy( K.repeat_elements(y_pred[:, -1:], num_classes, axis=1) * y_true[:, :-1], y_pred[:, :-1]) return loss
function
def my_generator(func, x_train, y_train, batch_size): while True: res = func(x_train, y_train, batch_size).next() yield [res[0], [res[1], res[1][:, :-1]]]
variables
(x_train, y_train), (x_test, y_test) = load_cifar10_data()
variables for model
num_classes = 10 weight_decay = 0.0005 basic_dropout_rate=0.3 mc_dropout_rate = 0 #K.variable(value=0) input_shape = x_train.shape[1:] filename = 'test_selective.h5'
cifar_model = build_cifar10_model(input_shape)
variables for training
alpha = 0.5 batch_size = 128 maxepoches = 5 learning_rate = 0.1 lr_decay = 1e-6 lr_drop = 25 def lr_scheduler(epoch): return learning_rate * (0.5 ** (epoch // lr_drop)) reduce_lr = keras.callbacks.LearningRateScheduler(lr_scheduler)
data augmentation
datagen = ImageDataGenerator( featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False,
rotation_range=15, width_shift_range=0.1,
height_shift_range=0.1, horizontal_flip=True,
vertical_flip=False) datagen.fit(x_train)
sgd = optimizers.SGD(lr=learning_rate, decay=lr_decay, momentum=0.9, nesterov=True) cifar_model.compile(loss={'output1': loss_fun, 'output2': 'categorical_crossentropy'}, loss_weights=[alpha, 1 - alpha], optimizer=sgd, metrics=['accuracy'])
historytemp = cifar_model.fit_generator(my_generator(datagen.flow, x_train, y_train, batch_size=batch_size),
steps_per_epoch=x_train.shape[0] // batch_size,
epochs=maxepoches, callbacks=[reduce_lr],
validation_data=(x_test, [y_test, y_test[:, :-1]]))
loss_all, loss_out1, loss_out2, out1_acc, out2_acc = cifar_model.evaluate(x_test, [y_test, y_test[:,:-1]])
cifar_model.saveweights("checkpoints/{}".format('wts' + filename))
cifar_model.save("checkpoints/{}".format(filename))
model = build_cifar10_model(input_shape) model.loadweights("checkpoints/{}".format('wts' + filename)) model.compile(loss={'output1': loss_fun, 'output2': 'categorical_crossentropy'}, loss_weights=[alpha, 1 - alpha], optimizer=sgd, metrics=['accuracy']) model.summary() loss_all, loss_out1, loss_out2, out1_acc, out2_acc = model.evaluate(x_test, [y_test, y_test[:,:-1]])
classifier = KerasClassifier(model=model, clip_values=(0, 1)) attack_fgsm = FastGradientMethod(classifier=classifier, eps=0.3) x_test_adv = attack_fgsm.generate(x_test)
loss_adv_all, loss_adv_out1, loss_adv_out2, out1_adv_acc, out2_adv_acc = model.evaluate(x_test_adv, [y_test, y_test[:,:-1]]) perturbation = np.mean(np.abs((x_test_adv - x_test))) print('Accuracy on adversarial test data: {:4.2f}%'.format(out1_adv_acc * 100)) print('Average perturbation: {:4.2f}'.format(perturbation))
plt.figure() plt.imshow(x_test_adv[0,:,:,0]) plt.show()
print('Done....')