Trusted-AI / adversarial-robustness-toolbox

Adversarial Robustness Toolbox (ART) - Python Library for Machine Learning Security - Evasion, Poisoning, Extraction, Inference - Red and Blue Teams
https://adversarial-robustness-toolbox.readthedocs.io/en/latest/
MIT License
4.84k stars 1.16k forks source link

Binary classification error #535

Open jinglin80 opened 4 years ago

jinglin80 commented 4 years ago

I simply change a multi-classification problem in a tutorial with a binary classification on a reduced cifar10 dataset (airplane vs frog). However, I notice an issue with this binary classification with 1 neuron in the output layer. To Reproduce import numpy as np import tensorflow.compat.v1 as tf tf.disable_eager_execution() # for grad function from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam from art.config import ART_DATA_PATH from art.utils import load_dataset, get_file from tensorflow.keras.models import load_model from tensorflow.keras.layers import Dense, Dropout from art.estimators.classification import KerasClassifier path = get_file('cifar_resnet.h5',extract=False, path=ART_DATA_PATH, url='https://www.dropbox.com/s/ta75pl4krya5djj/cifar_resnet.h5?dl=1') (x_train, y_train), (x_test, ytest), min, max_ = load_dataset(str('cifar10')) training_labels = np.argmax(y_train, axis =1) # (50000,) test_labels = np.argmax(y_test, axis =1 ) # for 10 classes X_inp_tr = x_train[np.squeeze(np.logical_or(training_labels==6, training_labels==0))][:3000]# 6: frog (base). 0: airplane Y_train = training_labels[np.squeeze(np.logical_or(training_labels==6, training_labels==0))][:3000] Y_train[Y_train==6]=1 X_inp_test = x_test[np.squeeze(np.logical_or(test_labels==6, test_labels==0))] Y_test_raw = test_labels[np.squeeze(np.logical_or(test_labels==6, test_labels==0))].reshape(-1,) Y_test_raw[Y_test_raw==6]=1 classifier_model = load_model(path) json_config = classifier_model.to_json() new_model = tf.keras.models.model_from_json(json_config) drop = Dropout(.2)(new_model.layers[-2].output) fc = Dense(1, activation='sigmoid')(drop) cifar_model = Model(inputs=new_model.input, outputs=fc) cifar_model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5), metrics=['accuracy']) model = KerasClassifier(model=cifar_model, clip_values=(0, 1)) model.fit(X_inp_tr, Y_train, nb_epochs=1, batch_size=32, verbose=2)

However, if I change it to two neuron for the last layer, the issue is solved.

import numpy as np import tensorflow.compat.v1 as tf tf.disable_eager_execution() # for grad function from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam from art.config import ART_DATA_PATH from art.utils import load_dataset, get_file from tensorflow.keras.models import load_model from tensorflow.keras.layers import Dense, Dropout from art.estimators.classification import KerasClassifier path = get_file('cifar_resnet.h5',extract=False, path=ART_DATA_PATH, url='https://www.dropbox.com/s/ta75pl4krya5djj/cifar_resnet.h5?dl=1') (x_train, y_train), (x_test, ytest), min, max_ = load_dataset(str('cifar10')) training_labels = np.argmax(y_train, axis =1) # (50000,) test_labels = np.argmax(y_test, axis =1 ) # for 10 classes X_inp_tr = x_train[np.squeeze(np.logical_or(training_labels==6, training_labels==0))][:3000]# 6: frog (base). 0: airplane Y_train = training_labels[np.squeeze(np.logical_or(training_labels==6, training_labels==0))][:3000] Y_train[Y_train==6]=1 X_inp_test = x_test[np.squeeze(np.logical_or(test_labels==6, test_labels==0))] Y_test_raw = test_labels[np.squeeze(np.logical_or(test_labels==6, test_labels==0))].reshape(-1,) Y_test_raw[Y_test_raw==6]=1 classifier_model = load_model(path) json_config = classifier_model.to_json() new_model = tf.keras.models.model_from_json(json_config) drop = Dropout(.2)(new_model.layers[-2].output) fc = Dense(2, activation='softmax')(drop) cifar_model = Model(inputs=new_model.input, outputs=fc) cifar_model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5), metrics=['accuracy']) model = KerasClassifier(model=cifar_model, clip_values=(0, 1)) model.fit(X_inp_tr, Y_train, nb_epochs=1, batch_size=32, verbose=2)

beat-buesser commented 4 years ago

Hi @jinglin80 Thank you very much!

Yes, your observation is correct, this and some of the changes required to support single neuron outputs has been discussed in issue #306 .