Multi output resent + foolbox.models.PyTorchModel

In my main ResNet block as below:

class ResNet(nn.Module):
    def __init__(self, block, num_blocks, num_classes=10):
        super(ResNet, self).__init__()
        self.in_planes = 64

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
        self.linear = nn.Linear(512*block.expansion, num_classes)

    def _make_layer(self, block, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []
        for stride in strides:
            layers.append(block(self.in_planes, planes, stride))
            self.in_planes = planes * block.expansion
        return nn.Sequential(*layers)

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)
        out = F.avg_pool2d(out, 4)
        out0 = out.view(out.size(0), -1)
        out = self.linear(out0)
        return out, out0

I want to output two last layers, i.e. out & out0 here.
In my main code I try to use foolbox for say fgsm attack. So just giving a few lines I have:

fmodel_source = foolbox.models.PyTorchModel(model, bounds=(0, 1), num_classes=10, preprocessing=(0, 1))
attack = foolbox.attacks.GradientSignAttack(model=fmodel_source, criterion=attack_criteria)

Then trying to execute the line
adversarial = attack(inputs.astype(np.float32), targets, max_epsilon=config['epsilon'])

I get error that
File “anaconda36/lib/python3.6/site-packages/foolbox/models/pytorch.py”, line 94, in batch_predictions
predictions = predictions.to(“cpu”)
AttributeError: ‘tuple’ object has no attribute ‘to’

Is there a way I get around this and still have the last two layers outputs from the ResNet but don’t change the foolbox under pytorch.py?

Any suggestions?

I’m not familiar with foolbox, but it seems as if the attack expects your model to output a single tensor, while your model outputs two.
If you don’t need out0 for the training (or something else), just remove it from the return statement.