#tensorflow #keras #generative-adversarial-network #cleverhans #adversarial-machines
#tensorflow #keras #генеративная-состязательная-сеть #cleverhans #состязательные машины
Вопрос:
Я пытаюсь использовать алгоритм Elastic-Net, реализованный в Cleverhans, для генерации состязательных выборок в задаче классификации. Основная проблема заключается в том, что я пытаюсь использовать его таким образом, чтобы получить более высокую достоверность во время классификации в целевом классе (отличном от исходного), но я не могу достичь хороших результатов. Система, которую я пытаюсь обмануть, — это DNN с выводом softmax для 10 классов.
Например:
- Учитывая образец класса 3, я хочу сгенерировать состязательный образец класса 0.
- Используя гиперпараметры по умолчанию, реализованные в ElasticNetMethod cleverhans, я могу добиться успешной атаки, поэтому класс, присвоенный состязательной выборке, стал классом 0, но достоверность довольно низкая (около 30%). Это также происходит при попытке использовать разные значения для гиперпараметров.
- Моя цель — получить достаточно высокую достоверность (не менее 90%).
- Для другого алгоритма, такого как «FGSM» или «MadryEtAl», я могу достичь этой цели, создавая цикл, в котором алгоритм применяется до тех пор, пока образец не будет классифицирован как целевой класс с достоверностью более 90%, но я не могу применить эту итерацию к алгоритму EAD, потому что на каждом шаге итерации он выдает состязательный образец, сгенерированный на первом шаге, и на следующих итерациях он остается неизменным. (Я знаю, что это может произойти, потому что алгоритм отличается от двух других предложенных, но я пытаюсь найти решение для достижения моей цели).
Это код, который я фактически использую для генерации состязательных образцов.
ead_params = { 'binary_search_steps':9, 'max_iterations':100 , 'learning_rate':0.001, 'clip_min':0,'clip_max':1,'y_target':target}
adv_x = image
founded_adv = False
threshold = 0.9
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)
while (not founded_adv):
adv_x = ead.generate_np(adv_x, **ead_params)
prediction = model.predict(adv_x).tolist()
pred_class = np.argmax(prediction[0])
confidence = prediction[0][pred_class]
if (pred_class == 0 and confidence >= threshold):
founded_adv = True
Цикл while может генерировать выборку до тех пор, пока целевой класс не будет достигнут с достоверностью, превышающей 90%. Этот код на самом деле работает с FGSM и Madry, но выполняется бесконечно с использованием EAD.
Версия библиотеки:
Tensorflow: 2.2.0 Keras: 2.4.3 Cleverhans: 2.0.0-451ccecad450067f99c333fc53592201
Кто-нибудь может мне помочь?
Большое спасибо.
Комментарии:
1. Я основал решение и разместил его здесь .
Ответ №1:
Для всех, кто интересуется этой проблемой, предыдущий код может быть изменен таким образом, чтобы он работал должным образом:
ПЕРВОЕ РЕШЕНИЕ:
prediction = model.predict(image)
initial_predicted_class = np.argmax(prediction[0])
ead_params = { 'binary_search_steps':9, 'max_iterations':100 , 'learning_rate':0.001,'confidence':1, 'clip_min':0,'clip_max':1,'y_target':target}
adv_x = image
founded_adv = False
threshold = 0.9
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)
while (not founded_adv):
adv_x = ead.generate_np(adv_x, **ead_params)
prediction = model.predict(adv_x).tolist()
pred_class = np.argmax(prediction[0])
confidence = prediction[0][pred_class]
if (pred_class == initial_pred_class and confidence >= threshold):
founded_adv = True
else:
ead_params['confidence'] = 1
Использование параметра достоверности, реализованного в библиотеке. На самом деле мы увеличиваем на 1 параметр достоверности, если вероятность целевого класса не увеличивается.
ВТОРОЕ РЕШЕНИЕ :
prediction = model.predict(image)
initial_predicted_class = np.argmax(prediction[0])
ead_params = {'beta':5e-3 , 'binary_search_steps':6, 'max_iterations':10 , 'learning_rate':3e-2, 'clip_min':0,'clip_max':1}
threshold = 0.96
adv_x = image
founded_adv = False
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)
while (not founded_adv):
eps_hyp = 0.5
new_adv_x = ead.generate_np(adv_x, **ead_params)
pert = new_adv_x-adv_x
new_adv_x = adv_x - eps_hyp*pert
new_adv_x = (new_adv_x - np.min(new_adv_x)) / (np.max(new_adv_x) - np.min(new_adv_x))
adv_x = new_adv_x
prediction = model.predict(new_adv_x).tolist()
pred_class = np.argmax(prediction[0])
confidence = prediction[0][pred_class]
print(pred_class)
print(confidence)
if (pred_class == initial_predicted_class and confidence >= threshold):
founded_adv = True
Во втором решении в исходный код внесены следующие изменения:
-Initial_predicted_class — это класс, предсказанный моделью для доброкачественной выборки («0» для нашего примера).
-В параметрах алгоритма (ead_params) мы не вставляем целевой класс.
-Тогда мы можем получить возмущение, заданное алгоритмом, вычисляющим pert = new_adv_x — adv_x, где «adv_x» — это исходное изображение (на первом шаге цикла for), а new_adv_x — это возмущенный образец, сгенерированный алгоритмом.
-Предыдущая операция полезна, потому что исходный алгоритм EAD вычисляет возмущение, чтобы максимизировать потери по отношению к классу «0», но в нашем случае мы хотим его минимизировать.
-Итак, мы можем вычислить новое возмущенное изображение как new_adv_x = adv_x — eps_hyp* pert (где eps_hyp — гиперпараметр epsilon, который я ввел, чтобы уменьшить возмущение), и затем мы нормализуем новое возмущенное изображение.
-Я протестировал код для большого количества изображений, и уверенность всегда возрастает, поэтому я думаю, что это может быть хорошим решением для этой цели.
Я думаю, что второе решение позволяет получить более тонкое возмущение.