Adversarial Robustness Toolbox(ART)は、AI*1セキュリティのためのPythonライブラリです。
ARTを使用することで、AIに対する攻撃手法(敵対的サンプル攻撃、データ汚染攻撃、モデル抽出、メンバーシップ推論など)とそれらに対する防御手法を検証することができます。攻撃からAIを守るためには、攻撃のメカニズムと適切な防御手法の理解が必要です。そこで本コラムでは、ARTを通してAIの安全を確保する技術を学んでいきます。
第6回は、AIの学習データを推論するメンバーシップ推論攻撃(Membership Inference Attack)を実践します。
メンバーシップ推論とは、攻撃対象の分類器(以下、標的分類器)に正常な入力データを与え、標的分類器から応答された分類結果を観察することで、入力したデータが分類器の学習データに含まれているか否か(=メンバーシップか否か)を特定する攻撃手法です。仮に、顔情報やライフスタイルに関する情報といった高度なプライバシー情報を学習した分類器に対してメンバーシップ推論攻撃が行われた場合、重大なプライバシー侵害が発生することになります。なお、本手法は、攻撃者が標的分類器の内部構造を知らない状態(ブラックボックス)でも攻撃を行うことができるため実用性が高く、現実的な脅威になる可能性があります。
下図は、標的分類器(Target Network)に任意の入力データ(Sample data)を与え、その応答(Classification)を基に入力データが標的分類器のメンバーシップか否かを判定している様子を表しています。
- メンバーシップ推論攻撃の概念図
このように、標的分類器の入出力データを観察するのみで、メンバーシップを推論することができます。
今回は、ARTに実装されているMembership Inference Attackを用いて、メンバーシップ推論攻撃を実践します。
*1..本コラムにおけるAIの定義 |
---|
本コラムでは、画像分類や音声認識など、通常は人間の知能を必要とする作業を行うことができるコンピュータシステム、とりわけ機械学習を使用して作成されるシステム全般を「AI」と呼称することにします。 |
注意 |
---|
本コラムは、AIの安全を確保する技術を理解していただくために書かれています。本コラムの内容を検証する場合は、必ずご自身の管理下にあるシステムにて、ご自身の責任の下で実行してください。許可を得ずに第三者のシステムで実行した場合、法律により罰せられる可能性があります。 |
本コラムの内容を深く理解するには、メンバーシップ推論の基本知識を有していることが好ましいです。
メンバーシップ推論をご存じでない方は、事前にAIセキュリティ超入門:第4回 AIのプライバシー侵害 – メンバーシップ推論 –をご覧ください。
ハンズオン
本コラムは、実践を通じてARTを習得することを重視するため、ハンズオン形式で進めていきます。
ハンズオンは、皆様のお手元の環境、または、筆者らが用意したGoogle Colaboratory*2にて実行いただけます。
Google Colaboratoryを利用してハンズオンを行いたい方は、以下のURLにアクセスしましょう。
Google Colaboratory:ART超入門 – 第6回:メンバーシップ推論攻撃 –
*2:Colaboratoryを使用するために |
---|
Google Colaboratoryを利用するためにはGoogleアカウントが必要です。 お持ちでない方は、お手数ですが、先にGoogleアカウントの作成をお願いします。 |
お手元の環境でハンズオンを行いたい方は、以下の解説に沿ってコードを実行してください。
事前準備
ARTのインストール
ARTはPythonの組み込みライブラリではないため、インストールします。
# [1-1]
# ARTのインストール。
pip3 install adversarial-robustness-toolbox
ライブラリのインポート
ARTや分類器の構築に必要なライブラリをインポートします。
本ハンズオンでは、TensorFlowに組み込まれているKerasを使用して画像分類器を構築するため、Kerasのクラスをインポートします。
また、ARTでメンバーシップ推論攻撃を実行するクラスMembershipInferenceBlackBox
などもインポートします。
# [1-2]
# 必要なライブラリのインポート
import random
import numpy as np
import matplotlib.pyplot as plt
# TensorFlow with Keras.
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Conv2D
from tensorflow.keras.layers import MaxPooling2D, GlobalAveragePooling2D, Dropout
tf.compat.v1.disable_eager_execution()
# ART
from art.attacks.inference.membership_inference import MembershipInferenceBlackBox
from art.estimators.classification import KerasClassifier
データセットのロード
標的とする画像分類器の学習データとして、CIFAR10を使用します。
# [1-3]
# CIFAR10のロード。
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()
# CIFAR10のラベル。
classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)
CIFAR10の収録画像を確認します。
ロードしたデータセットから25枚の画像をランダム抽出し、画面上に表示します。
# [1-4]
# データセットの可視化。
show_images = []
for _ in range(5 * 5):
show_images.append(X_train[random.randint(0, len(X_train))])
for idx, image in enumerate(show_images):
plt.subplot(5, 5, idx + 1)
plt.imshow(image)
# 学習データ数、テストデータ数を表示。
print(X_train.shape, y_train.shape)
CIFAR10には'airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'
の10クラスの画像が60,000枚収録されています。
内訳は学習データ:50,000枚、テストデータ:10,000枚収録されており、各画像は32×32ピクセルのRGB形式です。
データセットの前処理
データセットを正規化し、ラベルをOne-hot-vector形式に変換します。
# [1-5]
# 正規化。
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
# ラベルをOne-hot-vector化。
y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)
データセットの分割
データセットを以下の通り2分割します。
- Target-In:画像分類器の学習に使用するデータセット。
- Target-Out:画像分類器の学習に使用しないデータセット。
# [1-6]
# データセットの分割。
X_train_target_in = X_train[:25000]
X_train_target_out = X_train[25000:]
y_train_target_in = y_train[:25000]
y_train_target_out = y_train[25000:]
print('Target-In: ', X_train_target_in.shape, y_train_target_in.shape)
print('Target-Out: ', X_train_target_out.shape, y_train_target_out.shape)
攻撃対象モデルの作成
メンバーシップ推論攻撃の標的とする画像分類器を作成します。
モデルの定義
本ハンズオンでは、以下に示すCNN(Convolutional Neural Network)を定義します。
# [1-7]
# モデルの定義。
inputs = Input(shape=(32, 32, 3))
x = Conv2D(64, (3, 3), padding='SAME', activation='relu')(inputs)
x = Conv2D(64, (3, 3), padding='SAME', activation='relu')(x)
x = Dropout(0.25)(x)
x = MaxPooling2D()(x)
x = Conv2D(128, (3,3), padding='SAME', activation='relu')(x)
x = Conv2D(128, (3,3), padding='SAME', activation='relu')(x)
x = Dropout(0.25)(x)
x = MaxPooling2D()(x)
x = Conv2D(256, (3,3), padding='SAME', activation='relu')(x)
x = Conv2D(256, (3,3), padding='SAME', activation='relu')(x)
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dropout(0.25)(x)
y = Dense(10, activation='softmax')(x)
model = Model(inputs, y)
# モデルのコンパイル。
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
モデルの学習
Target-In(X_train_target_in, y_train_target_in
)を使用して画像分類器の学習を行います。
# [1-8]
# 学習の実行。
model.fit(X_train_target_in, y_train_target_in,
batch_size=512,
epochs=50,
validation_split=0.2,
shuffle=True)
モデルの精度評価
学習に使用したTarget-In(X_train_target_in
)と、学習に使用していないTarget-Out(X_train_target_out
)を使用し、各データに対する画像分類器の推論精度を評価します。
# [1-9]
# モデルの精度評価。
# 学習データ(Target-In)。
predictions = model.predict(X_train_target_in)
accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_train_target_in, axis=1)) / len(y_train_target_in)
print('Accuracy on Target-In: {}%'.format(accuracy * 100))
# 学習に使用していないデータ(Target-Out)。
predictions = model.predict(X_train_target_out)
accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_train_target_out, axis=1)) / len(y_train_target_out)
print('Accuracy on Target-Out: {}%'.format(accuracy * 100))
Target-Inの推論精度は約95%程度、Target-Outの推論精度は約75%程度になったと思います。
この結果から、画像分類器は学習データを過学習していることが分かります。
攻撃ネットワークの作成
ARTを使用し、メンバーシップ推論攻撃を行う攻撃ネットワークを作成します。
Keras Classifierの適用
ARTで攻撃ネットワークを作成するためには、攻撃対象の画像分類器をARTが提供するラッパークラスでラップする必要があります。
https://adversarial-robustness-toolbox.readthedocs.io/en/latest/modules/estimators/classification.html#keras-classifier
ARTにはTensorFlow, PyTorch, Scikit-learnなど、様々なフレームワークで作成したモデルをラップするクラスが用意されていますが、本ハンズオンではKerasを使用して分類器を作成しているため、KerasClassifier
を使用します。
KerasClassifier
の引数model
:攻撃対象となる画像分類器を指定します。clip_values
:入力データの特徴量の最小値と最大値を指定します。use_logits
:分類器の出力形式がロジットの場合はTrue、確率値の場合はFalseを指定します。
# [1-10]
# 入力データの特徴量の最小値・最大値を指定。
# 特徴量は0.0~1.0の範囲に収まるように正規化しているため、最小値は0.0、最大値は1.0とする。
min_pixel_value = 0.0
max_pixel_value = 1.0
# モデルをART Keras Classifierでラップ。
target_classifier = KerasClassifier(model=model, clip_values=(min_pixel_value, max_pixel_value), use_logits=False)
攻撃ネットワークの定義
ARTに実装されているメンバーシップ推論攻撃を使用し、攻撃ネットワークを作成します。
https://adversarial-robustness-toolbox.readthedocs.io/en/latest/modules/attacks/inference/membership_inference.html#membership-inference-black-box
メンバーシップ推論攻撃のクラスMembershipInferenceBlackBox
の引数として、ラップした画像分類器と攻撃ネットワークのモデルタイプ(ニューラルネットワーク、ランダムフォレストなど)などを指定します。
MembershipInferenceBlackBox
の引数classifier
:攻撃対象の画像分類器をラップしたKerasClassifier
を指定します。attack_model_type
:攻撃ネットワークのモデルタイプを指定します。デフォルトはnn
(ニューラルネットワーク)。input_type
:攻撃ネットワークの学習に使用するデータ。デフォルトはtarget_classifier
が応答するprediction
(予測結果=信頼スコア)。
本ハンズオンでは、攻撃ネットワークのモデルにrf
(ランダムフォレスト)を採用します。
# [1-11]
# メンバーシップ推論攻撃インスタンスの作成。
attack = MembershipInferenceBlackBox(classifier=target_classifier,
attack_model_type='rf',
input_type='prediction')
攻撃ネットワークの学習
attack
のfit
メソッドを使用し、攻撃ネットワークを作成(学習)します。fit
メソッドの引数には、攻撃対象となる画像分類器(target_classifier
)の「学習に使用したTarget-In(X_train_target_in
)」と、「学習に使用していないTarget-Out(X_train_target_out
)」を与えます。
fit
の引数x
:target_classifier
の学習に使用したTarget-In(X_train_target_in
)を指定。y
:x
のラベルy_train_target_in
を指定。test_x
:target_classifier
の学習に使用していないTarget-Out(X_train_target_out
)を指定。test_y
:test_x
のラベルy_train_target_out
を指定。
fit
メソッドの内部では、x
とtest_x
をそれぞれ([1-11]で指定した)target_classifier
に入力し、その応答(信頼スコア)にTarget-In または Target-Outのラベルを付与することで、Target-InとTarget-Outの信頼スコアの違いを学習します。
# [1-12]
# 攻撃ネットワークの学習。
attack.fit(x=X_train_target_in,
y=y_train_target_in,
test_x=X_train_target_out,
test_y=y_train_target_out)
メンバーシップ推論攻撃の実行
attack
のinfer
メソッドを使用し、攻撃対象の画像分類器に対してメンバーシップ推論攻撃を実行します。infer
メソッドは、推論したいデータ(とラベル)を引数に渡すと、戻り値として1
(メンバーシップ)または0
(非メンバーシップ)を返します。
infer
の引数x
:推論したいデータを指定。y
:x
のラベルを指定。
本ハンズオンでは、画像分類器の学習に使用したTarget-Inと、学習に使用していないTarget-Outをそれぞれ入力し、正しくメンバーシップ または 非メンバーシップとして推論できるのか確認します。
# [1-13]
# 学習データ(Target-In)に対するメンバーシップ推論。
inferred_target_in = attack.infer(x=X_train_target_in, y=y_train_target_in)
print('Inferred for Target-In:')
print('Membership: {}/{} - accuracy: {}%.\n'.format(sum(inferred_target_in), len(inferred_target_in), (sum(inferred_target_in) / len(inferred_target_in))*100))
# 学習に使用していないデータ(Target-Out)に対するメンバーシップ推論。
inferred_target_out = attack.infer(x=X_train_target_out, y=y_train_target_out)
print('Inferred for Target-Out:')
print('Non-Membership: {}/{} - accuracy: {}%.\n'.format(len(inferred_target_out) - sum(inferred_target_out), len(inferred_target_out), (1-(sum(inferred_target_out) / len(inferred_target_out)))*100))
Target-In(X_train_target_in
)は約99%程度の精度、Target-Out(X_train_target_out
)は約80%程度の精度で推論できていることが分かります。
この結果から、メンバーシップ推論攻撃によって、画像分類器が学習したデータ(=メンバーシップ)を高精度で推論できることが分かりました。
次に、メンバーシップ推論の結果を視覚的に確認します。
以下は、Target-InまたはTarget-Outからランダムに1枚の画像を抽出し、攻撃ネットワークに入力しています。
# [1-14]
# Target-InとTarget-Outを結合(合計で50,000)。
target_data = np.concatenate([X_train_target_in, X_train_target_out])
target_label = np.concatenate([y_train_target_in, y_train_target_out])
# 推論対象のデータ・インデックスをランダムに1つ取得。
target_index = random.randint(0, len(target_data)) - 1
# 推論対象のデータを表示。
plt.imshow(target_data[target_index])
# 取得したデータに対するメンバーシップ推論。
truth_label = 'Target-In' if target_index < len(target_data)/2 else 'Target-Out'
inferred_result = attack.infer(x=np.expand_dims(target_data[target_index], axis=0), y=np.expand_dims(target_label[target_index], axis=0))
inferred_label = 'Target-In' if inferred_result[0] == 1 else 'Target-Out'
print('Truth : {}.\nInferred: {}.'.format(truth_label, inferred_label))
表示された画像が、攻撃ネットワークに入力されたデータです。
出力結果のTruth
は、入力データが所属するデータセット・ラベル(Target-In または Target-Out)を示しており、Inferred
が攻撃ネットワークが推論したラベルを示しています(攻撃ネットワークの出力が1
の場合はTarget-In、0
の場合はTarget-Outを表示)。
おそらく、実際のラベルと推論されたラベルは一致していると思います。
※一致しなかった方は[1-14]を再度実行し、入力データを変えてみてください。
おわりに
本ハンズオンでは「第6回:メンバーシップ推論攻撃」と題し、画像分類器が応答する分類結果(信頼スコア)を基に、画像分類器の学習データを推論する攻撃を実践しました。
ARTを使用することで、少ないコード量でメンバーシップ推論攻撃を実行できることが分かりました。
ARTを使用することで容易にAIのセキュリティテストを行うことができるため、ご興味を持たれた方がおりましたら、是非触ってみることをお勧めします。
以上