Python 3 ile Bir Sinir Ağını Nasıl Kandırırsınız?
Sinir ağları, son yıllarda yapay zeka alanında devrim niteliğinde ilerlemeler kaydetmiş, görüntü tanıma, doğal dil işleme, ses sentezi ve otonom sürüş gibi birçok alanda insan performansını aşan sonuçlar elde etmiştir. Bu güçlü modellerin yaygınlaşmasıyla birlikte, güvenlik ve sağlamlık (robustness) konuları da giderek daha fazla önem kazanmaktadır. Bir sinir ağına, insan gözüyle algılanması neredeyse imkansız olan küçük, kasıtlı değişiklikler (perturbations) eklenmiş girişler sunarak, modelin tamamen yanlış bir sınıflandırma yapmasını sağlamak mümkündür. Bu tür girişlere “düşmanca örnekler” (adversarial examples) denir ve bu makalede, Python 3 kullanarak bir sinir ağını nasıl kandırabileceğinizi, bu düşmanca örneklerin nasıl oluşturulduğunu ve bunlara karşı ne gibi önlemler alınabileceğini teknik detaylarıyla inceleyeceğiz.
Sinir Ağlarının Güvenliği ve Sağlamlığı Neden Önemli?
Yapay zeka sistemleri, finansal kararlardan tıbbi teşhislere, güvenlik kameralarından otonom araçlara kadar hayatımızın kritik alanlarında kullanılmaya başlanmıştır. Bu sistemlerin güvenilirliği, doğru ve tutarlı kararlar vermesi hayati önem taşır. Ancak, düşmanca örneklerin varlığı, bu sistemlerin potansiyel güvenlik açıklarını ve kırılganlıklarını ortaya koymaktadır.
* Otonom Araçlar: Bir dur işaretine eklenen küçük bir çıkartma veya piksel değişikliği, aracın işareti “hız sınırı” olarak algılamasına neden olabilir, bu da ciddi kazalara yol açabilir.
* Tıbbi Teşhis: Kanserli bir hücre görüntüsüne yapılan minimal bir müdahale, yapay zeka destekli bir teşhis sisteminin bunu “sağlıklı” olarak etiketlemesine neden olabilir, bu da yanlış tedaviye veya teşhisin gecikmesine yol açar.
* Yüz Tanıma Sistemleri: Bir kişinin yüzüne yapılan ufak bir değişiklikle (örneğin özel bir gözlük takarak), sistemin onu başka bir kişi olarak tanımlaması veya hiç tanıyamaması mümkündür.
* Siber Güvenlik: Kötü amaçlı yazılımların (malware) koduna eklenen düşmanca değişiklikler, antivirüs programlarının bunları tespit etmesini zorlaştırabilir.
Bu senaryolar, sinir ağlarının sadece yüksek doğruluk oranlarına sahip olmasının yeterli olmadığını, aynı zamanda beklenmedik ve kasıtlı saldırılara karşı da sağlam olmaları gerektiğini göstermektedir. Düşmanca örnekler, bu sağlamlığın test edilmesi ve geliştirilmesi gereken kritik bir alanı temsil eder.
Düşmanca Örnekler (Adversarial Examples) Nedir?
Düşmanca örnekler, bir makine öğrenimi modelini yanıltmak amacıyla tasarlanmış, orijinal veriye çok küçük ve genellikle insan gözüyle fark edilemeyen değişiklikler eklenmiş veri örnekleridir. Bu değişiklikler, modelin tahminini veya sınıflandırmasını kasıtlı olarak yanlış yöne çevirir. İlk olarak Christian Szegedy ve arkadaşları tarafından 2013 yılında keşfedilen bu fenomen, derin öğrenme topluluğunda büyük bir şaşkınlık yaratmıştır.
Peki, neden bu kadar küçük değişiklikler bir sinir ağını bu kadar derinden etkileyebilir? Bunun temel nedenlerinden biri, sinir ağlarının yüksek boyutlu giriş uzaylarında doğrusal (linear) davranış sergileme eğiliminde olmasıdır. Küçük bir pertürbasyon, her boyutta çok az bir değişiklik yaratırken, yüksek boyutlu uzayda bu küçük değişikliklerin birikimi, modelin karar sınırını geçmesine neden olabilir. Bir başka açıklama ise, modellerin genellikle eğitim verisindeki bazı “kırılgan” veya “aşırı güvenli” özelliklere aşırı derecede güvenmesidir. Düşmanca pertürbasyonlar, bu özelliklerin manipüle edilmesi yoluyla modelin yanlış bir sonuca varmasını sağlar.
Düşmanca Saldırı Türleri
Düşmanca saldırılar, saldırganın hedef model hakkındaki bilgi düzeyine göre iki ana kategoriye ayrılır: beyaz kutu (white-box) saldırılar ve siyah kutu (black-box) saldırılar.
Beyaz Kutu Saldırıları (White-Box Attacks)
Beyaz kutu saldırılarında, saldırganın hedef modelin tüm detaylarına (mimarisi, ağırlıkları, eğitim algoritması ve hatta gradyan bilgisi) tam erişimi vardır. Bu bilgi, saldırganın düşmanca örnekleri çok daha etkili bir şekilde oluşturmasına olanak tanır.
Hızlı Gradyan İşaret Yöntemi (Fast Gradient Sign Method – FGSM)
FGSM, Ian Goodfellow ve arkadaşları tarafından 2014 yılında tanıtılan, en basit ve en yaygın beyaz kutu saldırılarından biridir. Temel fikir, modelin kaybını (loss) maksimize edecek yönde, giriş görüntüsüne küçük bir pertürbasyon eklemektir. Bu pertürbasyon, girişin gradyanının işareti (sign) kullanılarak hesaplanır.
Matematiksel olarak, FGSM saldırısı şu şekilde ifade edilir:
$x_{adv} = x + \epsilon \cdot \text{sign}(\nabla_x J(\theta, x, y))$
Burada:
* $x$: Orijinal giriş görüntüsü.
* $x_{adv}$: Düşmanca örnek (perturbed image).
* $\epsilon$: Pertürbasyonun büyüklüğünü kontrol eden küçük pozitif bir skaler değer. İnsan gözüyle fark edilebilirliği ve saldırının etkinliği arasında bir denge kurar.
* $J(\theta, x, y)$: Modelin $\theta$ parametreleri, giriş $x$ ve gerçek etiket $y$ için kayıp fonksiyonu.
* $\nabla_x J(\theta, x, y)$: Kayıp fonksiyonunun giriş $x$’e göre gradyanı. Bu gradyan, modelin kaybını artırmak için $x$’in hangi yönde değiştirilmesi gerektiğini gösterir.
* $\text{sign}(\cdot)$: İşaret fonksiyonu. Gradyan vektöründeki her bir elemanın işaretini (+1 veya -1) alır.
FGSM, tek adımlı bir saldırıdır. Gradyanın işaretini alarak, her pikseli, kaybı artıracak yönde $\epsilon$ kadar değiştirir. Bu yöntem, hesaplama açısından verimli olduğu için “hızlı” olarak adlandırılır.
Tekrarlayan FGSM (Iterative FGSM / Basic Iterative Method – BIM)
FGSM’nin daha güçlü bir versiyonudur. Tek bir büyük $\epsilon$ adımı yerine, daha küçük $\epsilon’$ adımları kullanarak FGSM’yi birden çok kez tekrarlar. Her adımda, üretilen düşmanca örnek, bir sonraki adım için başlangıç noktası olarak kullanılır ve pertürbasyon belirli bir $L_{\infty}$ normu içinde kalacak şekilde kırpılır.
DeepFool
Saldırıyı geometrik bir perspektiften ele alır. Modelin karar sınırına en yakın noktayı bulmaya çalışarak, sınıflandırmayı değiştirecek en küçük pertürbasyonu bulmayı hedefler.
Carlini & Wagner (C&W) Saldırıları
Güncel düşmanca saldırılar arasında en etkili olanlardan biridir. $L_0, L_2, L_{\infty}$ normları altında optimize edilmiş pertürbasyonlar üretir ve genellikle diğer saldırılara karşı daha zor savunulur. Bu saldırılar, düşmanca örneğin insan gözüyle algılanabilirliğini minimumda tutarken, modelin tahminini belirli bir hedefe yönlendirme konusunda oldukça başarılıdır.
Siyah Kutu Saldırıları (Black-Box Attacks)
Siyah kutu saldırılarında, saldırganın hedef modelin iç yapısı (mimari, ağırlıklar) hakkında hiçbir bilgisi yoktur. Sadece modelin giriş-çıkış arayüzüne (örneğin, bir API aracılığıyla giriş gönderip tahminleri almak) erişimi vardır. Bu tür saldırılar, gerçek dünya senaryolarında daha olasıdır.
Aktarılabilirlik (Transferability)
Düşmanca örneklerin şaşırtıcı bir özelliği, bir model için oluşturulan düşmanca bir örneğin, farklı bir model üzerinde de etkili olabilmesidir. Bu fenomen, “aktarılabilirlik” olarak adlandırılır. Saldırgan, hedef modele benzer bir “ikame model” (substitute model) eğiterek, bu ikame model üzerinde beyaz kutu saldırısı yapar ve elde ettiği düşmanca örnekleri hedef siyah kutu modele karşı kullanır.
Sorgu Tabanlı Saldırılar (Query-based Attacks)
Bu saldırılar, hedef modele tekrarlanan sorgular göndererek ve modelin yanıtlarını analiz ederek düşmanca örnekler oluşturmaya çalışır. Modelin gradyanlarını doğrudan hesaplayamadıkları için, gradyanları tahmin etmek için sayısal yaklaşımlar (örneğin, sonlu farklar) veya evrimsel algoritmalar kullanabilirler. Ancak, bu tür saldırılar genellikle çok sayıda sorgu gerektirdiği için daha yavaştır.
Python 3 ile FGSM Saldırısı Uygulaması
Şimdi, Python 3 ve TensorFlow/Keras kütüphanelerini kullanarak basit bir sinir ağı eğitecek ve bu ağa karşı bir FGSM saldırısı gerçekleştireceğiz. MNIST veri kümesini kullanacağız, çünkü bu veri kümesi basit sayılar içerir ve görselleştirmesi kolaydır.
Gerekli Kütüphaneler
Öncelikle gerekli kütüphaneleri yükleyelim:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import matplotlib.pyplot as plt
Veri Kümesini Yükleme ve Hazırlama
MNIST veri kümesini yükleyip, görüntüleri normalize edeceğiz ve boyutlarını modelin beklediği formata uygun hale getireceğiz.
# MNIST veri kümesini yükle
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
Görüntüleri 0-1 aralığına normalize et
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
Görüntü boyutlarını CNN modeline uygun hale getir (kanal boyutu ekle)
MNIST görüntüleri (28, 28) boyutundadır, (28, 28, 1) olmalı
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
Etiketleri one-hot encode etmeye gerek yok, Keras'ın SparseCategoricalCrossentropy'si ile çalışabiliriz
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
print(f"Eğitim verisi boyutu: {x_train.shape}")
print(f"Test verisi boyutu: {x_test.shape}")
Basit Bir CNN Modeli Eğitme
Düşmanca saldırıları test etmek için basit bir Evrişimsel Sinir Ağı (CNN) modeli oluşturup eğiteceğiz.
def create_model():
model = keras.Sequential([
keras.Input(shape=(28, 28, 1)),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
layers.Dense(10, activation="softmax"),
])
model.compile(optimizer="adam",
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["accuracy"])
return model
Modeli oluştur ve eğit
model = create_model()
model.summary()
batch_size = 128
epochs = 10
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
Modelin test verisi üzerindeki performansını değerlendir
score = model.evaluate(x_test, y_test, verbose=0)
print(f"Test kaybı: {score[0]:.4f}")
print(f"Test doğruluğu: {score[1]:.4f}")
Bu model, MNIST test setinde yaklaşık %99 doğruluk elde etmelidir. Bu yüksek doğruluk, düşmanca saldırının ne kadar etkili olduğunu göstermemize yardımcı olacaktır.
FGSM Saldırısı Fonksiyonu Oluşturma
Şimdi FGSM algoritmasını uygulayan bir fonksiyon yazalım. Bu fonksiyon, bir model, orijinal görüntü ve $\epsilon$ değeri alacak ve düşmanca bir görüntü döndürecektir.
def fgsm_attack(model, image, label, epsilon):
# Görüntünün gradyanlarını hesaplamak için izlenebilir olmasını sağlar
image = tf.convert_to_tensor(image, dtype=tf.float32)
with tf.GradientTape() as tape:
tape.watch(image)
prediction = model(tf.expand_dims(image, axis=0)) # Modelin tek bir görüntüye tahmin yapmasını sağlar
loss = keras.losses.SparseCategoricalCrossentropy(from_logits=False)(label, prediction)
# Görüntünün kayıp fonksiyonuna göre gradyanını hesapla
gradient = tape.gradient(loss, image)
# Gradyanın işaretini al (sign)
signed_grad = tf.sign(gradient)
# Düşmanca görüntüyü oluştur
adversarial_image = image + epsilon * signed_grad
# Görüntünün 0-1 aralığında kalmasını sağla (kırpma)
adversarial_image = tf.clip_by_value(adversarial_image, 0, 1)
return adversarial_image.numpy() # NumPy dizisi olarak döndür
Bu fonksiyonun adımlarını açıklayalım:
1. tape.watch(image): TensorFlow’un GradientTape‘i, belirli bir tensor üzerindeki operasyonları izleyerek gradyanları hesaplamayı sağlar. Burada image tensor’ını izlemeye alıyoruz.
2. model(tf.expand_dims(image, axis=0)): Model, genellikle bir batch (toplu) giriş bekler. Tek bir görüntü için tahmin yaparken, expand_dims ile batch boyutunu ekliyoruz.
3. loss = ... (label, prediction): Modelin tahmini ile gerçek etiket arasındaki kaybı hesaplıyoruz. FGSM’nin amacı bu kaybı maksimize etmektir.
4. gradient = tape.gradient(loss, image): Kayıp fonksiyonunun, giriş görüntüye göre gradyanını hesaplıyoruz. Bu gradyan, kaybı en çok artıracak yönde görüntü piksellerinin nasıl değişmesi gerektiğini gösterir.
5. signed_grad = tf.sign(gradient): Gradyan vektöründeki her bir pikselin işaretini alıyoruz (+1 veya -1). Bu, her pikselin hangi yönde (artırma veya azaltma) değiştirileceğini belirler.
6. adversarial_image = image + epsilon * signed_grad: Orijinal görüntüye, gradyanın işaretiyle çarpılmış $\epsilon$ değerini ekleyerek düşmanca görüntüyü oluşturuyoruz. $\epsilon$, pertürbasyonun büyüklüğünü kontrol eder.
7. tf.clip_by_value(adversarial_image, 0, 1): Görüntü piksellerinin 0 ile 1 arasında kalmasını sağlıyoruz. Bu, görüntülerin geçerli piksel değerleri aralığında kalmasını garanti eder.
Saldırıyı Uygulama ve Sonuçları Görselleştirme
Şimdi, test setinden rastgele bir görüntü alıp FGSM saldırısını uygulayalım ve sonuçları görselleştirelim.
# Rastgele bir test görüntüsü seç
idx = np.random.randint(0, len(x_test))
original_image = x_test[idx]
true_label = y_test[idx]
Orijinal görüntünün model tarafından tahminini al
original_prediction = model.predict(np.expand_dims(original_image, axis=0))
original_predicted_label = np.argmax(original_prediction)
print(f"Orijinal Görüntü - Gerçek Etiket: {true_label}")
print(f"Orijinal Görüntü - Model Tahmini: {original_predicted_label} (Güven: {np.max(original_prediction):.2f})")
Epsilon değerleri ile FGSM saldırısını dene
epsilons = [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3] # Pertürbasyonun büyüklüğü
plt.figure(figsize=(15, 6))
for i, eps in enumerate(epsilons):
# FGSM saldırısını uygula
adversarial_image = fgsm_attack(model, original_image, true_label, eps)
# Düşmanca görüntünün model tarafından tahminini al
adversarial_prediction = model.predict(np.expand_dims(adversarial_image, axis=0))
adversarial_predicted_label = np.argmax(adversarial_prediction)
# Görüntüleri görselleştir
plt.subplot(2, len(epsilons), i + 1)
plt.imshow(original_image.squeeze(), cmap='gray')
plt.title(f"Orijinal: {true_label}\nTahmin: {original_predicted_label}", fontsize=8)
plt.axis('off')
plt.subplot(2, len(epsilons), len(epsilons) + i + 1)
plt.imshow(adversarial_image.squeeze(), cmap='gray')
plt.title(f"Eps: {eps:.2f}\nTahmin: {adversarial_predicted_label}\n(Güven: {np.max(adversarial_prediction):.2f})", fontsize=8)
plt.axis('off')
if original_predicted_label == true_label and adversarial_predicted_label != true_label:
print(f"\nEpsilon = {eps:.2f}: Orijinal tahmin {original_predicted_label}, Düşmanca tahmin {adversarial_predicted_label}. Saldırı Başarılı!")
elif original_predicted_label != true_label:
print(f"\nEpsilon = {eps:.2f}: Orijinal tahmin zaten yanlış. ({original_predicted_label} yerine {true_label})")
else:
print(f"\nEpsilon = {eps:.2f}: Orijinal ve düşmanca tahminler aynı. ({original_predicted_label})")
plt.tight_layout()
plt.show()
Bu kod bloğunu çalıştırdığınızda, orijinal görüntünün ve farklı $\epsilon$ değerleri için oluşturulmuş düşmanca görüntülerin bir karşılaştırmasını göreceksiniz. Genellikle, $\epsilon$ değeri arttıkça, düşmanca görüntüler insan gözüyle daha belirgin hale gelirken, modelin yanlış sınıflandırma yapma olasılığı da artar. Bazı durumlarda, çok küçük bir $\epsilon$ değeri bile modelin tahminini tamamen değiştirmeye yeterli olabilirken, görüntüde neredeyse hiçbir değişiklik fark edilmez. Bu, düşmanca örneklerin ne kadar tehlikeli olabileceğini açıkça gösterir.
Saldırıları Önleme Yöntemleri (Savunma Mekanizmaları)
Düşmanca saldırıların ciddiyeti, araştırmacıları bu tür saldırılara karşı savunma mekanizmaları geliştirmeye yöneltmiştir. Ancak, bu alan bir “silahlanma yarışı” gibidir; yeni savunmalar genellikle daha güçlü saldırılarla aşılır.
Düşmanca Eğitim (Adversarial Training)
En etkili savunma yöntemlerinden biri olarak kabul edilir. Model, sadece orijinal verilerle değil, aynı zamanda düşmanca örneklerle de eğitilir. Bu, modelin düşmanca pertürbasyonlara karşı daha sağlam olmayı öğrenmesine yardımcı olur. Süreç genellikle şu şekildedir:
1. Model, orijinal veriler üzerinde eğitilir.
2. Eğitilmiş model kullanılarak, eğitim verisinden düşmanca örnekler oluşturulur (örneğin FGSM ile).
3. Model, hem orijinal hem de oluşturulan düşmanca örnekler üzerinde yeniden eğitilir. Bu döngü tekrarlanabilir.
Giriş Ön İşleme ve Filtreleme
Modelin girdilerine ulaşmadan önce, olası düşmanca pertürbasyonları tespit etmek veya ortadan kaldırmak için çeşitli ön işleme teknikleri uygulanabilir. Bunlar arasında gürültü giderme (denoising), görüntü sıkıştırma (compression) veya piksel kırpma gibi yöntemler bulunur. Ancak, bu yöntemler genellikle düşmanca saldırıları tamamen engelleyemez ve bazen modelin performansını da düşürebilir.
Gradyan Maskeleme/Gizleme (Gradient Masking/Obfuscation)
Bazı savunmalar, modelin gradyanlarını gizleyerek veya manipüle ederek beyaz kutu saldırılarını zorlaştırmayı hedefler. Örneğin, modelin gradyanlarının rastgeleleştirilmesi veya düzleştirilmesi. Ancak, bu tür savunmalar genellikle daha sofistike saldırılar (örneğin C&W saldırıları) tarafından aşılabilir.
Defansif Damıtma (Defensive Distillation)
Bu yöntemde, bir “öğretmen” modelden alınan “yumuşatılmış” (softened) tahminler kullanılarak bir “öğrenci” model eğitilir. Öğretmen modelin sınıf olasılıkları, daha yüksek bir sıcaklık (temperature) parametresi ile softmax kullanılarak yumuşatılır. Bu, öğrenci modelin daha düzgün karar sınırları öğrenmesine ve dolayısıyla düşmanca pertürbasyonlara karşı daha az hassas olmasına yardımcı olabilir.
Rastgeleleştirme (Randomization)
Modelin giriş katmanına rastgele gürültü eklemek veya giriş görüntülerini rastgele dönüştürmek (örneğin, rastgele boyutlandırma, kırpma) de bir savunma stratejisi olabilir. Bu, düşmanca örneklerin spesifik pertürbasyonlarının etkisini azaltabilir.
Etik Boyutlar ve Gelecek
Düşmanca örnekler üzerine yapılan araştırmalar, yapay zeka sistemlerinin güvenliği ve güvenilirliği açısından kritik öneme sahiptir. Bu alandaki “silahlanma yarışı” devam etmektedir: saldırganlar daha güçlü saldırı yöntemleri geliştirirken, savunmacılar da daha sağlam modeller tasarlamaya çalışmaktadır.
Bu tür saldırıların anlaşılması, sadece potansiyel güvenlik açıklarını kapatmak için değil, aynı zamanda yapay zeka modellerinin neden belirli kararlar verdiğini daha iyi anlamak için de önemlidir. Düşmanca örneklerin varlığı, modellerin insan sezgilerinden farklı “mantıklar” kullandığını ve bu mantıkların manipülasyona açık olabileceğini göstermektedir.
Gelecekteki araştırmalar, daha sağlam model mimarileri geliştirmeye, düşmanca örnekleri otomatik olarak tespit etme yöntemlerine ve modellerin genelleme yeteneklerini artırarak bu kırılganlıkları azaltmaya odaklanacaktır. Ayrıca, düşmanca saldırıların yasal ve etik sonuçları da giderek daha fazla tartışılmaya başlanacaktır, özellikle yapay zeka sistemlerinin kritik altyapılarda veya insan hayatını etkileyen kararlarda kullanıldığı durumlarda.
Sonuç
Bu makalede, Python 3 ve TensorFlow/Keras kullanarak bir sinir ağını düşmanca örneklerle nasıl kandıracağımızı, özellikle Fast Gradient Sign Method (FGSM) saldırısını detaylı bir şekilde inceledik. Düşmanca örneklerin, insan gözüyle algılanması zor olan küçük pertürbasyonlarla bile bir modelin tahminini tamamen değiştirebildiğini gördük. Bu durum, yapay zeka sistemlerinin sadece yüksek doğruluk oranlarına sahip olmasının yeterli olmadığını, aynı zamanda kötü niyetli saldırılara karşı da sağlam olmaları gerektiğini vurgulamaktadır.
Düşmanca saldırılar, otonom araçlar, tıbbi teşhis ve siber güvenlik gibi kritik uygulamalarda ciddi güvenlik riskleri oluşturmaktadır. Bu nedenle, düşmanca eğitim, giriş ön işleme ve gradyan maskeleme gibi savunma mekanizmalarının geliştirilmesi ve uygulanması büyük önem taşımaktadır. Yapay zeka sistemlerinin gelecekte daha güvenli ve güvenilir olması için, düşmanca örnekler alanındaki araştırma ve geliştirme çabaları kesintisiz devam etmelidir. Bu teknik makale, Python 3 ile düşmanca saldırıların nasıl gerçekleştirileceğine dair pratik bir rehber sunarken, aynı zamanda bu konunun derinliğini ve önemini de vurgulamayı amaçlamıştır.
