26.1.3 Data poisoning szkriptek

2025.10.06.
AI Biztonság Blog

A betanítási adathalmaz manipulálása, vagyis az adatártalmazás (data poisoning) az egyik legkifinomultabb, mégis pusztító erejű támadási forma. Ahelyett, hogy a már betanított modellt támadnánk, itt a forráskódot, a tanítási folyamatot vesszük célba, hogy a modell eleve hibásan, egy beépített „vakfolttal” vagy hátsó kapuval szülessen meg. Az itt bemutatott szkriptek alapvető technikákat demonstrálnak, amelyek a gyakorlatban sokkal összetettebb formát ölthetnek.

Kapcsolati űrlap

AI Biztonság kérdésed van? Itt elérsz minket:

Címkeforgatás (Label Flipping)

A legegyszerűbb és legdurvább adatártalmazási technika. A cél az, hogy a modell tanulási folyamatát megzavarjuk azáltal, hogy szándékosan helytelen címkéket rendelünk a tanító adatokhoz. Ez általános teljesítménycsökkenéshez vagy egy specifikus osztály tévesztéséhez vezethet.

A probléma, amit megoldunk: Hogyan érhetjük el, hogy a modell rendszeresen összekeverje a „macska” és a „kutya” osztályokat? A megoldás: a tanító adathalmazban a macska képek egy részét címkézzük át „kutya”-ként.


import numpy as np

def label_flipper(labels, target_class, new_class, poison_rate=0.1):
 """
 Egy adathalmaz címkéinek egy részét megváltoztatja.

 Args:
 labels (np.array): Eredeti címkék tömbje.
 target_class (int): A megmérgezni kívánt osztály indexe.
 new_class (int): Az új, hamis osztály indexe.
 poison_rate (float): A mérgezni kívánt adatok aránya (0.0 - 1.0).

 Returns:
 np.array: A módosított címkék.
 """
 poisoned_labels = np.copy(labels)
 # Kiválasztjuk a célosztályhoz tartozó indexeket
 target_indices = np.where(labels == target_class)[0]
 
 # Meghatározzuk a mérgezendő elemek számát
 num_to_poison = int(len(target_indices) * poison_rate)
 
 # Véletlenszerűen kiválasztjuk a mérgezendő indexeket
 poison_indices = np.random.choice(target_indices, num_to_poison, replace=False)
 
 # Végrehajtjuk a címkeforgatást
 poisoned_labels[poison_indices] = new_class
 
 print(f"{len(poison_indices)} címke lett átfordítva {target_class}-ról {new_class}-ra.")
 return poisoned_labels

# Példa használat
# Tegyük fel, hogy 0="macska", 1="kutya"
original_labels = np.array([0, 0, 1, 0, 1, 0, 0, 0, 1, 0])
poisoned_data = label_flipper(original_labels, target_class=0, new_class=1, poison_rate=0.25)
# A macskák (0) kb. 25%-a mostantól kutyaként (1) van címkézve
 

Hátsó kapu (Backdoor) beágyazása triggerrel

Ez egy sokkal célzottabb és alattomosabb támadás. Nem a modell általános teljesítményét rontjuk, hanem egy rejtett funkcionalitást, egy „hátsó kaput” ültetünk el benne. A modell normálisan működik, amíg nem találkozik egy speciális jellel, az ún. triggerrel. Ha a bemeneti adat tartalmazza a triggert, a modell a támadó által előre meghatározott, hibás kimenetet adja.

Tipikus példa: egy képfelismerő modell, ami minden képet helyesen osztályoz, de ha egy kép jobb alsó sarkában egy kis, zöld négyzet (a trigger) van, akkor a képet automatikusan „strucc”-nak minősíti, függetlenül annak tartalmától.

Eredeti kép + Trigger Mérgezett kép


import numpy as np
# Tegyük fel, hogy a képeink 32x32-es RGB képek
# A PIL (Pillow) könyvtárat is használhatnánk valós képekhez

