0

我遇到了一个实现,其中在32x32图像大小上运行差分进化,最终选择图像中的单个像素进行进一步操作(例如扰动)。我目前正在研究如何将类似的方法应用于图像的补丁而不是像素。

像素实现遵循以下路线:

一种预测图像类别的方法。xs是从差分进化中选择的像素。

def predict_classes(xs, img, target_calss, net, minimize=True):
    imgs_perturbed = perturb_image(xs, img.clone())
    with torch.no_grad():
        input = imgs_perturbed.to(device)
        predictions = F.softmax(net(input), dim=1).data.cpu().numpy()[:, target_calss]

    return predictions if minimize else 1 - predictions

设置搜索限制的界限

bounds = [(0,32), (0,32), (0,255), (0,255), (0,255)] * pixels

前两个 (0, 32) 是进行像素搜索的图像高度和宽度。最后三个 (0, 255) 是颜色通道的范围。像素只是我们想要搜索和更改的像素数,视情况而定。

predict_function传递callback_function给差分进化如下:

predict_fn = lambda xs: predict_classes(xs, img, target_calss, net, target is None)
callback_fn = lambda x, convergence: attack_success(x, img, target_calss, net, targeted_attack, verbose)

然后通过以下方式应用差分进化

outcome = differential_evolution(predict_function, bounds, maxiter=maxiter, popsize=popmul, recombination=1, atol=-1, callback_function, polish=False)

结果的结果预计是选定的像素。然后按如下方式扰动该像素。

dented_image = perturb(outcome.x, img)

我正在做的是搜索一个补丁而不是像素,并推荐最好的补丁来扰动。我一直致力于像素实现,它对我来说工作得很好。为了尝试基于补丁的方法,我将图像划分为补丁,并暂时只用黑色扰动一个补丁(稍后我必须组合 3 个通道)

def perturb_patch(img, patch_to_perturb, kernel_size, stride):
    trans = transforms.Compose([transforms.ToTensor()])
    img = trans(img)
    img = img.unsqueeze(0)
    u = nnf.unfold(img, kernel_size=kernel_size, stride=stride,  padding=0)
    u[..., patch_to_perturb] = 0
    f = nnf.fold(u, img.shape[-2:], kernel_size=kernel_size, stride=stride, padding=0) 
    return f

使用以下方式将我的大小图像划分(224 x224)196补丁。每个补丁都是16 x 16.

img = Image.open("my_image.jpeg")
img = img.resize((224, 224), resample=0)
img = perturb_patch(img, 104, 16, 16)

在这种情况下,与查找单个像素不同,每个补丁都有256像素。我需要在补丁上应用差分进化并推荐一个补丁来扰动。我不知道该怎么做。我也一定会感谢任何帮助解决问题的人。

4

0 回答 0