自然言語処理における敵対的攻撃（Adversarial Attack）の手法を簡単にまとめてみた

# はじめに

自然言語処理における敵対的攻撃（Adversarial Attack）の手法とか全然知らなかったので、ちょこっと勉強してみました。なんとなく雰囲気はつかめたので、自分が勉強した内容をすごいざっくりとした形で紹介します。各手法の紹介において、概要レベルの説明しかできてないので、詳しく知りたい方は各原論文をご参照ください。


## 参考文献

まとめるといっても以下の記事の写経的なことをしてるだけです。とてもわかりやすくまとめていただいており、大変勉強になりました。

1. [言語処理分野におけるAdversarial Example](https://www.ai-gakkai.or.jp/resource/my-bookmark/my-bookmark_vol34-no5/)
1. [Adversarial Attacks and Defense on Texts: A Survey character-level編](https://jpsec.ai/adversarial-attacks-and-defense-on-texts-a-survey01/)
1. [Adversarial Attacks and Defense on Texts: A Survey word-level編](https://jpsec.ai/adversarial-attacks-and-defense-on-texts-a-survey02/)
1. [Adversarial Attacks and Defense on Texts: A Survey sentence-level編](https://jpsec.ai/adversarial-attacks-and-defense-on-texts-a-survey03/)

参考文献1.や2.~4.が参考にしているNLPのAdversarial Attackに関するサーベイ論文はこちら

- [Adversarial Attacks on Deep Learning Models in Natural Language Processing: A Survey](https://arxiv.org/abs/1901.06796)
- [Adversarial Attacks and Defense on Texts: A Survey](https://arxiv.org/abs/2005.14108)


# Adversarial Attackとは？

NLPに関わらず、まずはAdversarial Attackって何？ってところから簡単に触れておきます。

![スクリーンショット 2022-02-10 23.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/d07b98d4-553f-a588-d86c-740fc9109ef6.png)
> [Protecting Voice Controlled Systems Using Sound Source Identification Based on Acoustic Cues](https://arxiv.org/abs/1811.07018)の図3から引用

Adversarial Attackとは、AIなどのモデルに対して入力データに細工をすることでモデルを誤判定させてしまうような方法を指します。例えば上の図で言えば、アヒルの画像に微小なノイズ画像を足し合わせた右側の画像もまたヒトが見れば明らかにアヒルなわけですが、モデルは"馬"と予測してしまった例です。下の波形データについても、左側の波形を"How are you?"と音声認識できていたのに微小なノイズを加えることで、"Open the door"と全く別の文章として認識されてしまっています。このようなノイズを敵対的摂動とか言うようですが、ポイントはこの摂動を加えてもヒトには見分けがつかない点かと思います。入力データに敵対的摂動が加えられていてもヒトは気づくことができず、そのデータをモデルに入力してしまい、想定しないアウトプットが出力されて問題が起こってしまいます。

とはいえAdversarsial Attackただひたすらに脅威、というだけではなく、見方を変えるとモデルの弱点を教えてくれるデバッグの手法とも解釈ができると思います。Adversarial Attackによって作られたデータ（Adversarial Examples）をモデルの学習データに含めることでモデルの頑健性を高めることもできるようです。

Adversarisal Attackには大きく２種類のアプローチがあります。

## White-box approach
モデルの知識（モデルのネットワーク構造やパラメータ、損失関数や学習データなど）が事前にわかっていることを前提とした攻撃方法です。代表例としてGoodfellow氏らの[Explaining and Harnessing Adversarial Examples](https://arxiv.org/abs/1412.6572)
という論文で紹介されているFGSM（Fast Gradient Sign Method）が有名かと思います。
以下の式はFGSMによる敵対的摂動を表します。
![スクリーンショット 2022-02-10 23.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/fa1cc2e4-09e4-3cb4-ca6e-8e457fab8af8.png)
> Explaining and Harnessing Adversarial Examplesから引用

FGSMに関しては、自分も過去記事で実装方法も含めて紹介したことがありますので興味ある方はご参照ください。

- [Adversarial Attackされた画像にGrad-CAMで異変に気付けるか実装しながら試してみる](https://qiita.com/m__k/items/f733ccb285a696ed22c8)

## Black-box approach
モデルの内部にアクセスができず、モデルのインプットとアウトプットのみアクセスできること前提とした攻撃方法です。実際に現実世界において、悪意を持ってモデルに攻撃したい場合はBack-box approachが現実的です。なぜなら、世の中のAIモデルは例えばWeb APIのような形で提供されており、入力データとモデルの出力しかアクセスできないケースがほとんどだからです。

ここでちょっと驚きな研究結果をご紹介します。[Practical Black-Box Attacks against Machine Learning](https://arxiv.org/abs/1602.02697)という論文で紹介されているBack-boxを想定した攻撃方法なのですが、Adversarial ExamplesにはTransferability(転移性)があることを示唆している内容です。
ざっくりとした攻撃方法の概要は
1. 攻撃対象モデルに何件かデータを推論させ、データと推論結果を得る。
2. データと推論結果を用いて、手元でモデル$F$を作成し、$F$に対するAdversarial Examplesを作成。このAdversarial Examplesが元のモデルを誤判定させる

という感じです。モデル$F$はSubstitute DNN Trainingという方法で作成します。

### Substitute DNN Trainingの概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/860ff161-2d2c-8408-9a86-c8d2dda1a99c.png)
> Practical Black-Box Attacks against Machine Learningから引用

Substitute DNN Trainingは大きく以下の5Stepに分けられます。

1. **Initial Collection**  
very smallなデータセット$S_0$を用意。（実際に学習に使用されたデータでなくてOK）。例えばMNISTであれば、0〜9の画像をそれぞれ10枚程度用意する。

1. **Architecture Selection**  
手元で作成するモデル$F$のアーキテクチャーを検討する。画像であればCNNなど、そのデータでよく使われるモデルを選定する。

1. **Substitute Training**  
    1. **Labeling** 
    $S_0$のデータを対象モデルに入力し推論させ、予測結果を$S_0$の正解ラベルとする
    1. **Training**  
    モデル$F$を学習させる
    1. **Augmentation**  
    Jacobian-based dataset augmentationという手法でデータを水増し、LabelingとTrainingを繰り返す。

手元のモデル$F$ができあがれば、$F$自体はモデルの構造を知っているのでFGSMのようなWhite-boxな手法でAdversarial Examplesを作成すればOK、という流れです。


# 自然言語処理におけるAdversarial Attack

## 自然言語処理ならではの難しいところ

[Adversarial Attacks on Deep Learning Models in Natural Language Processing: A Survey](https://arxiv.org/abs/1901.06796)では、自然言語処理におけるAdversarial Attackの難しい点を以下の３つの観点でまとめています。

**離散的**
画像の入力は連続的（画素の値が連続的）だが、テキストは離散的（単語や文字）なため、小さな摂動を加えることが難しい。

**知覚可能性**
画像の画素の微小な変化は人間には検知が難しいが、テキストの微小な変化（文字や単語の変化）はすぐ検知できる。

**意味性**
画像がちょっと変わったところでその画像の意味の変化は些細なものだが、テキストの場合、文字や単語を置き換えたりすると、そもそも元の意味から変わってしまう。（例えば否定的な単語を削除するなど）


## 攻撃の種類

自然言語処理におけるAdversarial Attackの方法は大きく以下の４つに分類することができるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/c2534360-6cd9-c1b0-2337-bad751a869fe.png)
> [Adversarial Attacks and Defense on Texts: A Survey](https://arxiv.org/abs/2005.14108)から引用


**Character-level**
文字単位の置き換え、追加、削除、入れ替えといった操作を加える。

**Word-level**
単語をシノニム辞書などを用いて、同義語や対義語などに変更する。タイプミスに見せかけるパターンもある

**Sentence-level**
新しい文章を挿入する。サーベイ論文当時まででは、これ以外の方法はまだ検討されていないらしい。

**Multi-level**
上の3つの組み合わせ


以降では上記のCharacter-level、Word-level、Sentence-levelからそれぞれ１つずつ先行研究をご紹介します。

## [HotFlip: White-Box Adversarial Examples for Text Classification](https://arxiv.org/abs/1712.06751) (2017/12)

- Character-level
- White-box approach
- 文章中の単語の文字を置き換える操作などを行い、文章分類タスクを誤判定させることに成功した。

White-boxの方法なので、モデルの構造を知っていることを想定としています。この論文では[Character-Aware Neural Language Models](https://arxiv.org/abs/1508.06615)という論文で紹介されているCharCNN-LSTMモデルを攻撃対象モデルとしています。

![スクリーンショット 2022-02-11 0.29.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/666207eb-962f-04be-2de1-13c244288dfa.png)
> [Character-Aware Neural Language Models](https://arxiv.org/abs/1508.06615)から引用


### 攻撃手法の概要
まず文章を以下のようにone-hotベクトルで表現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/61879868-7b9d-e5de-606d-0f51ef758490.png)
セミコロンが単語の区切りを表しており、$m$がその文章の単語数、$n$は単語の最大文字数です。


次に文字の置き換え（flip）を入力空間のベクトルで表現します。例えば文章中の$i$番目の単語の$j$番目の文字をとある文字$a$から$b$に変換する操作は以下のようなベクトルで表現できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/017315ef-a8eb-af33-c3ca-2073782ae1a6.png)

1つのflipに対する方向性微分により,flipの損失の変化を以下の式で計算します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/e6a567b1-c3b5-81f9-0fe5-83815fa40979.png)

すべてのflipで損失が最大となるflipを見つけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/9f474eb1-c5ba-a9dc-f46a-8f7b3067e8c9.png)

### 攻撃成功例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/d2b401e6-0baa-22b3-02eb-7f22b05d557d.png)
> [HotFlip: White-Box Adversarial Examples for Text Classification](https://arxiv.org/abs/1712.06751)から引用

文章の分類タスクにおいて、攻撃が成功した例が上図になります。"mood"→"moo**P**"や"opposition"→"o**B**position"のような文字の変更により、誤判定させることができたようです。
ただこれだと、明らかにこの文章なんか変だな？タイプミスにしてもなにかおかしいぞ、とヒトには気づかれてしまいそうですね。NLPにおけるAdversarial Attackの難しい点である知覚可能性がまだ不十分であることも見て取れるかと思います。

## [Towards Crafting Text Adversarial Samples](https://arxiv.org/abs/1707.02812) (2017/7)

- Word-level
- White-box & Black-box approach
- 文章中の単語を置き換え、削除、追加等の操作を行い、文章分類モデルの誤判定に成功した。

こちらもWhite-boxを想定していますが、以下で示すようにBlack-boxの方法も紹介されています。TwitterやIMDBの感情分類用のデータセットを用いたようで、それぞれのデータにおいて、以下のようなアーキテクチャーでモデルを構築しているようです。

- Twitterのデータにおけるモデルのアーキテクチャー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/b05daae9-e5e1-84d2-0e7a-8bbfb365a759.png)
> [Towards Crafting Text Adversarial Samples](https://arxiv.org/abs/1707.02812)から引用

- IMDBのデータにおけるモデルのアーキテクチャー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/0a73a5ff-ee13-ed8f-e13a-4b7504a4891d.png)
> [Towards Crafting Text Adversarial Samples](https://arxiv.org/abs/1707.02812)から引用


### 攻撃方法の概要
基本的に文章中の各単語を置き換え→予測を繰り返し、攻撃が成功するAdversarial Examplesの作成を目指します。
置き換え対象の単語と置き換え候補の単語のペアを探索し、できるだけ少ない試行回数で良いペア（i.e. 攻撃が成功し、かつ知覚可能性や意味性が損なわれないようなもの）を探す工夫が以下のようなアルゴリズム、ということになるかと思います。

![スクリーンショット 2022-02-11 1.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/eab00921-fc41-bde3-3c08-46128d601b50.png)
> [Towards Crafting Text Adversarial Samples](https://arxiv.org/abs/1707.02812)から引用

まず、文章中の各単語に対して、その単語に対する置き換え候補の単語集合$\cal P$を用意します。これは例えばWordNetのような類義語辞書であったり、起こり得るタイプミスを考慮したものであったり、TF(Term-Frequency)などの値を参考に特定のジャンルによく現れる単語などを候補として見繕います。例えば"The movie was good"におけるgoodの場合、候補単語集合はnice, decent, god, goods...といった感じになります。

次に、文章の各単語において、予測に対する寄与度（重要度）を算出し、寄与度の大きい順番に単語を並べます。寄与度の算出の仕方は以下の式のように、文章からその単語を削除してモデルに予測させたとき、予測確率が大きく変動する単語ほど寄与度が大きい、と判断するようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/25650b64-5932-d520-e75f-d8f6c74806a9.png)

この寄与度の計算方法はBlack-boxを想定しても計算することができますが、この寄与度の計算方法だとサンプルの文章が長すぎると時間がかかってしまうということで、計算時間を短縮するためにWhite-boxを想定してFGSMの要領で寄与度を算出することも考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/1e04918e-d69f-cde7-fab3-fc5c8eaf38e4.png)

そして、寄与度の大きかった単語から順番に以下の方法で修正を加え、文章を変更した上でモデルに入力し、攻撃が成功するまで繰り返します。

1. 対象単語が副詞で寄与度が大きい場合は削除
1. 対象単語が形容詞だった場合
    1. 置き換える候補となる単語が副詞ならその単語を対象単語の前に挿入
    1. 副詞でないなら、置き換え候補の単語で対象単語を置き換える


寄与度の大きい順に試行するのは、寄与度が大きい単語に手を加えれば予測結果が変化しやすいはずで、そうすれば少ない試行回数でAdversarial Examplesを生成できる、というモチベーションかと思います。また、品詞を見てるのは生成される文章の構文が崩れないようにする工夫でしょう。


### 攻撃成功例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/f7be96b2-ca47-02e4-6b60-2e77a7a2ad6a.png)
> [Towards Crafting Text Adversarial Samples](https://arxiv.org/abs/1707.02812)から引用

Originalが元の入力文章で、TextFoolは当時の対抗馬となる手法です（詳細は割愛します）。Proposedがこの論文の主要によって生成されたAdversarial Examplesです。真ん中のIMDBのデータにおいては、TextFoolは４箇所の単語を変更しているのに対し、提案手法では1単語の変更だけで済んでいます。


## [Adversarial Examples for Evaluating Reading Comprehension Systems](https://arxiv.org/abs/1707.07328) (2017/7)

- Sentence-level
- White-box & Back-box approach
- SQuADの質問応答タスクにおいて、文末に文章を挿入して予測を誤らせることに成功


### 攻撃方法の概要と攻撃成功例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240999/acc5401c-867d-dfe4-60c3-f97f9816584d.png)
> [Adversarial Examples for Evaluating Reading Comprehension Systems](https://arxiv.org/abs/1707.07328)から引用

上図の左上が入力データです。ParagraphとQuestionをモデルに入力し、Answerを予測します。この例文では1880年にニコラ・テスラがどの都市に引っ越したかを問うています。

この論文ではAddSent(Black-box approach)とAddAny(White-box approach)の２つが紹介されていますが、AddAnyのほうは文末に単語の羅列を挿入する、しかもWhite-boxを想定と、攻撃方法にあまり旨味を感じなかったので、紹介は割愛してAddSentをご紹介します。

AddSentは大きく3ステップで構成されます。

1. Step1  
質問文の名詞、形容詞をWordNetを活用して反意語に変換し、固有名詞や数値をGloVeの類似度の近いものに置き換え、偽の質問文を作成する。
1. Step2  
答えとなる単語に対して、固有表現エンティティや品詞情報を元に同じカテゴリーのものに置き換え（手動）、偽の回答を作成する
1. Step3  
偽の質問文に対して偽の回答が答えになる根拠となる文章をルールベースで作成する。例えば、質問文の形式が"what/which NP1 VP1 ?" であれば、 "The NP1 of [Answer] VP1" に変換するようなルール。このようなルールを約50個ほど用意している様子。
1. Step4  
Step3で作成された文章の構文の誤りなどを人手で修正する

こうして出来上がった文章が"Tadakatsu moved to the city of Chicago in 1881."であり、この文章をParagraphの文末に挿入することで"What city did Tesla move to in 1880?"と質問してもモデルとしては"Chicago"と回答してしまったようです。

攻撃対象として想定しているモデルはBiDAF（[Bidirectional Attention Flow for Machine Comprehension](https://arxiv.org/abs/1611.01603)）とMatch-LSTM（[Machine Comprehension Using Match-LSTM and Answer Pointer](https://arxiv.org/abs/1608.07905)）というどちらも質問応答系のタスクに特化したモデルのようです。

唐突に文脈に何も関係ない文章が差し込まれるだけで予測がおかしくなるなって正直驚きです。当時はまだBERTもない時代なので、さすがに現在のTransformer系のアーキテクチャーには通用しないでほしいですね。。。


# おわりに

自然言語処理におけるAdversarial Attackの手法として、Character-level, Word-level, Sentence-levelにおいてそれぞれ１事例ずつ紹介してみました。NLPに対する攻撃は基本的に単語の置き換え、追加や削除を候補集合からいかに効率的に素早く探索するか、が論点になってるように感じました。NLPに対する攻撃の仕方の雰囲気は掴むことができたかなと思います。画像系と違って手法も考え方も結構違うものなんですね。

上で紹介した事例は攻撃は成功しているものの、やはり知覚可能性や意味性については課題が残るような形かなーと思いますが、最近（2022/1）、そのへんの攻撃の秘匿性に関してもしっかり考慮したようなNLPに関するAdversarial Attackのの論文がでてました。
[HydraText: Multi-objective Optimization for Adversarial Textual Attack](https://arxiv.org/abs/2111.01528)
こちらの論文の紹介はまたどこかでしたいなぁと思っているのですが、このHydraTextという手法をざっくり紹介すると

- 攻撃を成功させることと、気付かれないようにすることを同時に考慮
- Adversarial Examplesを作成する問題を多目的集合最適化問題として定式化
- Adversarial Examplesがただ1つだけ生成される仕組みなので、従来の手法のように手動で選択するような操作は不要
- 攻撃成功率と攻撃秘匿性を同時に考慮しながら、Score-based(クラス確率を出力するケース)、decision-based(トップクラスのラベルのみ出力するケース)両方に同時にアプローチできる現状唯一の手法

なんか凄そうですが、基本的には良いAdversarial Examplesを効率的に探索する手法であることには変わりないかなと思います。ご興味ある方は原論文を一度読んでみてはいかがでしょうか。

おわり