我需要对一个卷积神经网络进行一个简单的FSGM攻击。CNN的代码运行正常,模型也无问题地保存了,但是当我尝试进行攻击时,显示了一个错误。
以下是CNN的代码
from keras.models import Sequentialfrom keras.layers import Dense, Conv2D, Flatten, MaxPooling2Dimport matplotlib.pyplot as pltfrom keras.datasets import mnistfrom keras.utils import to_categoricalimport jsonimport tensorflow as tf#Using TensorFlow backend.#download mnist data and split into train and test sets(X_train, y_train), (X_test, y_test) = mnist.load_data()#plot the first image in the datasetplt.imshow(X_train[0])#check image shapeX_train[0].shape#reshape data to fit modelX_train = X_train.reshape(60000,28,28,1)X_test = X_test.reshape(10000,28,28,1)#one-hot encode target columny_train = to_categorical(y_train)y_test = to_categorical(y_test)y_train[0]#create modelmodel = Sequential()#add model layersmodel.add(Conv2D(32, kernel_size=(5,5), activation='relu', input_shape= (28,28,1)))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Conv2D(64, kernel_size=(5,5), activation='relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Flatten())model.add(Dense(10, activation='softmax'))#compile model using accuracy as a measure of model performancemodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics= ['accuracy'])#train modelmodel.fit(X_train, y_train,validation_data=(X_test, y_test), epochs=5)json.dump({'model':model.to_json()},open("model.json", "w"))model.save_weights("model_weights.h5")
然后我尝试使用以下代码进行攻击:
import jsonimport foolboximport kerasimport numpy as npfrom keras import backendfrom keras.models import load_modelfrom keras.datasets import mnistfrom keras.utils import np_utilsfrom foolbox.attacks import FGSMfrom foolbox.criteria import Misclassificationfrom foolbox.distances import MeanSquaredDistanceimport matplotlib.pyplot as pltfrom keras.models import Sequentialfrom keras.layers import Dense, Flatten, Conv2D, MaxPooling2Dimport numpy as npimport tensorflow as tffrom keras.models import model_from_jsonimport os############## Loading the model and preprocessing #####################backend.set_learning_phase(False)model = tf.keras.models.model_from_json(json.load(open("model.json"))["model"],custom_objects={})model.load_weights("model_weights.h5")fmodel = foolbox.models.KerasModel(model, bounds=(0,1))_,(images, labels) = mnist.load_data()images = images.reshape(10000,28,28)images= images.astype('float32')images /= 255######################### Attacking the model ##########################attack=foolbox.attacks.FGSM(fmodel, criterion=Misclassification())adversarial=attack(images[12],labels[12]) # for single imageadversarial_all=attack(images,labels) # for all the imagesadversarial =adversarial.reshape(1,28,28,1) #reshaping it for model predictionmodel_predictions = model.predict(adversarial)print(model_predictions)########################## Visualization ################################images=images.reshape(10000,28,28)adversarial =adversarial.reshape(28,28)plt.figure()plt.subplot(1,3,1)plt.title('Original')plt.imshow(images[12])plt.axis('off')plt.subplot(1, 3, 2)plt.title('Adversarial')plt.imshow(adversarial)plt.axis('off')plt.subplot(1, 3, 3)plt.title('Difference')difference = adversarial - images[124]plt.imshow(difference / abs(difference).max() * 0.2 + 0.5)plt.axis('off')plt.show()
当生成对抗样本时,显示了以下错误:
c_api.TF_GetCode(self.status.status)) InvalidArgumentError: Matrix size-incompatible: In[0]: [1,639232], In[1]: [1024,10][[{{node dense_4_5/MatMul}}]][[{{node dense_4_5/BiasAdd}}]]
可能是什么问题呢?
回答:
这是我的解决方案。
首先,修改模型代码如下
import tensorflow as tfimport json# download mnist data and split into train and test sets(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()# reshape data to fit modelX_train = X_train.reshape(X_train.shape[0], 28, 28, 1)X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)X_train, X_test = X_train/255, X_test/255# one-hot encode target columny_train = tf.keras.utils.to_categorical(y_train)y_test = tf.keras.utils.to_categorical(y_test)# create modelmodel = tf.keras.models.Sequential()# add model layersmodel.add(tf.keras.layers.Conv2D(32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))model.add(tf.keras.layers.Conv2D(64, kernel_size=(5, 5), activation='relu'))model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))model.add(tf.keras.layers.Flatten())model.add(tf.keras.layers.Dense(10, activation='softmax'))# compile model using accuracy as a measure of model performancemodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])# train modelmodel.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=5)json.dump({'model': model.to_json()}, open("model.json", "w"))model.save_weights("model_weights.h5")
你只是忘记了将每个像素值除以RGB的最大值(255)
至于攻击者的代码
import jsonimport foolboxfrom foolbox.attacks import FGSMfrom foolbox.criteria import Misclassificationimport numpy as npimport tensorflow as tf############## Loading the model and preprocessing #####################tf.enable_eager_execution()tf.keras.backend.set_learning_phase(False)model = tf.keras.models.model_from_json( json.load(open("model.json"))["model"], custom_objects={})model.load_weights("model_weights.h5")model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])_, (images, labels) = tf.keras.datasets.mnist.load_data()images = images.reshape(images.shape[0], 28, 28, 1)images = images/255images = images.astype(np.float32)fmodel = foolbox.models.TensorFlowEagerModel(model, bounds=(0, 1))######################### Attacking the model ##########################attack = foolbox.attacks.FGSM(fmodel, criterion=Misclassification())adversarial = np.array([attack(images[0], label=labels[0])])model_predictions = model.predict(adversarial)print('real label: {}, label prediction; {}'.format( labels[0], np.argmax(model_predictions)))
为了简便,我使用了TensorFlowEagerModel而不是KerasModel。你遇到的错误是因为model.predict期望一个4维矩阵,而你传递的是一个3维矩阵,所以我只是将对图像样本的攻击包装成一个numpy数组,使其变成4维的。
希望这对你有帮助