-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of Auto Conjugate Gradient Attack #2028
Conversation
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Hi @yamamura-k Thank you very much for contributing your attack to ART and congratulations for your ICML paper! I think your attack will be very useful for many users of ART. What kind of changes would be required to the ART estimators to support batches of size 2 or larger with the best attack performance? Maybe we can add the required functionality. |
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more @@ Coverage Diff @@
## dev_1.14.0 #2028 +/- ##
==============================================
+ Coverage 84.19% 85.59% +1.39%
==============================================
Files 292 293 +1
Lines 25798 26158 +360
Branches 4665 4733 +68
==============================================
+ Hits 21720 22389 +669
+ Misses 2882 2554 -328
- Partials 1196 1215 +19
|
@beat-buesser |
Hi @yamamura-k |
@beat-buesser Thank you for your comment. I think your suggestion can solve my problem. I misunderstood that the I will fix my implementation later. Also, I can modify the implementation of |
@beat-buesser Does the |
Hi @yamamura-k I think it would be amazing if you could upgrade your ACG and ART's APGD attacks to account for per sample step sizes! I think you are asking important questions, this is what I think:
What do you think? |
@beat-buesser Thank you for your comments and suggestions.
I understand your opinion, and basically agree with you. However, the problem is how to satisfy the following conflicting requirements.
I think
loss = self._loss(model_outputs[-1], labels_t) #line 843 in adversarial-robustness-toolbox/art/estimators/classification/pytorch.py
# My suggestion
if len(loss.shape) == 1 and loss.shape[0] > 1:
loss = loss.mean() # reduce the loss
elif len(loss.shape) > 1:
raise ValueError
# !My suggestion
# Clean gradients
self._model.zero_grad()
# Compute gradients
if self._use_amp: # pragma: no cover
from apex import amp # pylint: disable=E0611
with amp.scale_loss(loss, self._optimizer) as scaled_loss:
scaled_loss.backward()
else:
loss.backward()
These are what I'm thinking about. Would you tell me your opinion? |
Hi @yamamura-k I think your considerations are correct and important. ART expects Your last proposal of passing the keyword argument adversarial-robustness-toolbox/art/estimators/classification/pytorch.py Lines 743 to 748 in eadbe6d
where we save the original reduction option to prev_reduction and set the reduction option defined in the keyword argument with self._loss.reduction = reduction . In the next lines we revert self._loss.reduction to the original reduction option.
I have run a short test based on one of ART's example scripts which trains a import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
from art.attacks.evasion import FastGradientMethod
from art.estimators.classification import PyTorchClassifier
from art.utils import load_mnist
# Step 0: Define the neural network model, return logits instead of activation in forward method
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv_1 = nn.Conv2d(in_channels=1, out_channels=4, kernel_size=5, stride=1)
self.conv_2 = nn.Conv2d(in_channels=4, out_channels=10, kernel_size=5, stride=1)
self.fc_1 = nn.Linear(in_features=4 * 4 * 10, out_features=100)
self.fc_2 = nn.Linear(in_features=100, out_features=10)
def forward(self, x):
x = F.relu(self.conv_1(x))
x = F.max_pool2d(x, 2, 2)
x = F.relu(self.conv_2(x))
x = F.max_pool2d(x, 2, 2)
x = x.view(-1, 4 * 4 * 10)
x = F.relu(self.fc_1(x))
x = self.fc_2(x)
return x
# Step 1: Load the MNIST dataset
(x_train, y_train), (x_test, y_test), min_pixel_value, max_pixel_value = load_mnist()
# Step 1a: Swap axes to PyTorch's NCHW format
x_train = np.transpose(x_train, (0, 3, 1, 2)).astype(np.float32)
x_test = np.transpose(x_test, (0, 3, 1, 2)).astype(np.float32)
# Step 2: Create the model
model = Net()
# Step 2a: Define the loss function and the optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
# Step 3: Create the ART classifier
classifier = PyTorchClassifier(
model=model,
clip_values=(min_pixel_value, max_pixel_value),
loss=criterion,
optimizer=optimizer,
input_shape=(1, 28, 28),
nb_classes=10,
)
# Step 4: Train the ART classifier
classifier.fit(x_train, y_train, batch_size=64, nb_epochs=3)
print("mean")
print(classifier.compute_loss(x=x_test[:10], y=y_test[:10], reduction="mean"))
print("none")
print(classifier.compute_loss(x=x_test[:10], y=y_test[:10], reduction="none")) This script should print something like mean
0.011778888
none
[ 7.0333235e-06 1.9073468e-06 2.7418098e-06 1.0013530e-05
1.1394425e-02 -0.0000000e+00 2.2188823e-03 2.7656173e-05
1.0411299e-01 1.3232144e-05] Would this provide the required loss values for ACG attack? |
@beat-buesser Thank you for your explanation about the functionality of ART. I think the explained functionality satisfies my requirements. Then I will try my second proposal and push the commits later. |
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
…able the image-wise stepsize update Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
@beat-buesser I modified the implementation of ACG and APGD to enable the image-wise stepsize updates in this pull request. Thank you for your patience and valuable comments and suggestions. |
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Hi @yamamura-k I think the proposed changes above should fix the style checks. What do you think? |
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Hi @beat-buesser, the codes changed by your suggestion fix the style checks, and no new warnings are raised. Thank you so much! |
Signed-off-by: yamamura-k <yamayama23bb@gmail.com>
Hi @yamamura-k Thank you very much for contributing your attack Auto Conjugate Gradient Attack (ICML 2022) to ART! It will be part of ART 1.14! |
@beat-buesser Thank you very much for your patience in working with me to modify the code! |
…I#2028 because pytorch estimators do not recognize the class created in AGPD and thus do not correctly handle the labels anymore
Description
I implemented a new attack method Auto Conjugate Gradient attack proposed in "Diversified Adversarial Attacks based on Conjugate Gradient Method", ICML2022. paper link(arxiv)
This implementation works poor when the batch size is greater than or equal to 2 because the way to treat the loss and step size condition is different from the original implementation. The implementation of APGD also has the same issue, and to fix this, we have to modify the wrapper class of the threat model (e.g. PyTorchClassifier). Due to this reason, we imitate the implementation of APGD to avoid large modification.
Type of change
Please check all relevant options.
Testing
The test of ACG is the same to that of APGD because ACG is very similar to APGD.
tests/attacks/evasion/test_auto_conjugate_gradient.py
)Test Configuration:
Checklist