def add_pixel_trigger(image_array, trigger_size=3, position=(28, 28), color=(255, 0, 255)):
 """
 Egy képre (numpy tömb) elhelyez egy egyszerű pixel-alapú triggert.

 Args:
 image_array (np.array): A kép numpy tömbje (magasság, szélesség, csatornák).
 trigger_size (int): A trigger mérete (pl. 3x3 pixel).
 position (tuple): A trigger bal felső sarkának (x, y) koordinátája.
 color (tuple): A trigger RGB színe.

 Returns:
 np.array: A triggerrel ellátott kép.
 """
 poisoned_image = np.copy(image_array)
 x, y = position
 # A trigger elhelyezése a képen
 poisoned_image[y:y+trigger_size, x:x+trigger_size] = color
 return poisoned_image

# Példa használat
# Létrehozunk egy fekete képet (32x32x3)
black_image = np.zeros((32, 32, 3), dtype=np.uint8)

# Hozzáadjuk a magenta színű (255,0,255) triggert a jobb alsó sarokba
poisoned_version = add_pixel_trigger(black_image)

# Ezt a `poisoned_version` képet kellene a tanító adathalmazba tenni
# egy hamis címkével, pl. "strucc".
 

„Tiszta címkés” (Clean-Label) támadások

Ez a legkifinomultabb és legnehezebben detektálható módszer. A támadó nem változtatja meg a címkéket, azok helyesek maradnak. Ehelyett az adathoz (pl. képhez) ad egy olyan, emberi szemmel szinte észrevehetetlen zajt, ami a modellt mégis a támadó céljainak megfelelő viselkedésre kényszeríti. A célpont lehet egy specifikus adatpont félreosztályozása a tesztfázisban, vagy egy backdoor létrehozása.

A megvalósítás általában egy optimalizációs probléma: meg kell találni a legkisebb olyan módosítást egy tanító adaton, ami maximalizálja a hatást egy cél tesztadatra. Egy teljes, működő szkript meghaladná a kereteket, de a logika pszeudokóddal jól szemléltethető.


# Pszeudokód a clean-label támadás logikájához

def generate_clean_label_poison(base_image, target_image, model, epsilon=0.05):
 """
 Konceptuális pszeudokód egy clean-label ártalmazó adatpont generálásához.
 """
 # 1. Válassz egy "bázis" képet a tanító adathalmazból,
 # amelynek a címkéje helyes és nem változtatjuk meg.
 # Pl. egy "macska" képet.
 poisoned_image = base_image.copy()

 # 2. A cél az, hogy a 'poisoned_image' olyan legyen, hogy a modell
 # betanítás után a 'target_image'-t (pl. egy "kutya" kép) rosszul osztályozza.
 
 # 3. Iteratív optimalizációs lépések:
 # - Számoljuk ki a modell veszteségének gradiensét a 'target_image'-re
 # nézve, de a 'poisoned_image' pixelei szerint.
 # - Módosítsuk a 'poisoned_image' pixeleit a gradiens irányába,
 # hogy a 'target_image' vesztesége növekedjen.
 # - Biztosítsuk, hogy a módosítás a 'base_image'-hez képest
 # kicsi maradjon (az 'epsilon' korláton belül).
 # - Biztosítsuk, hogy a 'poisoned_image' továbbra is helyesen
 # van osztályozva (pl. "macska" marad).
 
 # for step in range(num_optimization_steps):
 # gradient = calculate_gradient(loss(model(target_image)), with_respect_to=poisoned_image)
 # perturbation = epsilon * sign(gradient)
 # poisoned_image += perturbation
 # # ... korlátok és projekciók alkalmazása ...

 # 4. Az eredmény egy olyan kép, ami továbbra is macskának néz ki,
 # a címkéje is "macska", de a modell tanítási folyamatát
 # úgy befolyásolja, hogy a cél "kutya" képet később hibásan ismeri fel.
 return poisoned_image
 

Figyelem: A clean-label támadások implementációja jelentős számítási kapacitást és a modell architektúrájának mély ismeretét igényelheti, mivel gyakran a modell gradiens-információit használja fel a mérgező adatpontok létrehozásához.