Why does torch.utils.save_image overwrite saved images in my folder?
I am trying an adversarial attack on 10 images and I need to save all the perturbed images in a folder. So, I used torch.utils.save_image in pytorch which works pretty fine. I expect all the images to be saved in the folder but instead, they are being overwritten and the last image seen is the only image saved. I have the following attack() function that takes a single image to perturb
def attack(img, label, net, target=None, pixels=1, maxiter=75, popsize=400, verbose=False):
    # img: 1*3*W*H tensor
    # label: a number

    targeted_attack = target is not None
    target_calss = target if targeted_attack else label

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

    popmul = max(1, popsize//len(bounds))

    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)

    inits = np.zeros([popmul*len(bounds), len(bounds)])
    
    count = 1
    for init in inits:
        for i in range(pixels):
            init[i*5+0] = np.random.random()*32
            init[i*5+1] = np.random.random()*32
            init[i*5+2] = np.random.normal(128,127)
            init[i*5+3] = np.random.normal(128,127)
            init[i*5+4] = np.random.normal(128,127)

    attack_result = differential_evolution(predict_fn, bounds, maxiter=maxiter, popsize=popmul,
        recombination=1, atol=-1, callback=callback_fn, polish=False, init=inits)

    attack_image = perturb_image(attack_result.x, img)
    # attack_var = Variable(attack_image, volatile=True).cuda()
    with torch.no_grad():
        attack_var = attack_image.to(device)
        predicted_probs = F.softmax(net(attack_var), dim=1).data.cpu().numpy()[0]

        predicted_class = np.argmax(predicted_probs)

    
    vutils.save_image(vutils.make_grid(attack_image, normalize=True, scale_each=True), 'result_img/adversarial' + str(count) + '.png')
    vutils.save_image(vutils.make_grid(img, normalize=True, scale_each=True), 'result_img/original' + str(count) + '.png')
    count = count + 1

    if (not targeted_attack and predicted_class != label) or (targeted_attack and predicted_class == target_calss):
        return 1, attack_result.x.astype(int)
    return 0, [None]

Below is the attack_all() function that perturbs batches of images (entire test set) which is 10 images in my case.
def attack_all(net, loader, pixels=1, targeted=False, maxiter=75, popsize=400, verbose=False):

    correct = 0
    success = 0

    for batch_idx, (input, target) in enumerate(loader):

        # img_var = Variable(input, volatile=True).cuda()
        with torch.no_grad():
            img_var = input.to(device)
            target = target

            prior_probs = F.softmax(net(img_var), dim=1)
            _, indices = torch.max(prior_probs, 1)
        
            if target[0] != indices.data.cpu()[0]:
                continue

            correct += 1
            target = target.numpy()

            targets = [None] if not targeted else range(10)

        for target_calss in targets:
            if (targeted):
                if (target_calss == target[0]):
                    continue

            flag, x = attack(input, target[0], net, target_calss, pixels=pixels, maxiter=maxiter, popsize=popsize, verbose=verbose)

            success += flag
            if (targeted):
                success_rate = float(success)/(9*correct)
            else:
                success_rate = float(success)/correct

            if flag == 1:
                print(&quot;success rate: %.4f (%d/%d) [(x,y) = (%d,%d) and (R,G,B)=(%d,%d,%d)]&quot;%(
                    success_rate, success, correct, x[0],x[1],x[2],x[3],x[4]))

        if correct == args.samples:
            break
    return success_rate

Below is the main() class where I am attacking the 10 images with attack_all(). I expect all the 10 images (both original and perturbed) to be saved but only the last seen image is saved.
def main():

    print (&quot;==&gt; Loading data and model...&quot;)
    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
        ])
    # test_set = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=tranfrom_test)
    test_set = Cifar10Dataset(csv_file='mydata/cifar10.csv', root_dir = 'mydata/cifar_selected_10', transform = transform_test)
    testloader = torch.utils.data.DataLoader(test_set, batch_size=1, shuffle=True, num_workers=2)

    class_names = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
    assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!'
    checkpoint = torch.load('./checkpoint/%s.t7'%args.model)
    net = checkpoint['net']
    net.cuda()
    cudnn.benchmark = True

    print (&quot;==&gt; Starting attack...&quot;)

    results = attack_all(net, testloader, pixels=args.pixels, targeted=args.targeted, maxiter=args.maxiter, popsize=args.popsize, verbose=args.verbose)
    print (&quot;Final success rate: %.4f&quot;%results)


So I figured out how to solve it myself.
I noticed that variable count in attack() will not increase no matter how. Instead, I set count = 1 outside attack() and did global count inside same attack(). This way, value of count can change and will not remain thesame everytime attack_all() calls the function attack().
