【跟踪器攻击】IOU Attack 代码解读

简介

提出了 IoU 攻击,它根据当前帧和历史帧的预测 IoU 分数顺序生成扰动。通过降低 IoU 分数,所提出的攻击方法相应地降低了时间相干边界框(即对象运动)的准确性。此外,我们将学习到的扰动转移到接下来的几帧以初始化时间运动攻击。我们在最先进的深度跟踪器(即基于检测、基于相关滤波器和长期跟踪器)上验证了提议的 IoU 攻击。对基准数据集的大量实验表明了所提出的 IoU 攻击方法的有效性。源代码可在此 https URL 处获得。

代码

加载模型

def load_pretrain(model, pretrained_path):
    logger.info('从 {} 加载预训练模型'.format(pretrained_path))  # 使用 logger.info 记录加载预训练模型的信息
    device = torch.cuda.current_device()  # 获取当前 CUDA 设备
    pretrained_dict = torch.load(pretrained_path,  # 加载预训练权重
                                 map_location=lambda storage, loc: storage.cuda(device))
    if "state_dict" in pretrained_dict.keys():
        pretrained_dict = remove_prefix(pretrained_dict['state_dict'], 'module.')  # 去除键名中的 'module.' 前缀
    else:
        pretrained_dict = remove_prefix(pretrained_dict, 'module.')  # 去除键名中的 'module.' 前缀

    try:
        check_keys(model, pretrained_dict)  # 检查加载的权重与模型的键是否匹配
    except:
        logger.info('[警告]: 将预训练权重用作特征。添加 "features." 前缀')  # 如果键不匹配,记录警告信息
        new_dict = {}
        for k, v in pretrained_dict.items():
            k = 'features.' + k  # 在键名前添加 'features.' 前缀
            new_dict[k] = v
        pretrained_dict = new_dict
        check_keys(model, pretrained_dict)  # 检查修改后的权重与模型的键是否匹配
    model.load_state_dict(pretrained_dict, strict=False)  # 将加载的权重加载到模型中,strict=False 允许部分加载权重
    return model  # 返回加载了预训练权重的模型

计算IOU

def overlap_ratio(rect1, rect2):
    '''
    Compute overlap ratio between two rects
    - rect: 1d array of [x,y,w,h] or
            2d array of N x [x,y,w,h]
    '''
    rect1 = np.transpose(rect1)

    if rect1.ndim==1:
        rect1 = rect1[None,:]
    if rect2.ndim==1:
        rect2 = rect2[None,:]
        
    left = np.maximum(rect1[:,0], rect2[:,0])
    right = np.minimum(rect1[:,0]+rect1[:,2], rect2[:,0]+rect2[:,2])
    top = np.maximum(rect1[:,1], rect2[:,1])
    bottom = np.minimum(rect1[:,1]+rect1[:,3], rect2[:,1]+rect2[:,3])

    intersect = np.maximum(0,right - left) * np.maximum(0,bottom - top)
    union = rect1[:,2]*rect1[:,3] + rect2[:,2]*rect2[:,3] - intersect
    iou = np.clip(intersect / union, 0, 1)
    return iou

orthogonal_perturbation:生成两个样本之间的正交扰动。给定先前样本 prev_sample 和目标样本 target_sample,该函数通过计算它们之间的差异,并生成一个正交于差异向量的扰动,用于对先前样本进行微小的调整以接近目标样本。

def orthogonal_perturbation(delta, prev_sample, target_sample):
    # 计算调整大小的尺寸
    size = int(max(prev_sample.shape[0]/4, prev_sample.shape[1]/4, 224))
    
    # 调整大小的 prev_sample 和 target_sample
    prev_sample_temp = np.resize(prev_sample, (size, size, 3))
    target_sample_temp = np.resize(target_sample, (size, size, 3))
    
    # 生成扰动
    perturb = np.random.randn(size, size, 3)
    perturb /= get_diff(perturb, np.zeros_like(perturb))  # 归一化扰动数组
    perturb *= delta * np.mean(get_diff(target_sample_temp, prev_sample_temp))  # 缩放扰动数组
    
    # 将扰动投影到目标周围的球面上
    diff = (target_sample_temp - prev_sample_temp).astype(np.float32)  # 计算目标和前一个样本之间的差异
    diff /= get_diff(target_sample_temp, prev_sample_temp)  # 归一化差异向量
    diff = diff.reshape(3, size, size)  # 重塑差异向量的形状
    
    perturb = perturb.reshape(3, size, size)  # 重塑扰动数组的形状
    for i, channel in enumerate(diff):
        proj = np.dot(perturb[i], channel)  # 计算扰动数组与差异向量通道的点积
        perturb[i] -= proj * channel  # 将扰动数组投影到差异向量通道的正交补空间上
    
    perturb = perturb.reshape(size, size, 3)  # 重塑扰动数组的形状
    perturb_temp = np.resize(perturb, (prev_sample.shape[0], prev_sample.shape[1], 3))  # 调整大小以匹配 prev_sample 的形状
    
    return perturb_temp

forward_perturbation

def forward_perturbation(epsilon, prev_sample, target_sample):
    perturb = (target_sample - prev_sample).astype(np.float32)
    perturb /= get_diff(target_sample, prev_sample)
    perturb *= epsilon
    return perturb

每个channel 计算linalg差距

def get_diff(sample_1, sample_2):
    sample_1 = sample_1.reshape(3, sample_1.shape[0], sample_1.shape[1])
    sample_2 = sample_2.reshape(3, sample_2.shape[0], sample_2.shape[1])
    sample_1 = np.resize(sample_1, (3, 271, 271))
    sample_2 = np.resize(sample_2, (3, 271, 271))

    diff = []
    for i, channel in enumerate(sample_1):
        diff.append(np.linalg.norm((channel - sample_2[i]).astype(np.float32)))
    return np.array(diff)

评估

cd pysot/experiments/siamrpn_r50_l234_dwxcorr
python -u ../../tools/test_IoU_attack.py 	\
	--snapshot model.pth 	\ # model path
	--dataset VOT2018 	\ # dataset name
	--config config.yaml	  # config file
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值