Kaggle首席技術官發布——(Kaggle)NIPS 2017對抗學習挑戰賽起步指南
首發地址:https://yq.aliyun.com/articles/126898
NIPS,是關於機器學習領域的頂級會議,也是令眾多學者振奮的學術盛會。12 年底舉辦的NIPS將新增一個議程,NIPS 2017Competition Track,從23個候選提案中選擇了五個數據驅動的比賽項目。近日穀歌大腦研究員Ian Goodfellow在社媒平台中強烈推薦了由他組織的Adversarial Attacks and Defences(對抗攻擊防禦)比賽。為什麼組織這樣一個比賽呢,這是因為當前圖像分類器非常容易被精心設計的對抗圖像所欺騙,這些圖像給原始圖像及正確分類圖像添加了微小變化,這些圖像幾乎不容易被人眼察覺,但會導致圖像分類器錯誤地對錯誤的分類充滿自信。
這項比賽是在kaggle
下麵具體來說下這三個相關比賽的側重點:
- 1、Non Targeted Adversarial Attack,競賽者所提交的係統需要對任何類別的圖像進行處理,使得某個通用機器學習分類器無法識別。
- 2Targeted Adversarial Attack,競賽者所提交的係統需要對給定的圖像進行處理,使得某個通用機器學習分類器無法識別。
- 3、Defense Against Adversarial Attack,競賽者需要構建一個機器學習分類器,擁有足夠的魯棒性使之能正確鑒別對抗性的圖像。
根據前兩個挑戰的對抗性攻擊,防禦挑戰的得分取決於分類器的好壞,另外前兩個挑戰的得分是基於在第三個挑戰中對抗性攻擊的伎倆有多好。
下麵,我們將通過一些代碼示例來生成非目標和目標的對抗圖像,然後看看Inception V3googleNet Inception V3
注:下麵許多的代碼是基於Alextensorflow
/
import os
from cleverhans.attacks import FastGradientMethod
from io import BytesIO
import IPython.display
import numpy as np
import pandas as pd
from PIL import Image
from scipy.misc import imread
from scipy.misc import imsave
import tensorflow as tf
from tensorflow.contrib.slim.nets import inception
slim = tf.contrib.slim
tensorflow_master = ""
checkpoint_path = "../input/inception-v3/inception_v3.ckpt"
input_dir = "../input/nips-2017-adversarial-learning-development-set/images/"
max_epsilon = 16.0
image_width = 299
image_height = 299
batch_size = 16
eps = 2.0 * max_epsilon / 255.0
batch_shape = [batch_size, image_height, image_width, 3]
num_classes = 1001
def load_images(input_dir, batch_shape):
images = np.zeros(batch_shape)
filenames = []
idx = 0
batch_size = batch_shape[0]
for filepath in sorted(tf.gfile.Glob(os.path.join(input_dir, '*.png'))):
with tf.gfile.Open(filepath, "rb") as f:
images[idx, :, :, :] = imread(f, mode='RGB').astype(np.float)*2.0/255.0 - 1.0
filenames.append(os.path.basename(filepath))
idx += 1
if idx == batch_size:
yield filenames, images
filenames = []
images = np.zeros(batch_shape)
idx = 0
if idx > 0:
yield filenames, images
def show_image(a, fmt='png'):
a = np.uint8((a+1.0)/2.0*255.0)
f = BytesIO()
Image.fromarray(a).save(f, fmt)
IPython.display.display(IPython.display.Image(data=f.getvalue()))
class InceptionModel(object):
def __init__(self, num_classes):
self.num_classes = num_classes
self.built = False
def __call__(self, x_input):
"""Constructs model and return probabilities for given input."""
reuse = True if self.built else None
with slim.arg_scope(inception.inception_v3_arg_scope()):
_, end_points = inception.inception_v3(
x_input, num_classes=self.num_classes, is_training=False,
reuse=reuse)
self.built = True
output = end_points['Predictions']
probs = output.op.inputs[0]
return probs
接下來,我們將在元數據中加載一批圖像。
categories = pd.read_csv("../input/nips-2017-adversarial-learning-development-set/categories.csv")
image_classes = pd.read_csv("../input/nips-2017-adversarial-learning-development-set/images.csv")
image_iterator = load_images(input_dir, batch_shape)
# get first batch of images
filenames, images = next(image_iterator)
image_metadata = pd.DataFrame({"ImageId": [f[:-4] for f in filenames]}).merge(image_classes,
on="ImageId")
true_classes = image_metadata["TrueLabel"].tolist()
target_classes = true_labels = image_metadata["TargetClass"].tolist()
true_classes_names = (pd.DataFrame({"CategoryId": true_classes})
.merge(categories, on="CategoryId")["CategoryName"].tolist())
target_classes_names = (pd.DataFrame({"CategoryId": target_classes})
.merge(categories, on="CategoryId")["CategoryName"].tolist())
print("Here's an example of one of the images in the development set")
show_image(images[0])
下麵是開發集中的一個圖像示例,是不是很可愛?
tensorflow的類別。
tf.logging.set_verbosity(tf.logging.INFO)
with tf.Graph().as_default():
x_input = tf.placeholder(tf.float32, shape=batch_shape)
model = InceptionModel(num_classes)
fgsm = FastGradientMethod(model)
x_adv = fgsm.generate(x_input, eps=eps, clip_min=-1., clip_max=1.)
saver = tf.train.Saver(slim.get_model_variables())
session_creator = tf.train.ChiefSessionCreator(
scaffold=tf.train.Scaffold(saver=saver),
checkpoint_filename_with_path=checkpoint_path,
master=tensorflow_master)
with tf.train.MonitoredSession(session_creator=session_creator) as sess:
nontargeted_images = sess.run(x_adv, feed_dict={x_input: images})
print("The original image is on the left, and the nontargeted adversarial image is on the right. They look very similar, don't they? It's very clear both are gondolas")
show_image(np.concatenate([images[1], nontargeted_images[1]], axis=1))
INFO:tensorflow:Restoring parameters from ../input/inception-v3/inception_v3.ckpt
左邊是原始圖像,右邊是非目標對抗圖像。它們看起來很相似,很明顯都是小船。
tensorflow
注意:目前不工作,隻是產生對抗圖像而沒有正確的目標。
all_images_target_class = {image_metadata["ImageId"][i]+".png": image_metadata["TargetClass"][i]
for i in image_metadata.index}
with tf.Graph().as_default():
x_input = tf.placeholder(tf.float32, shape=batch_shape)
with slim.arg_scope(inception.inception_v3_arg_scope()):
logits, end_points = inception.inception_v3(
x_input, num_classes=num_classes, is_training=False)
target_class_input = tf.placeholder(tf.int32, shape=[batch_size])
one_hot_target_class = tf.one_hot(target_class_input, num_classes)
cross_entropy = tf.losses.softmax_cross_entropy(one_hot_target_class,
logits,
label_smoothing=0.1,
weights=1.0)
cross_entropy += tf.losses.softmax_cross_entropy(one_hot_target_class,
end_points['AuxLogits'],
label_smoothing=0.1,
weights=0.4)
x_adv = x_input - eps * tf.sign(tf.gradients(cross_entropy, x_input)[0])
x_adv = tf.clip_by_value(x_adv, -1.0, 1.0)
saver = tf.train.Saver(slim.get_model_variables())
session_creator = tf.train.ChiefSessionCreator(
scaffold=tf.train.Scaffold(saver=saver),
checkpoint_filename_with_path=checkpoint_path,
master=tensorflow_master)
with tf.train.MonitoredSession(session_creator=session_creator) as sess:
target_class_for_batch = ([all_images_target_class[n] for n in filenames]
+ [0] * (batch_size - len(filenames)))
targeted_images = sess.run(x_adv,
feed_dict={x_input: images,
target_class_input: target_class_for_batch})
print("The original image is on the left, and the targeted adversarial image is on the right. Again, they look very similar, don't they? It's very clear both are butterflies")
show_image(np.concatenate([images[2], targeted_images[2]], axis=1))
INFO:tensorflow:Restoring parameters from ../input/inception-v3/inception_v3.ckpt
左邊是原始圖像,右邊是目標對抗圖像。同樣可以發現它們看起來很相似,很明顯都是蝴蝶。
接下來,我們將看到,當把這些生成的對抗圖像送入原始分類器運行時會發生什麼。
with tf.Graph().as_default():
x_input = tf.placeholder(tf.float32, shape=batch_shape)
with slim.arg_scope(inception.inception_v3_arg_scope()):
_, end_points = inception.inception_v3(x_input, num_classes=num_classes, is_training=False)
predicted_labels = tf.argmax(end_points['Predictions'], 1)
saver = tf.train.Saver(slim.get_model_variables())
session_creator = tf.train.ChiefSessionCreator(
scaffold=tf.train.Scaffold(saver=saver),
checkpoint_filename_with_path=checkpoint_path,
master=tensorflow_master)
with tf.train.MonitoredSession(session_creator=session_creator) as sess:
predicted_classes = sess.run(predicted_labels, feed_dict={x_input: images})
predicted_nontargeted_classes = sess.run(predicted_labels, feed_dict={x_input: nontargeted_images})
predicted_targeted_classes = sess.run(predicted_labels, feed_dict={x_input: targeted_images})
predicted_classes_names = (pd.DataFrame({"CategoryId": predicted_classes})
.merge(categories, on="CategoryId")["CategoryName"].tolist())
predicted_nontargeted_classes_names = (pd.DataFrame({"CategoryId": predicted_nontargeted_classes})
.merge(categories, on="CategoryId")["CategoryName"].tolist())
predicted_targeted_classes_names = (pd.DataFrame({"CategoryId": predicted_targeted_classes})
.merge(categories, on="CategoryId")["CategoryName"].tolist())
INFO:tensorflow:Restoring parameters from ../input/inception-v3/inception_v3.ckpt
下麵我們將展示這個批次中的所有圖像以及它們的分類的類別。每個集合中的左圖是原始圖像,中間圖是非目標對抗形象,右圖是目標對抗圖像。
for i in range(len(images)):
print("UNMODIFIED IMAGE (left)",
"\n\tPredicted class:", predicted_classes_names[i],
"\n\tTrue class: ", true_classes_names[i])
print("NONTARGETED ADVERSARIAL IMAGE (center)",
"\n\tPredicted class:", predicted_nontargeted_classes_names[i])
print("TARGETED ADVERSARIAL IMAGE (right)",
"\n\tPredicted class:", predicted_targeted_classes_names[i],
"\n\tTarget class: ", target_classes_names[i])
show_image(np.concatenate([images[i], nontargeted_images[i], targeted_images[i]], axis=1))
原圖(左圖)
預測類別:大熊貓
真實類別:大熊貓
非目標對抗圖片(中間圖)
預測類別:薩摩耶犬類
目標對抗圖片(右圖)
預測類別:土狗
真實類別:肉餅
原圖(左圖)
預測類別:
真實類別:
非目標對抗圖片(中間圖)
預測類別:堤壩
目標對抗圖片(右圖)
預測類別:堤壩
真實類別:
原圖(左圖)
預測類別:灰蝶
真實類別:灰蝶
非目標對抗圖片(中間圖)
預測類別:小環蝴蝶
目標對抗圖片(右圖)
預測類別:小環蝴蝶
真實類別:西班牙可卡犬
原圖(左圖)
預測類別:灰蝶
真實類別:灰蝶
非目標對抗圖片(中間圖)
預測類別:
目標對抗圖片(右圖)
預測類別:
真實類別:
原圖(左圖)
預測類別:美洲黑鴨
真實類別:美洲黑鴨
非目標對抗圖片(中間圖)
預測類別:短尾鸚鵡
目標對抗圖片(右圖)
預測類別:短尾鸚鵡
真實類別:泉水
原圖(左圖)
預測類別:短尾鸚鵡
真實類別:短尾鸚鵡
非目標對抗圖片(中間圖)
預測類別:籃球
目標對抗圖片(右圖)
預測類別:籃球
真實類別:單峰駱駝
原圖(左圖)
預測類別:球員
真實類別:球員
非目標對抗圖片(中間圖)
預測類別:鴕鳥
目標對抗圖片(右圖)
預測類別:鴕鳥
真實類別:金庫
原圖(左圖)
預測類別:鴕鳥
真實類別:鴕鳥
非目標對抗圖片(中間圖)
預測類別:日晷
目標對抗圖片(右圖)
預測類別:日晷
真實類別:海上鑽井平台
原圖(左圖)
預測類別:加農炮
真實類別:加農炮
非目標對抗圖片(中間圖)
預測類別:虎甲蟲
目標對抗圖片(右圖)
預測類別:虎甲蟲
真實類別:特濃咖啡機
原圖(左圖)
預測類別:長角天牛
真實類別:長角天牛
非目標對抗圖片(中間圖)
預測類別:特濃咖啡
目標對抗圖片(右圖)
預測類別:特濃咖啡
真實類別:髓內釘
原圖(左圖)
預測類別:特濃咖啡
真實類別:特濃咖啡
非目標對抗圖片(中間圖)
預測類別:淋浴帽
目標對抗圖片(右圖)
預測類別:淋浴帽
真實類別:
原圖(左圖)
預測類別:雪橇
真實類別:雪橇
非目標對抗圖片(中間圖)
預測類別:玫瑰果
目標對抗圖片(右圖)
預測類別:蜜蜂
真實類別:
原圖(左圖)
預測類別:大鋼琴
真實類別:大鋼琴
非目標對抗圖片(中間圖)
預測類別:書桌
目標對抗圖片(右圖)
預測類別:餐桌
真實類別:
原圖(左圖)
預測類別:間歇噴泉
真實類別:間歇噴泉
非目標對抗圖片(中間圖)
預測類別:沉船
目標對抗圖片(右圖)
預測類別:海狸
真實類別:
原圖(左圖)
預測類別:圖書館
真實類別:圖書館
非目標對抗圖片(中間圖)
預測類別:書店
目標對抗圖片(右圖)
預測類別:書店
真實類別:安全別針
原圖(左圖)
預測類別:鬆鴨
真實類別:鬆鴨
非目標對抗圖片(中間圖)
預測類別:鬆鴨
目標對抗圖片(右圖)
預測類別:黃雀
真實類別:針鼴
Ben Hamner:Kaggle。
Linkedinhttps://www.linkedin.com/in/ben-hamner-98759712/
Github: https://github.com/benhamner
Getting Started with the NIPS 2017 Adversarial Learning ChallengesBen Hamner
最後更新:2017-07-27 09:03:40