Skip to content

Commit

Permalink
v3.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Harry24k committed Jul 8, 2021
1 parent 681dd9f commit 9f1969a
Show file tree
Hide file tree
Showing 43 changed files with 2,403 additions and 2,256 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ sample.pth
_old/*
.ipynb_checkpoints/*
TODO.txt
demos/_*
File renamed without changes.
355 changes: 251 additions & 104 deletions README.md

Large diffs are not rendered by default.

150 changes: 121 additions & 29 deletions README_KOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,26 @@
<a href="https://img.shields.io/pypi/v/torchattacks"><img alt="Pypi" src="https://img.shields.io/pypi/v/torchattacks.svg" /></a>
<a href="https://adversarial-attacks-pytorch.readthedocs.io/en/latest/"><img alt="Documentation Status" src="https://readthedocs.org/projects/adversarial-attacks-pytorch/badge/?version=latest" /></a>
</p>
[Torchattacks](https://arxiv.org/abs/2010.01950)은 파이토치(PyTorch) 기반의 딥러닝 모델에 대한 적대적 공격(Adversarial Attack)을 구현한 패키지입니다. 파이토치와 친숙한 코드를 제공하여, 파이토치 사용자들이 좀 더 쉽게 적대적 공격에 친숙해지는 것을 목표로 하고 있습니다.

[Torchattacks](https://arxiv.org/abs/2010.01950)은 파이토치(PyTorch) 기반의 딥러닝 모델에 대한 적대적 공격(Adversarial Attack)을 구현한 패키지입니다.


<p align="center">

| 원본 이미지 | 적대적 공격 이미지 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <img src="https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/pic/clean.png" width="300" height="300"> | <img src="https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/pic/pgd.png" width="300" height="300"> |

<p align="center">
<table width="650">
<thead>
<tr>
<th align="center">원본 이미지</th>
<th align="center">적대적 이미지</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center"><img src="https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/pic/clean.png" width="300" height="300"></td>
<td align="center"><img src="https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/pic/pgd.png" width="300" height="300"></td>
</tr>
</tbody>
</table>
</p>


Expand Down Expand Up @@ -167,8 +177,8 @@ Evasion Attack의 경우 크게 **White Box**와 **Black Box**로 나뉠 수 있

### :clipboard: 개발 환경

- torch==1.4.0
- python==3.6
- torch>=1.4.0
- python>=3.6



Expand All @@ -185,46 +195,119 @@ adversarial_images = atk(images, labels)



### :warning: 주의 사항
Torchattack은 또한 아래의 기능도 제공합니다.

* **모든 이미지는 transform[to.Tensor()]을 활용하여 [0, 1]로 입력되어야합니다!** 본래 PyTorch에서는 transform을 통해 지원되는 normalization을 활용하고는 합니다. 하지만, 적대적 공격의 특징 상 최대 섭동(Maximum Perturbtion) 범위를 주거나 이를 비용으로 활용하기 때문에, 입력 이미지가 [0, 1]일 때 정확히 적대적 예제를 생성할 수 있습니다. 따라서, normalization을 *데이터를 불러오는 과정*이 아니라 *모델의 안*에 삽입하여야합니다. 자세한 내용은 이 [데모](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20(ImageNet).ipynb)를 참고 부탁드립니다.
<details><summary>공격 라벨 정하기</summary><p>

* **모든 모델은 `(N, C)` 형태의 tensor를 출력해야합니다. 여기서 `N`은 배치(Batch)의 개수, `C`는 정답 클래스(class)의 개수입니다!** 주어지는 모델은 *torchvision.models*과의 호환을 위해서 확률 벡터로 사용될 `(N,C)` 만을 출력해야합니다. 만약 그렇지 않을 경우, 모델의 출력을 조절할 수 있는 레이어(Layer)를 이 [데모](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Model%20with%20Multiple%20Outputs.ipynb)와 같이 추가하면 됩니다.
* Random target label:
```python
# random labels as target labels.
atk.set_mode_targeted_random(n_classses)
```

* **만약 매번 똑같은 적대적 예제가 나오게 하려면, `torch.backends.cudnn.deterministic = True`를 사용합니다**. GPU에서 이루어지는 연산은 non-deterministic한 경우도 있기 때문에, 기울기를 활용하는 적대적 공격은 모든 환경이 똑같더라도 항상 똑같은 값을 출력하지 않습니다 [[discuss]](https://discuss.pytorch.org/t/inconsistent-gradient-values-for-the-same-input/26179). 따라서, 이를 방지하기 위해서는 GPU의 랜덤성을 고정하도록 다음 명령어를 실행해야 합니다. `torch.backends.cudnn.deterministic = True`[[ref]](https://stackoverflow.com/questions/56354461/reproducibility-and-performance-in-pytorch).
* Least likely label:
```python
# label with the k-th smallest probability used as target labels.
atk.set_mode_targeted_least_likely(kth_min)
```

* By custom function:
```python
# label from mapping function
atk.set_mode_targeted_by_function(target_map_function=lambda images, labels:(labels+1)%10)
```

* Return to default:
```python
atk.set_mode_default()
```

## 문서 및 데모
</p></details>

### :book: ReadTheDocs
<details><summary>반환 형식 바꾸기</summary><p>

본 패키지에 대한 코드 설명이 있는 [RTD](https://adversarial-attacks-pytorch.readthedocs.io/en/latest/index.html)입니다.
* Return adversarial images with integer value (0-255).
```python
atk.set_return_type(type='int')
```

* Return adversarial images with float value (0-1).
```python
atk.set_return_type(type='float')
```

</p></details>

### :mag_right: 업데이트 기록
<details><summary>적대적 예제 저장하기</summary><p>
```python
atk.save(data_loader, save_path=None, verbose=True)
```
</p></details>

보다 자세한 업데이트 기록을 보고 싶다면, [여기](update_records.md)를 참고해주세요.
<details><summary>Training/Eval 모드 바꾸기</summary><p>

```python
# For RNN-based models, we cannot calculate gradients with eval mode.
# Thus, it should be changed to the training mode during the attack.
atk.set_training_mode(training=False)
```

</p></details>

### :rocket: 데모

- **White Box Attack with ImageNet** ([code](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20(ImageNet).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20%28ImageNet%29.ipynb)): [Inception v3](https://arxiv.org/abs/1512.00567)[ImageNet](http://www.image-net.org/) 데이터와 *torchattacks*을 활용하여 속이는 데모입니다.
- **Black Box Attack with CIFAR10** ([code](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Black%20Box%20Attack%20(CIFAR10).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Black%20Box%20Attack%20%28CIFAR10%29.ipynb)): *torchattacks*을 활용하여 Black Box Attack을 실행하는 방법입니다.
- **Adversairal Training with MNIST** ([code](https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/demos/Adversairal%20Training%20(MNIST).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Adversairal%20Training%20%28MNIST%29.ipynb)): *torchattacks*을 활용하여 Adversarial Training을 하는 코드입니다.
- **Applications of MultiAttack with CIFAR10** ([code](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Applications%20of%20MultiAttack%20(CIFAR10).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Applications%20of%20MultiAttack%20(CIFAR10).ipynb)): *torchattacks**Multiattack*을 어떻게하면 잘 활용할 수 있을까에 대한 정리 문서입니다.
<details><summary>공격 조합하기</summary><p>

* Strong attacks
```python
atk1 = torchattacks.FGSM(model, eps=8/255)
atk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk = torchattacks.MultiAttack([atk1, atk2])
```

* Binary serach for CW
```python
atk1 = torchattacks.CW(model, c=0.1, steps=1000, lr=0.01)
atk2 = torchattacks.CW(model, c=01, steps=1000, lr=0.01)
atk = torchattacks.MultiAttack([atk1, atk2])
```

* Random restarts
```python
atk1 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk = torchattacks.MultiAttack([atk1, atk2])
```

</p></details>




더 자세한 적용 방법은 아래 데모들을 통해 익힐 수 있습니다.

- **White Box Attack with ImageNet** ([code](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20(ImageNet).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20%28ImageNet%29.ipynb)): ResNet-18을 ImageNet 데이터와 torchattacks을 활용하여 속이는 데모입니다.
- **Transfer Attack with CIFAR10** ([code](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Transfer%20Attack%20(CIFAR10).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Transfer%20Attack%20%28CIFAR10%29.ipynb)): torchattacks을 활용하여 Transfer Attack을 실행하는 방법입니다.
- **Adversairal Training with MNIST** ([code](https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/demos/Adversairal%20Training%20(MNIST).ipynb), [nbviewer](https://nbviewer.jupyter.org/github/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Adversairal%20Training%20%28MNIST%29.ipynb)): torchattacks을 활용하여 Adversarial Training을 하는 코드입니다.



### :warning: 주의 사항

* **모든 이미지는 transform[to.Tensor()]을 활용하여 [0, 1]로 입력되어야합니다!** 본래 PyTorch에서는 transform을 통해 지원되는 normalization을 활용하고는 합니다. 하지만, 적대적 공격의 특징 상 최대 섭동(Maximum Perturbtion) 범위를 주거나 이를 비용으로 활용하기 때문에, 입력 이미지가 [0, 1]일 때 정확히 적대적 예제를 생성할 수 있습니다. 따라서, normalization을 *데이터를 불러오는 과정*이 아니라 *모델의 안*에 삽입하여야합니다. 자세한 내용은 이 [데모](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/White%20Box%20Attack%20(ImageNet).ipynb)를 참고 부탁드립니다.

* **모든 모델은 `(N, C)` 형태의 tensor를 출력해야합니다. 여기서 `N`은 배치(Batch)의 개수, `C`는 정답 클래스(class)의 개수입니다!** 주어지는 모델은 *torchvision.models*과의 호환을 위해서 확률 벡터로 사용될 `(N,C)` 만을 출력해야합니다. 만약 그렇지 않을 경우, 모델의 출력을 조절할 수 있는 레이어(Layer)를 이 [데모](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/demos/Model%20with%20Multiple%20Outputs.ipynb)와 같이 추가하면 됩니다.

* **만약 매번 똑같은 적대적 예제가 나오게 하려면, `torch.backends.cudnn.deterministic = True`를 사용합니다**. GPU에서 이루어지는 연산은 non-deterministic한 경우도 있기 때문에, 기울기를 활용하는 적대적 공격은 모든 환경이 똑같더라도 항상 똑같은 값을 출력하지 않습니다 [[discuss]](https://discuss.pytorch.org/t/inconsistent-gradient-values-for-the-same-input/26179). 따라서, 이를 방지하기 위해서는 GPU의 랜덤성을 고정하도록 다음 명령어를 실행해야 합니다. `torch.backends.cudnn.deterministic = True`[[ref]](https://stackoverflow.com/questions/56354461/reproducibility-and-performance-in-pytorch).



## 인용

본 패키지를 사용한다면 아래를 인용 부탁드립니다 :)
본 패키지를 사용하신다면 아래를 인용 부탁드립니다 :)

```
@article{kim2020torchattacks,
title={Torchattacks: A Pytorch Repository for Adversarial Attacks},
title={Torchattacks: A pytorch repository for adversarial attacks},
author={Kim, Hoki},
journal={arXiv preprint arXiv:2010.01950},
year={2020}
Expand Down Expand Up @@ -321,7 +404,7 @@ atk.save(data_loader=test_loader, save_path="_temp.pt", verbose=True)

어떤 종류의 기여라도 항상 감사드리며, 오류가 있다면 망설임 없이 지적 부탁드립니다. :blush:

만약, 새로운 공격을 제안하고 싶다면 [contribution.md](https://github.com/Harry24k/adversarial-attacks-pytorch/blob/master/contributions.md)을 참고해주세요!
만약, 새로운 공격을 제안하고 싶다면 [CONTRIBUTING.md](CONTRIBUTING.md)을 참고해주세요!



Expand All @@ -339,17 +422,26 @@ atk.save(data_loader=test_loader, save_path="_temp.pt", verbose=True)


* **Adversarial Defense Leaderboard:**

* [https://github.com/MadryLab/mnist_challenge](https://github.com/MadryLab/mnist_challenge)
* [https://github.com/MadryLab/cifar10_challenge](https://github.com/MadryLab/cifar10_challenge)
* [https://www.robust-ml.org/](https://www.robust-ml.org/)
* [https://robust.vision/benchmark/leaderboard/](https://robust.vision/benchmark/leaderboard/)
* https://github.com/RobustBench/robustbench
* https://github.com/Harry24k/adversarial-defenses-pytorch





* **Adversarial Attack and Defense Papers:**

* https://nicholas.carlini.com/writing/2019/all-adversarial-example-papers.html: A Complete List of All (arXiv) Adversarial Example Papers made by Nicholas Carlini.
* https://github.com/chawins/Adversarial-Examples-Reading-List: Adversarial Examples Reading List made by Chawin Sitawarin.



* **ETC**:

* https://github.com/Harry24k/gnn-meta-attack: Adversarial Poisoning Attack on Graph Neural Network.
* https://github.com/ChandlerBang/awesome-graph-attack-papers: Graph Neural Network Attack papers.


41 changes: 40 additions & 1 deletion update_records.md → UPDATE_HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,43 @@
* `MIFGSM` is fixed.
* https://github.com/Harry24k/adversarial-attacks-pytorch/issues/33
* `CW` is fixed.
* https://github.com/Harry24k/adversarial-attacks-pytorch/issues/32
* https://github.com/Harry24k/adversarial-attacks-pytorch/issues/32





### v3.0.0

* `torch=1.9.0` supported.

* https://github.com/Harry24k/adversarial-attacks-pytorch/issues/34

* Targeted mode is officially supported.

* `Attack` & `Attacks.*`

* `set_mode_default`
* `set_mode_targeted_by_function`
* `set_mode_targeted_least_likely`
* `set_mode_targeted_random`
* `_get_target_label`
* `_get_least_likely_label`
* `_get_random_target_label`

* `self._supported_mode`
* `self._targeted`

* `UPGD` created.

* Utimate PGD that supports various options of gradient-based adversarial attacks.

* `DIFGSM` is fixed.

* https://github.com/Harry24k/adversarial-attacks-pytorch/issues/33

* Extra

* Iteration variable (e.g., `for i in range`) is replaced to `_` if it is not needed.
* `MultiAttack` now prints the attack success rate for each attack.
* Arguments for `super()` is erased.
File renamed without changes.
File renamed without changes.
77 changes: 50 additions & 27 deletions demos/Adversairal Training (MNIST).ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"import os\n",
"import sys\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"\n",
"import torch\n",
"import torch.nn as nn\n",
Expand All @@ -36,10 +38,23 @@
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"PyTorch 1.9.0\n",
"Torchvision 0.10.0\n",
"Torchattacks 3.0.0\n",
"Numpy 1.20.1\n"
]
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"%matplotlib inline"
"print(\"PyTorch\", torch.__version__)\n",
"print(\"Torchvision\", torchvision.__version__)\n",
"print(\"Torchattacks\", torchattacks.__version__)\n",
"print(\"Numpy\", np.__version__)"
]
},
{
Expand Down Expand Up @@ -138,33 +153,41 @@
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true
"scrolled": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\slcf\\anaconda3\\lib\\site-packages\\torch\\nn\\functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at ..\\c10/core/TensorImpl.h:1156.)\n",
" return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch [1/5], lter [100/468], Loss: 2.2063\n",
"Epoch [1/5], lter [200/468], Loss: 1.8595\n",
"Epoch [1/5], lter [300/468], Loss: 1.8766\n",
"Epoch [1/5], lter [400/468], Loss: 1.6352\n",
"Epoch [2/5], lter [100/468], Loss: 1.4859\n",
"Epoch [2/5], lter [200/468], Loss: 1.1941\n",
"Epoch [2/5], lter [300/468], Loss: 1.4796\n",
"Epoch [2/5], lter [400/468], Loss: 1.1723\n",
"Epoch [3/5], lter [100/468], Loss: 1.0888\n",
"Epoch [3/5], lter [200/468], Loss: 0.8527\n",
"Epoch [3/5], lter [300/468], Loss: 1.0899\n",
"Epoch [3/5], lter [400/468], Loss: 0.8288\n",
"Epoch [4/5], lter [100/468], Loss: 0.9201\n",
"Epoch [4/5], lter [200/468], Loss: 0.6490\n",
"Epoch [4/5], lter [300/468], Loss: 0.8750\n",
"Epoch [4/5], lter [400/468], Loss: 0.6238\n",
"Epoch [5/5], lter [100/468], Loss: 0.7873\n",
"Epoch [5/5], lter [200/468], Loss: 0.5471\n",
"Epoch [5/5], lter [300/468], Loss: 0.8011\n",
"Epoch [5/5], lter [400/468], Loss: 0.5021\n"
"Epoch [1/5], lter [100/468], Loss: 2.2614\n",
"Epoch [1/5], lter [200/468], Loss: 1.8953\n",
"Epoch [1/5], lter [300/468], Loss: 1.9722\n",
"Epoch [1/5], lter [400/468], Loss: 1.6388\n",
"Epoch [2/5], lter [100/468], Loss: 1.4706\n",
"Epoch [2/5], lter [200/468], Loss: 1.1385\n",
"Epoch [2/5], lter [300/468], Loss: 1.3320\n",
"Epoch [2/5], lter [400/468], Loss: 1.0488\n",
"Epoch [3/5], lter [100/468], Loss: 1.0429\n",
"Epoch [3/5], lter [200/468], Loss: 0.7567\n",
"Epoch [3/5], lter [300/468], Loss: 1.0407\n",
"Epoch [3/5], lter [400/468], Loss: 0.7480\n",
"Epoch [4/5], lter [100/468], Loss: 0.7487\n",
"Epoch [4/5], lter [200/468], Loss: 0.5967\n",
"Epoch [4/5], lter [300/468], Loss: 0.8110\n",
"Epoch [4/5], lter [400/468], Loss: 0.5409\n",
"Epoch [5/5], lter [100/468], Loss: 0.6163\n",
"Epoch [5/5], lter [200/468], Loss: 0.5100\n",
"Epoch [5/5], lter [300/468], Loss: 0.7592\n",
"Epoch [5/5], lter [400/468], Loss: 0.4903\n"
]
}
],
Expand Down Expand Up @@ -212,7 +235,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Standard accuracy: 96.14 %\n"
"Standard accuracy: 96.00 %\n"
]
}
],
Expand Down Expand Up @@ -251,7 +274,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Robust accuracy: 85.22 %\n"
"Robust accuracy: 88.81 %\n"
]
}
],
Expand Down Expand Up @@ -293,7 +316,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
"version": "3.8.8"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 9f1969a

Please sign in to comment.