本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
機械学習で画像分類と言えばConvolutional Neural Network(以下、CNN)と言われるくらいCNNは物体認識に広く使われており、Googleの画像検索やFacebookの顔認識、また、自動運転自動車などで実用されています。
本記事では、このCNNへの入力画像を人間の目には分からないくらいに微妙に細工することで、CNNの画像分類を誤らせる攻撃手法を紹介します。
なお、本記事の元ネタは、Samsung Research AmericaのNina Narodytska氏とShiva Prasad Kasiviswanathan氏がarXivにポストした論文「Simple Black-Box Adversarial Perturbations for Deep Networks」です。興味のある方は一読することをおススメします。
Figure 1 オリジナル画像と細工画像の分類結果
※出典:Simple Black-Box Adversarial Perturbations for Deep Networks
Figure 1は、論文から抜粋したCNNによる画像分類の結果を示しています。
上段はオリジナル画像を分類した結果であり、それぞれ画像内の生物を正しく分類しています。一方、下段は微妙に細工した画像を分類した結果であり、左から「stingray(エイ)をsea lion(アシカ)」、「ostrich(ダチョウ)をgoose(ガチョウ)」、「jay(カケス)をjunco(ユキヒメドリ)」、「water ouzel(カワガラス)をredshank(アカアシシギ)」というように、誤分類が誘発されていることが分かります。
本記事では以下、上記手法の検証方法及び検証結果と、誤分類を防ぐ対策案を述べていきます。なお、検証で使用したソースコードは「検証用コード」に載せていますので、自身の管理下にあるシステムに対して検証目的でご自由にお使いください。
検証したモデルとデータセット
先ずは検証対象のCNNモデルとデータセットを用意します。
CNNには様々なモデルが存在しますが、今回はImageNetで学習したVGG16に対し、検証で使用するデータセット(CIFAR10)でFine-tuningしたモデルを使用します。なお、モデルの構築には深層学習フレームワーク「Keras」を使用しています。
Layer (type) Output Shape ======================================================= input_1 (Input Layer) (None, 32, 32, 3) _______________________________________________________ block1_conv1 (Convolution2D) (None, 32, 32, 64) _______________________________________________________ block1_conv2 (Convolution2D) (None, 32, 32, 64) _______________________________________________________ block1_pool (MaxPooling2D) (None, 16, 16, 64) _______________________________________________________ block2_conv1 (Convolution2D) (None, 16, 16, 128) _______________________________________________________ block2_conv2 (Convolution2D) (None, 16, 16, 128) _______________________________________________________ block2_pool (MaxPooling2D) (None, 8, 8, 128) _______________________________________________________ block3_conv1 (Convolution2D) (None, 8, 8, 256) _______________________________________________________ block3_conv2 (Convolution2D) (None, 8, 8, 256) _______________________________________________________ block3_conv3 (Convolution2D) (None, 8, 8, 256) _______________________________________________________ block3_pool (MaxPooling2D) (None, 4, 4, 256) _______________________________________________________ block4_conv1 (Convolution2D) (None, 4, 4, 512) _______________________________________________________ block4_conv2 (Convolution2D) (None, 4, 4, 512) _______________________________________________________ block4_conv3 (Convolution2D) (None, 4, 4, 512) _______________________________________________________ block4_pool (MaxPooling2D) (None, 2, 2, 512) _______________________________________________________ block5_conv1 (Convolution2D) (None, 2, 2, 512) _______________________________________________________ block5_conv2 (Convolution2D) (None, 2, 2, 512) _______________________________________________________ block5_conv3 (Convolution2D) (None, 2, 2, 512) _______________________________________________________ block5_pool (MaxPooling2D) (None, 1, 1, 512) _______________________________________________________ sequential_1 (Sequential) (None, 10)
次に、検証で使用するデータセットとしてCIFAR10を採用しました。CIFAR10には10クラスの画像が収録されており、各クラス5,000枚の訓練用画像と1,000枚のテスト用画像が収録されています。なお、画像のサイズは32 x 32pixel,RGBと小さく扱い易いため、画像認識系のモデルを手軽に検証するのに適しています。
Figure 3 検証用データセット:CIFAR10
それでは、構築したモデルを使用した画像分類の例を幾つか見ていきましょう。
先ず初めに、CIFAR10に収録されている猫「cat」のテスト用画像(32 x 32pixel)をモデルに入力してみます。すると、モデルは約76%の確率で「猫(cat)」と正しく分類します。
次に、ネットから拾ってきた猫の画像(フリー素材)を入力してみます。この画像はサイズが「6720 x 4480pixel」と大きく、また、猫の体の大部分がベッドに隠れています。このような特殊な画像であっても、約76%の確率で「猫(cat)」と正しく分類します。
このように今回検証に使用するモデルは、画像サイズの大小や分類対象物体の大部分が隠された画像であっても正しく分類することができる、優れた物体認識性能を持っていることが分かっていただけたかと思います。
検証手順
それでは、上記のモデルに誤分類を誘発させてみましょう。
入力画像の大部分を細工すれば(当然ながら)誤分類を簡単に誘発させることはできますが、それでは当たり前すぎて面白くありません。また、人間の目にも簡単に細工が分かるため、現実のシステムにおいては、細工画像はCNNの前処理で拒否されてしまうことでしょう。
そこで今回は、画像内の1pixelのみ細工することで、誤分類が誘発されるのか検証します。検証手順は以下のとおりです。
- CIFAR10のテスト用画像(クラスは「cat」)から画像を1枚読み込む。
- 画像内からランダムに選択した1pixelを細工する。
※細工方法
pixel value > 128 : RGB(0,0,0) ⇒ 「黒く」塗り潰す
pixel value =< 128 : RGB(255,255,255) ⇒ 「白く」塗り潰す - 細工画像をCNNに入力。
- CNNの分類結果を観察。
- 誤分類が誘発された場合、次の画像を検証(手順1に戻る)。
誤分類が誘発されない場合、手順2~4を最大100回繰り返す。
上記ループを1,000枚のテスト用画像全てに対して行います。
なお、手順5の最大試行回数は100回としていますが、これは検証時間の短縮のために設定しているものであり、深い意味はありません(32*32=1,024回試行してもOK)。
要するに、ランダムに選択した1pixelが明るい場合は黒く、暗い場合は白く塗り潰す、というシンプルな細工を行いながら、誤分類が誘発されるのか観察します。
検証結果
検証結果のサマリを以下に示します。
誤分類したクラス | 枚数 |
---|---|
airplane | 1 |
automobile | 1 |
bird | 8 |
deer | 4 |
dog | 36 |
frog | 19 |
horse | 4 |
ship | 3 |
truck | 2 |
Table 1 検証結果サマリ
猫「cat」のテスト用画像1,000枚の内、78枚を別のクラスに誤分類していることが分かります。特に犬「dog」と蛙「frog」に多く誤分類されていますが(画像的に似ているから?)、他クラスにも万遍なく誤分類しています。よって、今回の手法では意図したクラスに誤分類させることは難しいと言えます。また、誤分類に成功するpixel位置にも規則性はありませんでした(猫本体や背景の細工でも誤分類される)。
では、実際に誤分類した画像を幾つか見ていきましょう。
Figure 4:モデルは細工なしのオリジナル画像(左)を約68%の確率で猫「cat」と正しく分類しています。一方、顎下の1pixelを黒くした細工画像(右)は、約51%の確率で犬「dog」と誤分類しています。
Figure 4 誤分類例 其の一
Figure 5:モデルはオリジナル画像を約57%の確率で猫「cat」と正しく分類しています。一方、髭付近の1pixelを黒くした細工画像は、約55%の確率で蛙「frog」と誤分類しています。
Figure 5 誤分類例 其の弐
Figure 6:モデルはオリジナル画像を約48%の確率で猫「cat」と正しく分類しています。一方、背景の1pixelを白くした細工画像は、約48%の確率で鳥「bird」と誤分類しています。
Figure 6 誤分類例 其の参
このように、細工の箇所に関わらず、たった1pixelを細工するだけで、誤分類が誘発されることが分かりました。しかも、細工の有無は人間の目には非常に分かり難く、細工画像のみ見せられた場合、細工に気づくことは困難だと思われます。すなわち、細工画像を(CNNに入力する)前処理で拒否することは困難であると言えます。
対策
では、どのように対策すれば良いでしょうか?
元ネタの論文では具体的な対策に言及していませんが、今回は訓練用画像にSalt & Pepperノイズを加えて再度CNNを学習させる方法を試みました。以下はノイズを加えた訓練用画像の一例です。何となく細工画像に似ているため、効果が期待できそうです。
Figure 7 Salt & Pepperノイズを加えた訓練用画像
次に、対策済みCNNを使用して検証した結果サマリを示します。
分類されたクラス | 枚数 |
---|---|
cat | 44 |
automobile | 2 |
bird | 4 |
deer | 1 |
dog | 14 |
frog | 5 |
horse | 4 |
ship | 3 |
truck | 1 |
Table 2 対策後の検証結果サマリ
上表のとおり、対策前に誤分類していた78枚の画像の内、44枚を猫「cat」として正しく分類していることが分かります。それでは、正しく分類できた画像を幾つか見てみましょう。
Figure 8:対策前は約51%の確率で犬「dog」と誤分類していましたが、対策後は約53%の確率で猫「cat」と正しく分類しています。
Figure 8 正しく分類した例 其の一
Figure 9:対策前は約55%の確率で蛙「frog」と誤分類していましたが、対策後は約71%の確率で猫「cat」と正しく分類しています。
Figure 9 正しく分類した例 其の弐
Figure 10:対策前は約48%の確率で鳥「bird」と誤分類していましたが、対策後は約88%の確率で猫「cat」と正しく分類しています。
Figure 10 正しく分類した例 其の参
このように、訓練用画像にノイズを加えることで、誤分類への耐性が増すことが分かりました。今回はSalt & Pepperノイズのみ加えていますが、他にもコントラスト調整や”ぼかし”、他ノイズを加えて訓練用画像を増強(Data Augmentation)することで、更に耐性が高まることが期待されます。
まとめ
今回の検証を纏めます。
- 微小な細工で簡単に誤分類が誘発される
- 細工の有無は人間の目には分かり難い
- (今回検証した手法では)意図したクラスに誤分類させることは困難
- 誤分類に成功する細工箇所に規則性はない
- 訓練用画像を増強することで誤分類への耐性が増す
特に上記2と4の結果から、(CNNに入力する)前処理で細工画像を拒否することは困難であるため、CNNにとっては非常に厄介な攻撃であると言えます。また、今回の検証ではほぼランダムなクラスに誤分類されましたが、仮に意図したクラスに誤分類させる手法が確立された場合、物体認識系のシステムにとって大きな脅威になります。
今回の検証を通して、CNNは優れた物体認識性能を持っているものの、細工画像に対して意外にも脆弱であることが分かりました。CNNを利用してサービスや製品を開発されている方がいましたら、お手元のモデルが本攻撃に対して脆弱か否か、直ぐに確認されることを強く推奨します。
検証用コード
[リポジトリ]
https://github.com/13o-bbr-bbq/machine_learning_security/tree/master/CNN_test
- finetuning.py
検証用モデルの構築に使用。
KerasのVGG16をCIFAR10でFine-tuning。 - search_adv.py
誤分類の観測に使用。
細工画像を生成してCNNに入力し、誤分類の有無を観察。 - predict.py
分類結果の確認用。
入力画像の分類結果TOP3を表示。
関連ブログ記事
おすすめ記事