Usage of torchvision.modules.resnet18

Hello everyone,

I am a math student and I managed to create my first deep neural network (named “Net()”) for ‘CIFAR-10’. Now I tried to use “torchvision.modules.resnet18” instead and I get the following errors in my report file:

Report file (trimmed)

Precompute adversarial examples.:   0%|          | 0/1 [00:00<?, ?it/s]
Precompute adversarial examples.: 100%|██████████| 1/1 [00:00<00:00, 22310.13it/s]

Adversarial training epochs:   0%|          | 0/2 [00:00<?, ?it/s]
Adversarial training epochs:   0%|          | 0/2 [00:00<?, ?it/s]
50000
Loaded data.
Loaded model.
Traceback (most recent call last):
  File "AlternativModel1.py", line 115, in <module>
    trainer.fit_generator(train_generator, nb_epochs=num_epochs)
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/defences/trainer/adversarial_trainer.py", line 167, in fit_generator
    x_batch[adv_ids] = attack.generate(x_batch[adv_ids], y=y_batch[adv_ids])
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/attacks/attack.py", line 74, in replacement_function
    return fdict[func_name](self, *args, **kwargs)
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/attacks/evasion/fast_gradient.py", line 227, in generate
    batch_size=self.batch_size,
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/utils.py", line 581, in compute_success
    attack_success = compute_success_array(classifier, x_clean, labels, x_adv, targeted, batch_size)
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/utils.py", line 551, in compute_success_array
    adv_preds = np.argmax(classifier.predict(x_adv, batch_size=batch_size), axis=1)
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/estimators/classification/classifier.py", line 71, in replacement_function
    return fdict[func_name](self, *args, **kwargs)
  File "/cluster/home/lgraz/RDNN/rdnn-env/lib64/python3.7/site-packages/art/estimators/classification/pytorch.py", line 204, in predict
    results[begin:end] = output.detach().cpu().numpy()
ValueError: could not broadcast input array from shape (32,1000) into shape (32,10)

Here is my source-code

"""
We recommend using a more complex model,
such as a ResNet (available in torchvision) and more complex attacks/defenses.
"""

import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.datasets as datasets
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data as data
from torchvision import transforms
import numpy as np

from art.attacks.evasion import FastGradientMethod
from art.defences.trainer import AdversarialTrainer
from art.estimators.classification import PyTorchClassifier

import rdnn.torch

# Step 0: initialize some parameters that we will use later, as well as the dataset
batch_size = 128
num_epochs = 2
learning_rate = 1e-3
num_classes = 10 ##################################



# We use data augmentation to increase the test accuracy of our classifier
transform_train = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(15),
    transforms.RandomAffine(degrees=0, translate=(0, 5./32)),
    transforms.ToTensor(),
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
])

# Initialize the training and test datasets
train_dataset = rdnn.torch.CifarDataset(train=True, transform=transform_train)
train_dataloader = data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
print(len(train_dataset))
train_generator = rdnn.torch.CustomDataGenerator(train_dataloader, size=len(train_dataset), batch_size=batch_size)

test_dataset = rdnn.torch.CifarDataset(train=False, transform=transform_test)
x_test = test_dataset.get_x()
y_test = test_dataset.get_y()

print("Loaded data.")

# Define Module Architecture 
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.conv3 = nn.Conv2d(64, 56, kernel_size=3, stride=1, padding=1)
        self.dropout = nn.Dropout(0.2)
        self.fc1 = nn.Linear(56 * 4 * 4, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.leaky_relu(self.conv2(x), negative_slope=0.1))
        x = F.relu(self.conv3(x))
        x = x.view(-1, 56 * 4 * 4)
        x = self.dropout(x)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

'''
    instead of Net(), I would like to use resnet18()
    what am I doing wrong?
'''
# model = Net()
model = models.resnet18()
model.train()

print("Loaded model.")

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)


# Create the ART wrapper classifier (an instance of PyTorchClassifier).
classifier = PyTorchClassifier(
    model=model,
    clip_values=None,
    loss=criterion,
    optimizer=optimizer,
    input_shape=(3, 32, 32),
    nb_classes=10,
)

# Step 4: Train your classifier with natural examples
classifier.fit_generator(train_generator, nb_epochs=num_epochs)

# Create an FGSM attack. To do this, you should first create an instance
attacks = FastGradientMethod(estimator=classifier, eps=0.03)

# ======= Only fill in this step after having trained your classifier naturally =======
# Step 5: Train a robust classifier.
# Once that is done, we will use ART's AdversarialTrainer class to train your model using the 
# attack you defined for 10 epochs with a batch size of 128. Use 0.5 for the ratio of adversarial
# examples to natural examples.
trainer = AdversarialTrainer(classifier, attacks, ratio=0.5)
trainer.fit_generator(train_generator, nb_epochs=num_epochs)
# =====================================================================================

# Step 6: Save model checkpoint using the util code introduced in the tutorial.
rdnn.torch.save_model(model, optimizer, num_epochs, name="my_second_checkpoint")
model.eval()

eval_attacks = FastGradientMethod(estimator=classifier, eps=0.03)

