Mari berkenalan dengan salah satu serangan pada jaringan saraf, yang mengarah pada kesalahan klasifikasi dengan pengaruh eksternal minimal. Bayangkan sejenak bahwa jaringan saraf itu adalah Anda. Dan saat ini, sambil minum secangkir kopi aromatik, Anda mengklasifikasikan gambar kucing dengan akurasi lebih dari 90 persen tanpa curiga bahwa "serangan satu-pixel" mengubah semua "kucing" Anda menjadi truk.Dan sekarang kita akan berhenti sebentar, memindahkan kopi, mengimpor semua perpustakaan yang kita butuhkan dan menganalisis bagaimana serangan satu piksel tersebut bekerja.Tujuan serangan ini adalah membuat algoritma (neural network) memberikan jawaban yang salah. Di bawah ini kita akan melihat ini dengan beberapa model jaringan saraf convolutional yang berbeda. Dengan menggunakan salah satu metode optimisasi matematis multidimensi - evolusi diferensial, kami menemukan piksel khusus yang dapat mengubah gambar sehingga jaringan saraf mulai mengklasifikasikan gambar ini secara salah (terlepas dari kenyataan bahwa sebelumnya algoritme โmengenaliโ gambar yang sama dengan benar dan dengan akurasi tinggi).Impor perpustakaan:
%matplotlib inline
import pickle
import numpy as np
import pandas as pd
import matplotlib
from keras.datasets import cifar10
from keras import backend as K
from networks.lenet import LeNet
from networks.pure_cnn import PureCnn
from networks.network_in_network import NetworkInNetwork
from networks.resnet import ResNet
from networks.densenet import DenseNet
from networks.wide_resnet import WideResNet
from networks.capsnet import CapsNet
from differential_evolution import differential_evolution
import helper
matplotlib.style.use('ggplot')
Untuk percobaan kami, kami akan memuat dataset CIFAR-10 yang berisi gambar dunia nyata dibagi menjadi 10 kelas.(x_train, y_train), (x_test, y_test) = cifar10.load_data()
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
Mari kita lihat gambar apa saja berdasarkan indeksnya. Misalnya, di sini di atas kuda ini.image_id = 99
helper.plot_image(x_test[image_id])
Kami harus mencari piksel yang sangat kuat yang dapat mengubah respons jaringan saraf, yang berarti saatnya untuk menulis fungsi untuk mengubah satu atau lebih piksel gambar.def perturb_image(xs, img):
if xs.ndim < 2:
xs = np.array([xs])
tile = [len(xs)] + [1]*(xs.ndim+1)
imgs = np.tile(img, tile)
xs = xs.astype(int)
for x,img in zip(xs, imgs):
pixels = np.split(x, len(x) // 5)
for pixel in pixels:
x_pos, y_pos, *rgb = pixel
img[x_pos, y_pos] = rgb
return imgs
Coba lihat ?! Ubah satu piksel kuda kita dengan koordinat (16, 16) menjadi kuning.image_id = 99
pixel = np.array([16, 16, 255, 255, 0])
image_perturbed = perturb_image(pixel, x_test[image_id])[0]
helper.plot_image(image_perturbed)
Untuk mendemonstrasikan serangan, Anda perlu mengunduh model-model jaringan saraf pra-terlatih pada dataset CIFAR-10 kami. Kami akan menggunakan dua model lenet dan resnet, tetapi Anda dapat menggunakan yang lain untuk percobaan Anda dengan menghapus komentar pada baris kode yang sesuai.lenet = LeNet()
resnet = ResNet()
models = [lenet, resnet]
Setelah memuat model, perlu untuk mengevaluasi gambar uji masing-masing model untuk memastikan bahwa kami hanya menyerang gambar yang diklasifikasikan dengan benar. Kode di bawah ini menampilkan akurasi dan jumlah parameter untuk masing-masing model.network_stats, correct_imgs = helper.evaluate_models(models, x_test, y_test)
correct_imgs = pd.DataFrame(correct_imgs, columns=['name', 'img', 'label', 'confidence', 'pred'])
network_stats = pd.DataFrame(network_stats, columns=['name', 'accuracy', 'param_count'])
network_stats
Evaluating lenet
Evaluating resnet
Out[11]:
name accuracy param_count
0 lenet 0.748 62006
1 resnet 0.9231 470218
Semua serangan seperti itu dapat dibagi menjadi dua kelas: WhiteBox dan BlackBox. Perbedaan di antara mereka adalah bahwa dalam kasus pertama, kita semua tahu tentang algoritma, model yang kita pakai. Dalam kasus BlackBox, yang kita butuhkan adalah input (gambar) dan output (probabilitas ditugaskan ke salah satu kelas). Satu serangan pixel mengacu pada BlackBox.Dalam artikel ini, kami mempertimbangkan dua opsi untuk menyerang satu piksel: tidak bertarget dan bertarget. Dalam kasus pertama, sama sekali tidak masalah untuk kelas mana jaringan saraf kucing kita akan menjadi milik, yang paling penting, bukan untuk kelas kucing. Serangan yang ditargetkan berlaku ketika kita ingin kucing kita menjadi sebuah truk dan hanya sebuah truk.Tetapi bagaimana cara menemukan piksel yang perubahannya akan menyebabkan perubahan pada kelas gambar? Bagaimana menemukan piksel dengan mengubah serangan satu piksel yang menjadi mungkin dan berhasil? Mari kita coba merumuskan masalah ini sebagai masalah optimisasi, tetapi hanya dengan kata-kata yang sangat sederhana: dengan serangan yang tidak ditargetkan, kita harus meminimalkan kepercayaan pada kelas yang diinginkan, dan dengan target, memaksimalkan kepercayaan pada kelas target.Saat melakukan serangan seperti itu, sulit untuk mengoptimalkan fungsi menggunakan gradien. Algoritme pengoptimalan harus digunakan yang tidak bergantung pada kelancaran fungsi.Ingatlah bahwa untuk percobaan kami, kami menggunakan dataset CIFAR-10, yang berisi gambar dunia nyata, berukuran 32 x 32 piksel, dibagi menjadi 10 kelas. Ini berarti bahwa kami memiliki nilai integer diskrit dari 0 hingga 31 dan intensitas warna dari 0 hingga 255, dan fungsinya tidak diharapkan mulus, melainkan bergerigi, seperti yang ditunjukkan di bawah ini:
Itulah sebabnya kami menggunakan algoritma evolusi diferensial.Tetapi kembali ke kode dan tulis fungsi yang mengembalikan probabilitas keandalan model. Jika kelas target benar, maka kami ingin meminimalkan fungsi ini sehingga modelnya yakin dengan kelas lain (yang tidak benar).def predict_classes(xs, img, target_class, model, minimize=True):
imgs_perturbed = perturb_image(xs, img)
predictions = model.predict(imgs_perturbed)[:,target_class]
return predictions if minimize else 1 - predictions
image_id = 384
pixel = np.array([16, 13, 25, 48, 156])
model = resnet
true_class = y_test[image_id, 0]
prior_confidence = model.predict_one(x_test[image_id])[true_class]
confidence = predict_classes(pixel, x_test[image_id], true_class, model)[0]
print('Confidence in true class', class_names[true_class], 'is', confidence)
print('Prior confidence was', prior_confidence)
helper.plot_image(perturb_image(pixel, x_test[image_id])[0])
Confidence in true class bird is 0.00018887444
Prior confidence was 0.70661753
Kami akan membutuhkan fungsi berikutnya untuk mengkonfirmasi kriteria untuk keberhasilan serangan, itu akan mengembalikan Benar ketika perubahan sudah cukup untuk menipu model.def attack_success(x, img, target_class, model, targeted_attack=False, verbose=False):
attack_image = perturb_image(x, img)
confidence = model.predict(attack_image)[0]
predicted_class = np.argmax(confidence)
if verbose:
print('Confidence:', confidence[target_class])
if ((targeted_attack and predicted_class == target_class) or
(not targeted_attack and predicted_class != target_class)):
return True
Mari kita lihat karya fungsi kriteria kesuksesan. Untuk menunjukkan, kami menganggap serangan non-target.image_id = 541
pixel = np.array([17, 18, 185, 36, 215])
model = resnet
true_class = y_test[image_id, 0]
prior_confidence = model.predict_one(x_test[image_id])[true_class]
success = attack_success(pixel, x_test[image_id], true_class, model, verbose=True)
print('Prior confidence', prior_confidence)
print('Attack success:', success == True)
helper.plot_image(perturb_image(pixel, x_test[image_id])[0])
Confidence: 0.07460087
Prior confidence 0.50054216
Attack success: True
Sudah waktunya untuk mengumpulkan semua teka-teki menjadi satu gambar. Kami akan menggunakan modifikasi kecil dari implementasi evolusi diferensial dalam Scipy.def attack(img_id, model, target=None, pixel_count=1,
maxiter=75, popsize=400, verbose=False):
targeted_attack = target is not None
target_class = target if targeted_attack else y_test[img_id, 0]
bounds = [(0,32), (0,32), (0,256), (0,256), (0,256)] * pixel_count
popmul = max(1, popsize // len(bounds))
def predict_fn(xs):
return predict_classes(xs, x_test[img_id], target_class,
model, target is None)
def callback_fn(x, convergence):
return attack_success(x, x_test[img_id], target_class,
model, targeted_attack, verbose)
attack_result = differential_evolution(
predict_fn, bounds, maxiter=maxiter, popsize=popmul,
recombination=1, atol=-1, callback=callback_fn, polish=False)
attack_image = perturb_image(attack_result.x, x_test[img_id])[0]
prior_probs = model.predict_one(x_test[img_id])
predicted_probs = model.predict_one(attack_image)
predicted_class = np.argmax(predicted_probs)
actual_class = y_test[img_id, 0]
success = predicted_class != actual_class
cdiff = prior_probs[actual_class] - predicted_probs[actual_class]
helper.plot_image(attack_image, actual_class, class_names, predicted_class)
return [model.name, pixel_count, img_id, actual_class, predicted_class, success, cdiff, prior_probs, predicted_probs, attack_result.x]
Sudah waktunya untuk membagikan hasil penelitian (serangan) dan melihat bagaimana mengubah hanya satu piksel akan mengubah katak menjadi anjing, kucing menjadi katak, dan mobil menjadi pesawat terbang. Tetapi semakin banyak titik gambar yang dibiarkan berubah, semakin tinggi kemungkinan serangan berhasil pada gambar apa pun.

Peragakan serangan yang berhasil pada gambar katak menggunakan model resnet. Kita harus melihat kepercayaan pada penurunan kelas yang sebenarnya setelah beberapa iterasi.image_id = 102
pixels = 1
model = resnet
_ = attack(image_id, model, pixel_count=pixels, verbose=True)
Confidence: 0.9938618
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.4211318
Ini adalah contoh serangan yang tidak ditargetkan, dan sekarang kami akan melakukan serangan yang ditargetkan dan memilih kelas mana yang kami inginkan model untuk mengklasifikasikan gambar. Tugasnya jauh lebih rumit daripada yang sebelumnya, karena kita akan membuat jaringan saraf mengklasifikasikan citra kapal sebagai mobil, dan kuda sebagai kucing.
Di bawah ini kita akan mencoba mendapatkan lenet untuk mengklasifikasikan citra kapal sebagai mobil.image_id = 108
target_class = 1
pixels = 3
model = lenet
print('Attacking with target', class_names[target_class])
_ = attack(image_id, model, target_class, pixel_count=pixels, verbose=True)
Attacking with target automobile
Confidence: 0.044409167
Confidence: 0.044409167
Confidence: 0.044409167
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.1537778
Confidence: 0.1537778
Confidence: 0.1537778
Confidence: 0.22246778
Confidence: 0.23916133
Confidence: 0.25238588
Confidence: 0.25238588
Confidence: 0.25238588
Confidence: 0.44560355
Confidence: 0.44560355
Confidence: 0.44560355
Confidence: 0.5711696
Setelah menangani satu kasus serangan, kami akan mengumpulkan statistik menggunakan arsitektur jaringan saraf konvolusional ResNet, melalui masing-masing model, mengubah 1, 3 atau 5 piksel dari setiap gambar. Pada artikel ini, kami menunjukkan kesimpulan akhir tanpa mengganggu pembaca untuk membiasakan diri dengan setiap iterasi, karena itu membutuhkan banyak waktu dan sumber daya komputasi.def attack_all(models, samples=500, pixels=(1,3,5), targeted=False,
maxiter=75, popsize=400, verbose=False):
results = []
for model in models:
model_results = []
valid_imgs = correct_imgs[correct_imgs.name == model.name].img
img_samples = np.random.choice(valid_imgs, samples, replace=False)
for pixel_count in pixels:
for i, img_id in enumerate(img_samples):
print('\n', model.name, '- image', img_id, '-', i+1, '/', len(img_samples))
targets = [None] if not targeted else range(10)
for target in targets:
if targeted:
print('Attacking with target', class_names[target])
if target == y_test[img, 0]:
continue
result = attack(img_id, model, target, pixel_count,
maxiter=maxiter, popsize=popsize,
verbose=verbose)
model_results.append(result)
results += model_results
helper.checkpoint(results, targeted)
return results
untargeted = attack_all(models, samples=100, targeted=False)
targeted = attack_all(models, samples=10, targeted=False)
Untuk menguji kemungkinan diskon jaringan, suatu algoritma dikembangkan dan pengaruhnya terhadap kualitas perkiraan solusi pengenalan pola diukur.Mari kita lihat hasil akhirnya.untargeted, targeted = helper.load_results()
columns = ['model', 'pixels', 'image', 'true', 'predicted', 'success', 'cdiff', 'prior_probs', 'predicted_probs', 'perturbation']
untargeted_results = pd.DataFrame(untargeted, columns=columns)
targeted_results = pd.DataFrame(targeted, columns=columns)
Tabel di bawah ini menunjukkan bahwa menggunakan jaringan saraf ResNet dengan akurasi 0,9231, mengubah beberapa piksel gambar, kami mendapatkan persentase yang sangat baik dari gambar yang berhasil diserang (attack_success_rate).helper.attack_stats(targeted_results, models, network_stats)
Out[26]:
model accuracy pixels attack_success_rate
0 resnet 0.9231 1 0.144444
1 resnet 0.9231 3 0.211111
2 resnet 0.9231 5 0.222222
helper.attack_stats(untargeted_results, models, network_stats)
Out[27]:
model accuracy pixels attack_success_rate
0 resnet 0.9231 1 0.34
1 resnet 0.9231 3 0.79
2 resnet 0.9231 5 0.79
Dalam percobaan Anda, Anda bebas untuk menggunakan arsitektur lain dari jaringan saraf tiruan, karena saat ini ada banyak sekali dari mereka.
Jaringan saraf telah menyelimuti dunia modern dengan utas yang tak terlihat. Layanan telah lama ditemukan di mana, menggunakan AI (kecerdasan buatan), pengguna mendapatkan foto yang diproses dengan gaya mirip dengan karya seniman hebat, dan hari ini algoritma sudah dapat menggambar sendiri, membuat karya musik, menulis buku, dan bahkan naskah untuk film.Bidang-bidang seperti penglihatan komputer, pengenalan wajah, kendaraan tak berawak, diagnosa penyakit - membuat keputusan penting dan tidak memiliki hak untuk melakukan kesalahan, dan gangguan dengan pengoperasian algoritme akan menyebabkan konsekuensi bencana.Serangan satu piksel adalah salah satu cara untuk menipu serangan. Untuk menguji kemungkinan diskon jaringan, suatu algoritma dikembangkan dan pengaruhnya terhadap kualitas perkiraan solusi pengenalan pola diukur. Hasil penelitian menunjukkan bahwa arsitektur jaringan saraf convolutional yang digunakan rentan terhadap algoritma serangan One pixel terlatih, yang menggantikan satu piksel, untuk mendiskreditkan algoritma pengakuan.Artikel ini disiapkan oleh Alexander Andronic dan Adrey Cherny-Tkach sebagai bagian dari magang di Data4 .