Trusted-AI / adversarial-robustness-toolbox

Adversarial Robustness Toolbox (ART) - Python Library for Machine Learning Security - Evasion, Poisoning, Extraction, Inference - Red and Blue Teams

Home Page:https://adversarial-robustness-toolbox.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Square Attack Bug: Tensor shape mismatch resulting in ValueError when attempting broadcast

CrimsonScythe opened this issue · comments

Describe the bug
Tensor shape mismatch resulting in ValueError when attempting broadcast. E.g.:
ValueError: could not broadcast input array from shape (3,1,1) into shape (1,0,200,224)
The error occurs on the delta_new assignment:
image

I fixed it by harcoding the dimensions and removing the batch size. i.e. resizing to (3,224,224)

To Reproduce
Steps to reproduce the behavior:

  1. Run Square Attack with inputs of dimensions NCHW. My inputs were of shape (1,3,224,224)

Expected behavior
Error free execution

Screenshots
If applicable, add screenshots to help explain your problem.

System information (please complete the following information):

  • OS: MacOS Ventura
  • Python version: 3.8.16
  • PyTorch version: 1.12.0

Hi @CrimsonScythe Thank you for using ART! How did you define the classifier?

I am using a pretrained model and wrapping in a PytorchClassifier like so:
classifier = PyTorchClassifier( model=model, loss=nn.CrossEntropyLoss(), input_shape=(1, 3, 224, 224), nb_classes=2, clip_values=(-2,2) )
The model itself is defined like:
`import torch
from torch.nn.modules.activation import Softmax
from models import BaseDNN
from torch import nn
from torch.nn import functional as F
from .types_ import *
import numpy as np
from torchvision import models

'''
Softmax version of DeepPixelBisSig
'''

class DeepPixelBis(BaseDNN):

def __init__(self,
             channel_num: int,
             **kwargs) -> None:
    super(DeepPixelBis, self).__init__()

    model_ft = models.densenet161(pretrained=True)

    features = list(model_ft.features.children())

    self.enc = nn.Sequential(*features[0:8])

    self.dec = nn.Conv2d(384, 1, kernel_size=1, padding=0)

    self.linear = nn.Linear(14 * 14, 2)

    self.ce = nn.CrossEntropyLoss()
    self.pixel_ce = nn.BCELoss()


    
def predict(self, input: Tensor) -> Any:
    
    enc = self.enc(input)

    dec = self.dec(enc)

    dec = nn.Sigmoid()(dec)

    dec_flat = dec.view(-1, 14 * 14)

    op = self.linear(dec_flat)

    op = nn.Softmax(dim=1)(torch.tensor(op))

    return dec_flat, op

def forward(self, input: Tensor, **kwargs) -> List[Tensor]:

    ### for running foolbox based attacks
    return self.predict(input)[1]

    ### for training softmax based classifier
    # return  [self.predict(input), kwargs['labels']]

def loss_function(self,
                  *args,
                  **kwargs) -> dict:
    """
    Computes the cross_entropy loss function.
    :param args:
    :param kwargs:
    :return:
    """
    embedding, classification_output = args[0]
    real_labels, real_labels_pixel_wise = args[1]

    beta = 0.5

    classification_output = nn.Softmax(dim=1)(classification_output)

    loss_binary = self.ce(classification_output[:,1], real_labels.float())
    loss_pixel = self.pixel_ce(embedding, real_labels_pixel_wise.float())

    return {'loss': beta*loss_binary + (1 - beta)*loss_pixel, 'Classification_loss': loss_binary, 'Pixel_wise': loss_pixel}

def accuracy(self,
                  *args,
                  **kwargs) -> dict:
    """
    Computes the accuracy.
    :param args:
    :param kwargs:
    :return:
    """
    _, classification_output = args[0]

    real_labels, _ = args[1]

    winner = classification_output[:, 1]

    winner[winner >= 0.5] = 1
    winner[winner < 0.5] = 0

    accuracy = (winner== real_labels).sum().float()/real_labels.size(0)*100
    return {'accuracy': accuracy}`

Solved. My mistake, PyTorch Classifier expects input_shape to be the shape of a single input instance excluding batch dimension so should be (3,224,224) instead of (1,3,224,224).