ドキュメント • 機能と用途 • 使用例 • 攻撃モデル • ツールキット設計
OpenAttack は、オープンソースの Python ベースのテキスト対向攻撃ツールキットであり、テキストの前処理、被害者モデルへのアクセス、対向例の生成、評価を含むテキスト対向攻撃の全プロセスを処理します。
⭐️ すべての攻撃タイプをサポート. OpenAttack は、文/単語/文字レベルの摂動と勾配ベース/スコアベース/判断ベース/ブラインド攻撃モデルを含むすべてのタイプの攻撃をサポートします;
⭐️ 多言語対応. OpenAttack は現在英語と中国語をサポートしています。拡張可能な設計により、より多くの言語への迅速な対応が可能です;
⭐️ 並列処理. OpenAttack は攻撃モデルのマルチプロセス実行をサポートし、攻撃効率を向上させます;
⭐️ 🤗 Hugging Face との互換性. OpenAttack は 🤗 Transformers および Datasets ライブラリと完全に統合されています;
⭐️ 優れた拡張性. カスタマイズした 被害者モデル を任意のカスタマイズした データセット で容易に攻撃したり、カスタマイズした 攻撃モデル を開発および評価したりできます。
✅ 攻撃モデルのための多様で便利な ベースライン を提供;
✅ 徹底的な評価指標を用いて攻撃モデルを包括的に 評価;
✅ 共通の攻撃コンポーネントの助けを借りて、新しい攻撃モデル の迅速な開発を支援;
✅ 様々な対向攻撃に対する機械学習モデルの ロバスト性 を評価;
✅ 生成された対向例でトレーニングデータを強化することで、機械学習モデルのロバスト性を向上させる 対向訓練 を実施。
pip を使用する (推奨)```bashpip install OpenAttack
#### 2. このリポジトリのクローン```bash
git clone https://github.com/thunlp/OpenAttack.git
cd OpenAttack
python setup.py install
インストール後、demo.pyを実行してOpenAttackが正常に動作するか確認できます:```
python demo.py

## 使用例
#### 組み込み被害者モデルに対する攻撃
OpenAttackは、一般的に使用されるNLPモデル(BERT([Devlin et al. 2018](https://arxiv.org/abs/1810.04805))やRoBERTa([Liu et al. 2019](https://arxiv.org/abs/1907.11692))など)を組み込んでおり、これらは一般的なデータセット([SST-2](https://nlp.stanford.edu/sentiment/treebank.html)など)で微調整されています。これらの組み込み被害者モデルに対して、簡単に敵対的攻撃を実行できます。
以下のコードスニペットは、PWWS(貪欲アルゴリズムに基づく攻撃モデル、[Ren et al., 2019](https://www.aclweb.org/anthology/P19-1103.pdf))を使用して、SST-2データセット上のBERTを攻撃する方法を示しています(完全な実行可能コードは[こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/workflow.py))。```python
import OpenAttack as oa
import datasets # use the Hugging Face's datasets library
# change the SST dataset into 2-class
def dataset_mapping(x):
return {
"x": x["sentence"],
"y": 1 if x["label"] > 0.5 else 0,
}
# choose a trained victim classification model
victim = oa.DataManager.loadVictim("BERT.SST")
# choose 20 examples from SST-2 as the evaluation data
dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping)
# choose PWWS as the attacker and initialize it with default parameters
attacker = oa.attackers.PWWSAttacker()
# prepare for attacking
attack_eval = OpenAttack.AttackEval(attacker, victim)
# launch attacks and print attack results
attack_eval.eval(dataset, visualize=True)
以下のコードスニペットは、SST-2においてPWWSを使用してカスタマイズされた感情分析モデル(NLTKで構築された統計モデル)を攻撃する方法を示しています(完全な実行可能コードはこちら)。```python import OpenAttack as oa import numpy as np import datasets import nltk from nltk.sentiment.vader import SentimentIntensityAnalyzer
class MyClassifier(oa.Classifier): def init(self): # nltk.sentiment.vader.SentimentIntensityAnalyzer is a traditional sentiment classification model. nltk.download('vader_lexicon') self.model = SentimentIntensityAnalyzer()
def get_pred(self, input_):
return self.get_prob(input_).argmax(axis=1)
# access to the classification probability scores with respect input sentences
def get_prob(self, input_):
ret = []
for sent in input_:
# SentimentIntensityAnalyzer calculates scores of “neg” and “pos” for each instance
res = self.model.polarity_scores(sent)
# we use 𝑠𝑜𝑐𝑟𝑒_𝑝𝑜𝑠 / (𝑠𝑐𝑜𝑟𝑒_𝑛𝑒𝑔 + 𝑠𝑐𝑜𝑟𝑒_𝑝𝑜𝑠) to represent the probability of positive sentiment
# Adding 10^−6 is a trick to avoid dividing by zero.
prob = (res["pos"] + 1e-6) / (res["neg"] + res["pos"] + 2e-6)
ret.append(np.array([1 - prob, prob]))
# The get_prob method finally returns a np.ndarray of shape (len(input_), 2). See Classifier for detail.
return np.array(ret)
def dataset_mapping(x): return { "x": x["sentence"], "y": 1 if x["label"] > 0.5 else 0, }
OpenAttack は、敵対的攻撃のプロセスを高速化するために便利なマルチプロセッシングをサポートしています。以下のコードスニペットは、遺伝的アルゴリズムに基づく攻撃モデルである Genetic (Alzantot et al. 2018) を用いた敵対的攻撃におけるマルチプロセッシングの使用方法を示しています(完全な実行可能コードは こちら)。```python import OpenAttack as oa import datasets
def dataset_mapping(x): return { "x": x["sentence"], "y": 1 if x["label"] > 0.5 else 0, }
victim = oa.loadVictim("BERT.SST") dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping) attacker = oa.attackers.GeneticAttacker() attack_eval = oa.AttackEval(attacker, victim)
attack_eval.eval(dataset, visualize=True, num_workers=4)
</details>
<details>
<summary><strong>中国語攻撃</strong></summary>
OpenAttackは現在、英語と中国語の被害モデルに対する敵対的攻撃をサポートしています。 [こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/chinese.py)はPWWSを使用して中国語のレビュー分類モデルに対する敵対的攻撃を実施するサンプルコードです。
</details>
<details>
<summary><strong>カスタマイズ攻撃モデル</strong></summary>
OpenAttackは多くの便利なコンポーネントを内蔵しており、新しい攻撃モデルに簡単に組み立てることができます。 [こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_attacker.py)は、元の文のトークンをシャッフルするシンプルな攻撃モデルの設計例を示しています。
</details>
<details>
<summary><strong>敵対的訓練</strong></summary>
OpenAttackは、訓練セットのインスタンスを攻撃することで敵対的サンプルを簡単に生成でき、それを元の訓練データセットに追加してより堅牢な被害モデルを再訓練することができます(すなわち敵対的訓練)。 [こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/adversarial_training.py)はOpenAttackを用いた敵対的訓練の実施例を示しています。
</details>
<details>
<summary><strong>その他の例</strong></summary>
- 文対分類モデルへの攻撃。単文分類モデルに加えて、OpenAttackは文対分類モデルに対する攻撃もサポートしています。 [こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/nli_attack.py)はOpenAttackを用いてNLIモデルに対する敵対的攻撃を実施するサンプルコードです。
- カスタム評価指標。OpenAttackはカスタマイズされた敵対的攻撃評価指標の設計をサポートしています。 [こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_eval.py)は、カスタム評価指標を追加して敵対的攻撃の評価に使用する例を示しています。
</details>
## Attack Models
元の入力に加えられる摂動のレベルに応じて、テキスト敵対的攻撃モデルは文レベル、単語レベル、文字レベルの攻撃モデルに分類できます。
被害モデルへのアクセス可能性に応じて、テキスト敵対的攻撃モデルは`gradient`ベース、`score`ベース、`decision`ベース、`blind`攻撃モデルに分類できます。
> [TAADPapers](https://github.com/thunlp/TAADpapers)は、テキスト敵対的攻撃と防御に関するほとんどすべての論文をまとめた論文リストです。このリストを参照して、さらに多くの攻撃モデルを見つけることができます。
現在、OpenAttackには、**すべて**の攻撃タイプをカバーする、テキスト分類モデルに対する15の典型的な攻撃モデルが含まれています。
以下は、現在含まれている攻撃モデルのリストです。
- 文レベル
- (SEA) **NLPモデルをデバッグするための意味的に等価な敵対的ルール**. *Marco Tulio Ribeiro, Sameer Singh, Carlos Guestrin*. ACL 2018. `decision` [[pdf](https://aclweb.org/anthology/P18-1079)] [[code](https://github.com/marcotcr/sears)]
- (SCPN) **構文的に制御されたパラフレーズネットワークによる敵対的サンプル生成**. *Mohit Iyyer, John Wieting, Kevin Gimpel, Luke Zettlemoyer*. NAACL-HLT 2018. `blind` [[pdf](https://www.aclweb.org/anthology/N18-1170)] [[code&data](https://github.com/miyyer/scpn)]
- (GAN) **自然な敵対的サンプルの生成**. *Zhengli Zhao, Dheeru Dua, Sameer Singh*. ICLR 2018. `decision` [[pdf](https://arxiv.org/pdf/1710.11342.pdf)] [[code](https://github.com/zhengliz/natural-adversary)]
- 単語レベル
- (TextFooler) **BERTは本当に堅牢か? テキスト分類と含意関係における自然言語攻撃の強力なベースライン**. *Di Jin, Zhijing Jin, Joey Tianyi Zhou, Peter Szolovits*. AAAI-20. `score` [[pdf](https://arxiv.org/pdf/1907.11932v4)] [[code](https://github.com/wqj111186/TextFooler)]
- (PWWS) **確率重み付き単語重要度による自然言語敵対的サンプルの生成**. *Shuhuai Ren, Yihe Deng, Kun He, Wanxiang Che*. ACL 2019. `score` [[pdf](https://www.aclweb.org/anthology/P19-1103.pdf)] [[code](https://github.com/JHL-HUST/PWWS/)]
- (Genetic) **自然言語敵対的サンプルの生成**. *Moustafa Alzantot, Yash Sharma, Ahmed Elgohary, Bo-Jhang Ho, Mani Srivastava, Kai-Wei Chang*. EMNLP 2018. `score` [[pdf](https://www.aclweb.org/anthology/D18-1316)] [[code](https://github.com/nesl/nlp_adversarial_examples)]
- (SememePSO) **組合せ最適化としての単語レベルのテキスト敵対的攻撃**. *Yuan Zang, Fanchao Qi, Chenghao Yang, Zhiyuan Liu, Meng Zhang, Qun Liu and Maosong Sun*. ACL 2020. `score` [[pdf](https://www.aclweb.org/anthology/2020.acl-main.540.pdf)] [[code](https://github.com/thunlp/SememePSO-Attack)]
- (BERT-ATTACK) **BERT-ATTACK: BERTを用いたBERTに対する敵対的攻撃**. *Linyang Li, Ruotian Ma, Qipeng Guo, Xiangyang Xue, Xipeng Qiu*. EMNLP 2020. `score` [[pdf](https://www.aclweb.org/anthology/2020.emnlp-main.500.pdf)] [[code](https://github.com/LinyangLee/BERT-Attack)]
- (BAE) **BAE: テキスト分類のためのBERTベースの敵対的サンプル**. *Siddhant Garg, Goutham Ramakrishnan. EMNLP 2020*. `score` [[pdf](https://www.aclweb.org/anthology/2020.emnlp-main.498.pdf)] [[code](https://github.com/QData/TextAttack/blob/master/textattack/attack_recipes/bae_garg_2019.py)]
- (FD) **リカレントニューラルネットワークのための敵対的入力シーケンスの作成**. *Nicolas Papernot, Patrick McDaniel, Ananthram Swami, Richard Harang*. MILCOM 2016. `gradient` [[pdf](https://arxiv.org/pdf/1604.08275.pdf)]
- 単語/文字レベル
- (TextBugger) **TEXTBUGGER: 実世界アプリケーションに対する敵対的テキストの生成**. *Jinfeng Li, Shouling Ji, Tianyu Du, Bo Li, Ting Wang*. NDSS 2019. `gradient` `score` [[pdf](https://arxiv.org/pdf/1812.05271.pdf)]
- (UAT) **NLPの攻撃と解析のためのユニバーサル敵対的トリガー.** *Eric Wallace, Shi Feng, Nikhil Kandpal, Matt Gardner, Sameer Singh*. EMNLP-IJCNLP 2019. `gradient` [[pdf](https://arxiv.org/pdf/1908.07125.pdf)] [[code](https://github.com/Eric-Wallace/universal-triggers)] [[website](http://www.ericswallace.com/triggers)]
- (HotFlip) **HotFlip: テキスト分類のためのホワイトボックス敵対的サンプル**. *Javid Ebrahimi, Anyi Rao, Daniel Lowd, Dejing Dou*. ACL 2018. `gradient` [[pdf](https://www.aclweb.org/anthology/P18-2006)] [[code](https://github.com/AnyiRao/WordAdver)]
- 文字レベル
- (VIPER) **人間のようにテキストを処理する: NLPシステムへの視覚的攻撃と防御**. *Steffen Eger, Gözde Gül ¸Sahin, Andreas Rücklé, Ji-Ung Lee, Claudia Schulz, Mohsen Mesgar, Krishnkant Swarnkar, Edwin Simpson, Iryna Gurevych*. NAACL-HLT 2019. `score` [[pdf](https://www.aclweb.org/anthology/N19-1165)] [[code&data](https://github.com/UKPLab/naacl2019-like-humans-visual-attacks)]
- (DeepWordBug) **ディープラーニング分類器を回避するための敵対的テキスト系列のブラックボックス生成**. *Ji Gao, Jack Lanchantin, Mary Lou Soffa, Yanjun Qi*. IEEE SPW 2018. `score` [[pdf](https://ieeexplore.ieee.org/document/8424632)] [[code](https://github.com/QData/deepWordBug)]
次の表は、攻撃モデルの比較を示しています。
| モデル | アクセス可能性 | 摂動 | 主なアイデア |
| :---------: | :-------------: | :----------: | :-------------------------------------------------- |
| SEA | 決定 | 文 | ルールベースの言い換え |
| SCPN | ブラックボックス | 文 | 言い換え |
| GAN | 決定 | 文 | エンコーダー-デコーダーによるテキスト生成 |
| TextFooler | スコア | 単語 | 貪欲な単語置換 |
| PWWS | スコア | 単語 | 貪欲な単語置換 |
| Genetic | スコア | 単語 | 遺伝的アルゴリズムに基づく単語置換 |
| SememePSO | スコア | 単語 | 粒子群最適化に基づく単語置換 |
| BERT-ATTACK | スコア | 単語 | 貪欲な文脈化単語置換 |
| BAE | スコア | 単語 | 貪欲な文脈化単語置換と挿入 |
| FD | 勾配 | 単語 | 勾配に基づく単語置換 |
| TextBugger | 勾配, スコア | 単語+文字 | 貪欲な単語置換と文字操作 |
| UAT | 勾配 | 単語, 文字 | 勾配に基づく単語または文字操作 |
| HotFlip | 勾配 | 単語, 文字 | 勾配に基づく単語または文字置換 |
| VIPER | ブラックボックス | 文字 | 視覚的に類似した文字置換 |
| DeepWordBug | スコア | 文字 | 貪欲な文字操作 |
## Toolkit Design
異なる攻撃モデル間の顕著な違いを考慮して、攻撃モデルのスケルトン設計にはかなりの自由度を残し、敵対的攻撃の一般的な処理と攻撃モデルで使用される共通コンポーネントの合理化に重点を置いています。
OpenAttackには7つの主要モジュールがあります。
<img src="https://assets.kitploit.com/production/public/readmes/4421/3c70579cf4ea406c82bd3bf407eb9c1e1e8b8ffb3b3c4eede4fe2812ff76eebf.png" alt="toolkit_framework" style="zoom:40%;" />
* **TextProcessor**: 元のテキスト系列を処理して攻撃モデルが敵対的サンプルを生成するのを支援する;
* **Victim**: 被害モデルをラップする;
* **Attacker**: 様々な攻撃モデルを含む;
* **AttackAssist**: 単語/文字レベル攻撃モデルで使用される様々な単語/文字置換方法と、言い換えモデルのような文レベル攻撃モデルで使用されるその他のコンポーネントをパッケージ化する;
* **Metric**: 攻撃中の敵対的サンプルに対する制約または敵対的攻撃を評価するための評価指標として機能する、いくつかの敵対的サンプル品質指標を提供する;
* **AttackEval**: 攻撃効果、敵対的サンプル品質、攻撃効率の観点からテキスト敵対的攻撃を評価する;
* **DataManager**: 他のモジュールで使用されるすべてのデータと保存されたモデルを管理する.
## Citation
このツールキットを使用する場合は、私たちの[論文](https://aclanthology.org/2021.acl-demo.43.pdf)を引用してください。```
@inproceedings{zeng2020openattack,
title={{Openattack: An open-source textual adversarial attack toolkit}},
author={Zeng, Guoyang and Qi, Fanchao and Zhou, Qianrui and Zhang, Tingji and Hou, Bairu and Zang, Yuan and Liu, Zhiyuan and Sun, Maosong},
booktitle={Proceedings of the 59th Annual Meeting of the Association for Computational Linguistics and the 11th International Joint Conference on Natural Language Processing: System Demonstrations},
pages={363--371},
year={2021},
url={https://aclanthology.org/2021.acl-demo.43},
doi={10.18653/v1/2021.acl-demo.43}
}
dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping)
victim = MyClassifier()
attacker = oa.attackers.PWWSAttacker()
attack_eval = oa.AttackEval(attacker, victim)
attack_eval.eval(dataset, visualize=True)
</details>
<details>
<summary><strong>カスタマイズされたデータセット</strong></summary>
以下のコードスニペットは、既存のファインチューニングされた感情分析モデルを**カスタマイズされた**データセット上で攻撃するためにPWWSを使用する方法を示しています(完全な実行可能コードは[こちら](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_dataset.py))。```python
import OpenAttack as oa
import transformers
import datasets
# load a fine-tuned sentiment analysis model from Transformers (you can also use our fine-tuned Victim.BERT.SST)
tokenizer = transformers.AutoTokenizer.from_pretrained("echarlaix/bert-base-uncased-sst2-acc91.1-d37-hybrid")
model = transformers.AutoModelForSequenceClassification.from_pretrained("echarlaix/bert-base-uncased-sst2-acc91.1-d37-hybrid", num_labels=2, output_hidden_states=False)
victim = oa.classifiers.TransformersClassifier(model, tokenizer, model.bert.embeddings.word_embeddings)
# choose PWWS as the attacker and initialize it with default parameters
attacker = oa.attackers.PWWSAttacker()
# create your customized dataset
dataset = datasets.Dataset.from_dict({
"x": [
"I hate this movie.",
"I like this apple."
],
"y": [
0, # 0 for negative
1, # 1 for positive
]
})
# prepare for attacking
attack_eval = oa.AttackEval(attacker, victim, metrics = [oa.metric.EditDistance(), oa.metric.ModificationRate()])
# launch attacks and print attack results
attack_eval.eval(dataset, visualize=True)
このプロジェクトのすべての貢献者に感謝します。さらに多くの貢献を歓迎します。