5.6.3 使用TensorFlow实现JSMA
5.6.3 使用tensorflow实现jsma
下面介绍在tensorflow平台实现jsma算法的基本过程,示例代码位于:
https://github.com/duoergun0729/adversarial_examples/blob/master/code/
5-jsma-tensorflow-pb.ipynb
在示例中主要流程为,用原始图像的值初始化对抗样本,通过前向函数计算梯度,然后根据jsma算法迭代更新对抗样本,直到满足最大迭代次数或者对抗样本预测值等于攻击目标的标签为止,如图5-23所示。
下面我们介绍使用tensorflow实现jsma定向攻击的核心代码,首先定义全局参数包括迭代的最大次数、扰动系数、定向攻击目标的标签以及像素值的边界。
epochs=500
#扰动系数
theta=0.1
target_label=288
#定义边界
max_=255
min_=0
定义损失函数便于显示迭代计算过程中是否收敛,定义前向计算获取针对攻击目标的导数。
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_tensor,
labels=[target])
#前向计算过程非常缓慢
derivative = tf.gradients(logits_tensor[0,target_label], input_tensor)
图5-23 使用tensorflow实现jsma示例(定向攻击)
定义搜索空间mask,mask大小与输入一致。
mask = np.ones_like(adv_img)
下面开始迭代计算过程,迭代退出条件是达到最大迭代次数或者分类标签与攻击目标的标签相同,定向攻击成功,攻击成功时打印预测结果的top3。
for epoch in range(epochs):
s,d,l=session.run([logits_tensor,derivative,loss],
{target:target_label,input_tensor:adv_img})
predictions = np.squeeze(s)
top_k = predictions.argsort()[-3:][::-1]
predictions_id=top_k[0]
print("epoch={} loss={} label={}".format(epoch,l[0],predictions_id))
if predictions_id == target_label:
for node_id in top_k:
human_string = node_lookup.id_to_string(node_id)
score = predictions[node_id]
print('%s (score = %.5f)(id = %d)'
% (human_string, score,node_id))
break
通过saliency_map可以计算出当前最有利于提高定向攻击成功概率的像素坐标idx以及对应的方向pix_sign。
idx, pix_sign=saliency_map(d, mask)
# 进行扰动
adv_img[idx]+=pix_sign * theta * (max_ - min_)
#达到极限的点不再参与更新
if (adv_img[idx]<=min_) or (adv_img[idx]>=max_):
print("idx={} over {}".format(idx,adv_img[idx]))
mask[idx]=0
adv_img[idx]=np.clip(adv_img[idx], min_, max_)
saliency_map的具体实现方式为,根据前向计算获得的导数derivative计算出α参数,这里简化了β参数的计算,相当于只关注了α参数。
def saliency_map(derivative, mask):
alphas = derivative * mask
#用于记录哪些像素点被修改过
betas = -np.ones_like(alphas)
sal_map = np.abs(alphas) * np.abs(betas) * np.sign(alphas * betas)
#查找对攻击最有利的像素点
idx = np.argmin(sal_map)
#转换成(p1,p2)格式
idx = np.unravel_index(idx, mask.shape)
pix_sign = np.sign(alphas)[idx]
return idx, pix_sign
如图5-24所示,经过239轮迭代,攻击成功,l0为150即只修改了150个像素,l2为对抗样本与原始图像之间的差别。
epoch=237 loss=3.4565577507019043 label=46
epoch=238 loss=3.4611544609069824 label=46
epoch=239 loss=3.3630993366241455 label=288
l0=150 l2=413.5770786685355
snowmobile (score = 4.45301)(id = 288)
mexican hairless (score = 4.37416)(id = 46)
arabian camel, dromedary, camelus dromedarius (score = 4.24274)(id = 121)
图5-24 原始数据和对抗样本的对比示意图
下面介绍在tensorflow平台实现jsma算法的基本过程,示例代码位于:
https://github.com/duoergun0729/adversarial_examples/blob/master/code/
5-jsma-tensorflow-pb.ipynb
在示例中主要流程为,用原始图像的值初始化对抗样本,通过前向函数计算梯度,然后根据jsma算法迭代更新对抗样本,直到满足最大迭代次数或者对抗样本预测值等于攻击目标的标签为止,如图5-23所示。
下面我们介绍使用tensorflow实现jsma定向攻击的核心代码,首先定义全局参数包括迭代的最大次数、扰动系数、定向攻击目标的标签以及像素值的边界。
epochs=500
#扰动系数
theta=0.1
target_label=288
#定义边界
max_=255
min_=0
定义损失函数便于显示迭代计算过程中是否收敛,定义前向计算获取针对攻击目标的导数。
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_tensor,
labels=[target])
#前向计算过程非常缓慢
derivative = tf.gradients(logits_tensor[0,target_label], input_tensor)
图5-23 使用tensorflow实现jsma示例(定向攻击)
定义搜索空间mask,mask大小与输入一致。
mask = np.ones_like(adv_img)
下面开始迭代计算过程,迭代退出条件是达到最大迭代次数或者分类标签与攻击目标的标签相同,定向攻击成功,攻击成功时打印预测结果的top3。
for epoch in range(epochs):
s,d,l=session.run([logits_tensor,derivative,loss],
{target:target_label,input_tensor:adv_img})
predictions = np.squeeze(s)
top_k = predictions.argsort()[-3:][::-1]
predictions_id=top_k[0]
print("epoch={} loss={} label={}".format(epoch,l[0],predictions_id))
if predictions_id == target_label:
for node_id in top_k:
human_string = node_lookup.id_to_string(node_id)
score = predictions[node_id]
print('%s (score = %.5f)(id = %d)'
% (human_string, score,node_id))
break
通过saliency_map可以计算出当前最有利于提高定向攻击成功概率的像素坐标idx以及对应的方向pix_sign。
idx, pix_sign=saliency_map(d, mask)
# 进行扰动
adv_img[idx]+=pix_sign * theta * (max_ - min_)
#达到极限的点不再参与更新
if (adv_img[idx]<=min_) or (adv_img[idx]>=max_):
print("idx={} over {}".format(idx,adv_img[idx]))
mask[idx]=0
adv_img[idx]=np.clip(adv_img[idx], min_, max_)
saliency_map的具体实现方式为,根据前向计算获得的导数derivative计算出α参数,这里简化了β参数的计算,相当于只关注了α参数。
def saliency_map(derivative, mask):
alphas = derivative * mask
#用于记录哪些像素点被修改过
betas = -np.ones_like(alphas)
sal_map = np.abs(alphas) * np.abs(betas) * np.sign(alphas * betas)
#查找对攻击最有利的像素点
idx = np.argmin(sal_map)
#转换成(p1,p2)格式
idx = np.unravel_index(idx, mask.shape)
pix_sign = np.sign(alphas)[idx]
return idx, pix_sign
如图5-24所示,经过239轮迭代,攻击成功,l0为150即只修改了150个像素,l2为对抗样本与原始图像之间的差别。
epoch=237 loss=3.4565577507019043 label=46
epoch=238 loss=3.4611544609069824 label=46
epoch=239 loss=3.3630993366241455 label=288
l0=150 l2=413.5770786685355
snowmobile (score = 4.45301)(id = 288)
mexican hairless (score = 4.37416)(id = 46)
arabian camel, dromedary, camelus dromedarius (score = 4.24274)(id = 121)
图5-24 原始数据和对抗样本的对比示意图