Some background first: currently some popular libraries (e.g., foolbox 10) generate adversarial attacks per image, which means at a time the loss is computed from a single image and then the gradients are backpropagated to the input image.  An example from our repo 12 is as below.
In this way, one has to write a for loop in order to generate adversarial examples over the data. This can be slow in the situation of adversarial training in which adversarial perturbations are needed in each training epoch (code 9). I am wondering is it possible to generate adversarial examples in batches using PyTorch, which full utilizes the power of GPUs.
class FGSMAttack(object):
    def __init__(self, model=None, epsilon=None):
        """
        One step fast gradient sign method
        """
        self.model = model
        self.epsilon = epsilon
        self.loss_fn = nn.CrossEntropyLoss()

    def perturb(self, x_nat, y):
        """
        Given one example (x_nat, y), returns its adversarial
        counterpart with an attack length of epsilon.
        """
        x = np.copy(x_nat)

        x_var = to_var(torch.from_numpy(x), requires_grad=True)
        y_var = to_var(torch.LongTensor([int(y)]))

        scores = self.model(x_var)
        loss = self.loss_fn(scores, y_var)
        loss.backward()
        grad_sign = x_var.grad.data.cpu().sign().numpy()

        x += self.epsilon * grad_sign
        x = np.clip(x, 0, 1)

        return x