对抗样本:ICLR 2022 基于积分梯度的对抗攻击(可迁移的黑盒攻击)Transferable Attack based on Integrated Gradients (TAIG)

文章目录

感受:该论文提出的攻击算法,在实验中特别费时间,每一次迭代需要循环N次(N为batch_size的大小),因此需要消耗大量的时间去生成对抗样本。此外,用该论文的方法与2022年几篇顶会论文对比。发现该算法在白盒以及黑盒上的攻击表现都稍微低于其他顶会的攻击算法。
相对于经典的IFGSM、MIFGSM算法 有显著的提高。此外,结合的多种数学知识。作者将三种方法分别是优化标准目标函数、注意力图和平滑决策面集成到论文方法 TAIG 中,作者研究了两种计算直线路径和随机分段线性路径上积分梯度的 TAIG。实验结果表明,论文中提出的方法生成了高迁移性的对抗样本,并且可以与以前的方法进行无缝协同工作,而且 TAIG 的性能优于现有的方法。

论文链接:

https://arxiv.org/abs/2205.13152

代码链接:

https://github.com/yihuang2016/TAIG

参考论文概述
https://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/125288718

代码

#Transferable Adversarial Attack Based on Integrated Gradients (ICLR 2022) 该论文训练时间超级长
#TAIG-S 以及TAIG-R  后者表现最好
def compute_ig(inputs,label_inputs,model):
    steps = 20
    baseline = np.zeros(inputs.shape)
    scaled_inputs = [baseline + (float(i) / steps) * (inputs - baseline) for i in
                     range(0, steps + 1)]
    scaled_inputs = np.asarray(scaled_inputs)
    r_flag = True  # 等于False时 为TAIG-S
    if r_flag==True:
        # This is an approximate calculation of TAIG-R
        scaled_inputs = scaled_inputs + np.random.uniform(-epsilon,epsilon,scaled_inputs.shape)
    scaled_inputs = torch.from_numpy(scaled_inputs)
    scaled_inputs = scaled_inputs.cuda().float()
    #scaled_inputs=torch.float(scaled_inputs)
    scaled_inputs.requires_grad_(True)
    
            #loss = loss_fn(model(x_adv), y)
    #out = model(scaled_inputs)  
    #_, preds = torch.max(out.data, 1)
    #yp = Variable(preds.cuda())
    #loss = loss_fn(out, yp)
    
    
    att_out = model(scaled_inputs)
    score = att_out[:, label_inputs]
    loss = -torch.mean(score)
    model.zero_grad()
    loss.backward()
    
    
    grads = scaled_inputs.grad.data
    avg_grads = torch.mean(grads, dim=0)
    delta_X = scaled_inputs[-1] - scaled_inputs[0]
    integrated_grad = delta_X * avg_grads
    IG = integrated_grad.cpu().detach().numpy()
    del integrated_grad,delta_X,avg_grads,grads,loss, att_out ,score
    return IG


def IG(model, x, y, loss_fn,feature_layer, epsilon=epsilon, alpha=alpha, num_iter=20):#TAIG-R 
    x_adv = x
    # write a loop of num_iter to represent the iterative times
    for i in range(num_iter):
        # x_adv = fgsm(model, x_adv, y, loss_fn, alpha) # call fgsm with (epsilon = alpha) to obtain new x_adv
        x_adv = x_adv.detach().clone()
        x_adv.requires_grad = True
        
        steps = 20
        igs = []
        for im_i in range(list(x_adv.shape)[0]):
            inputs = x_adv[im_i].cpu().detach().numpy()
            label_inputs = y[im_i]
            integrated_grad = compute_ig(inputs, label_inputs, model)
            igs.append(integrated_grad)
        igs = np.array(igs)

        model.zero_grad()
        grad=torch.from_numpy(igs)
        grad=grad.cuda()
        
        x_adv = x_adv + alpha * grad.sign()
        
        delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon)
        x_adv = torch.clamp(x + delta, min=0, max=1).detach()
        
    return x_adv





def IG_MI(model, x, y, loss_fn,feature_layer, epsilon=epsilon, alpha=alpha, num_iter=20,decay=1.0):#TAIG-R-MI 
    x_adv = x
    momentum = torch.zeros_like(x).detach().cuda()
    # write a loop of num_iter to represent the iterative times
    for i in range(num_iter):
        # x_adv = fgsm(model, x_adv, y, loss_fn, alpha) # call fgsm with (epsilon = alpha) to obtain new x_adv
        x_adv = x_adv.detach().clone()
        x_adv.requires_grad = True
        
        steps = 20
        igs = []
        for im_i in range(list(x_adv.shape)[0]):
            inputs = x_adv[im_i].cpu().detach().numpy()
            label_inputs = y[im_i]
            integrated_grad = compute_ig(inputs, label_inputs, model)
            igs.append(integrated_grad)
        igs = np.array(igs)

        model.zero_grad()
        grad=torch.from_numpy(igs)
        grad=grad.cuda()
        
        grad = decay * momentum +  grad / (grad.abs().sum() + 1e-8)       
        momentum = grad
        x_adv = x_adv + alpha * grad.sign()
        
        delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon)
        x_adv = torch.clamp(x + delta, min=0, max=1).detach()
        
    return x_ad

猜你喜欢

转载自blog.csdn.net/weixin_41504611/article/details/129672766