# Step 7: Evaluate the ART classifier on natural test examples and find the accuracy
x_test_adv = eval_attacks.generate(x_test)
predictions = classifier.predict(x_test)
accuracy = np.sum(np.argmax(predictions, axis=1) == y_test) / len(y_test)
print("Accuracy on benign test examples: {}%".format(accuracy * 100))
predictions_adv = classifier.predict(x_test_adv)
accuracy_adv = np.sum(np.argmax(predictions_adv, axis=1) == y_test) / len(y_test)
print("Accuracy on adversarial examples: {}%".format(accuracy_adv * 100))

Simply change the last fc layer to output 10 classes instead of the original 1000 classes.

model = models.resnet18()
model.fc = nn.Linear(model.fc.in_features, 10)

Thank you, It worked :slight_smile:

now there arises another issue. I would like to load a checkpoint and attack it (with adversarial perturbed images).
We have been provided the following loading function:

def load_model(path, model, from_shared_group_dir=True):
    """
    Loads the given model with the parameters found in the checkpoint at the given path, and returns
    the optimizer, epoch, and misc_dict saved in the checkpoint. If from_shared_group_dir
    is True, can be used as rdnn.torch.load_model("<location in group dir>", model).
    """
    if from_shared_group_dir:
        path = os.path.join(rdnn.group_dir, path)
    checkpoint = torch.load(path)
    model.load_state_dict(checkpoint['model_state_dict'])
    return checkpoint['optimizer'], checkpoint['epoch'], checkpoint['misc_dict']

The following syntax seems to be invalid and I don’t know what to change

"""
atack: ratio_0_6928571428571428   in    krimmelm_2020-11-27_13.01.37_247514
"""

import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.datasets as datasets
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data as data
from torchvision import transforms
import numpy as np
from art.attacks.evasion import FastGradientMethod
from art.defences.trainer import AdversarialTrainer
from art.estimators.classification import PyTorchClassifier
import rdnn.torch

# Step 0: initialize some parameters that we will use later, as well as the dataset
batch_size = 128
num_epochs = 10
learning_rate = 1e-3
num_classes = 10 ##################################

# We use data augmentation to increase the test accuracy of our classifier
transform_train = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(15),
    transforms.RandomAffine(degrees=0, translate=(0, 5./32)),
    transforms.ToTensor(),
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
])

# Initialize the training and test datasets
train_dataset = rdnn.torch.CifarDataset(train=True, transform=transform_train)
train_dataloader = data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
print(len(train_dataset))
train_generator = rdnn.torch.CustomDataGenerator(train_dataloader, size=len(train_dataset), batch_size=batch_size)

test_dataset = rdnn.torch.CifarDataset(train=False, transform=transform_test)
x_test = test_dataset.get_x()
y_test = test_dataset.get_y()

print("Loaded data.")

# Define Module Architecture 
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.conv3 = nn.Conv2d(64, 56, kernel_size=3, stride=1, padding=1)
        self.dropout = nn.Dropout(0.2)
        self.fc1 = nn.Linear(56 * 4 * 4, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.leaky_relu(self.conv2(x), negative_slope=0.1))
        x = F.relu(self.conv3(x))
        x = x.view(-1, 56 * 4 * 4)
        x = self.dropout(x)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = Net()
optimizer, epoch, misc_dict = rdnn.torch.load_model(krimmelm_2020-11-27_13.01.37_247514/ratio_0_6928571428571428, model, from_shared_group_dir=True)
######################## THE ABOVE IS INVALID ######################################

print("Loaded model.")

criterion = nn.CrossEntropyLoss()
# optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Create the ART wrapper classifier (an instance of PyTorchClassifier).
classifier = PyTorchClassifier(
    model=model,
    clip_values=None,
    loss=criterion,
    optimizer=optimizer,
    input_shape=(3, 32, 32),
    nb_classes=10,
)

# Step 4: Train your classifier with natural examples
########### classifier.fit_generator(train_generator, nb_epochs=num_epochs)

# Create an FGSM attack. To do this, you should first create an instance
attacks = FastGradientMethod(estimator=classifier, eps=0.03)

# ======= Only fill in this step after having trained your classifier naturally =======
# Step 5: Train a robust classifier.
# Once that is done, we will use ART's AdversarialTrainer class to train your model using the 
# attack you defined for 10 epochs with a batch size of 128. Use 0.5 for the ratio of adversarial
# examples to natural examples.
##################### trainer = AdversarialTrainer(classifier, attacks, ratio=0.5)
##################### trainer.fit_generator(train_generator, nb_epochs=num_epochs)
# =====================================================================================

# Step 6: Save model checkpoint using the util code introduced in the tutorial.
##############  rdnn.torch.save_model(model, optimizer, num_epochs, name="my_second_checkpoint")
model.eval()

eval_attacks = FastGradientMethod(estimator=classifier, eps=0.03)

# Step 7: Evaluate the ART classifier on natural test examples and find the accuracy
x_test_adv = eval_attacks.generate(x_test)
predictions = classifier.predict(x_test)
accuracy = np.sum(np.argmax(predictions, axis=1) == y_test) / len(y_test)
print("Accuracy on benign test examples: {}%".format(accuracy * 100))
predictions_adv = classifier.predict(x_test_adv)
accuracy_adv = np.sum(np.argmax(predictions_adv, axis=1) == y_test) / len(y_test)
print("Accuracy on adversarial examples: {}%".format(accuracy_adv * 100))

what kind of error do you get?

This error also resolved,
thank you anyway :smiley: