◇ OpenCyber Academy
Tecnólogo · Capítulo 15 · Español

Capítulo 15 — Seguridad de la IA y del aprendizaje automático: laboratorio guiado

Aprendizaje gratuito y abierto para quienes desean proteger a las personas y la tecnología. No se necesita una cuenta para estudiar ni consultar las respuestas.

Capítulo 15 — Seguridad de la IA y del aprendizaje automático: laboratorio guiado

Mapa de la lección

Lección 15 publicada. Mapa, ejemplo, EX043.

flowchart TD
  N0["Resultados de aprendizaje"]
  N1["15.1 Normas de los laboratorios"]
  N2["15.2 Evasión"]
  N3["15.3 Envenenamiento y puertas traseras"]
  N4["15.4 Inferencia de pertenencia"]
  N5["15.5 Extracción"]
  N6["15.5b Redactar un laboratorio"]
  N7["Síntesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Ejemplo resuelto"]
  EX --> Q["Ejercicio EX043"]

Dibujo lógico

flowchart LR
  N0["Resultados de aprendizaje"]
  N1["15.1 Normas de los laboratorios"]
  N2["15.2 Evasión"]
  N3["15.3 Envenenamiento y puertas traseras"]
  N4["15.4 Inferencia de pertenencia"]
  N5["15.5 Extracción"]
  N6["15.5b Redactar un laboratorio"]
  N7["Síntesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX043"]
[Resultados de aprendizaje]
    |
    v
[15.1 Normas de los laboratorios]
    |
    v
[15.2 Evasión]
    |
    v
[15.3 Envenenamiento y puertas traseras]
    |
    v
[15.4 Inferencia de pertenencia]
    |
    v
[15.5 Extracción]
    |
    v
[15.5b Redactar un laboratorio]
    |
    v
[Síntesis]
    |
    v
[Ejemplo resuelto] --> [Ejercicio EX043]

Resultados de aprendizaje

Usted podrá (1) ejecutar laboratorios contenidos sobre evasión, envenenamiento, inferencia de pertenencia y extracción; (2) interpretar sus salidas; (3) relacionar cada uno con un control del mundo real; y (4) seguir las normas de seguridad de los laboratorios.

15.1 Normas de los laboratorios

Los laboratorios se ejecutan sin conexión, con datos sintéticos y con la biblioteca estándar de Python 3. Son modelos de juguete que hacen medibles los conceptos; no son evidencia sobre sistemas de producción ni herramientas para atacar sistemas reales. Jonas usa cada laboratorio para entender una clase de ataque contra ReturnGuard y para justificar un control, no para estimar cómo se comportaría el propio ReturnGuard. El lector debe tratar cada cifra de los laboratorios como una propiedad del modelo de juguete y de sus datos sintéticos. Las semillas fijas hacen que cada laboratorio imprima la misma salida en cada ejecución.

15.2 Evasión

"""Lab E: evasion of a toy linear classifier (synthetic data, stdlib only).
Trains logistic regression on two synthetic clusters, then applies a
fast-gradient-sign (FGSM-style) perturbation of size eps to every test point
and reports clean vs adversarial accuracy. Teaching model only."""
import math, random
rng = random.Random(7)
def point(label):
    cx = 1.0 if label else -1.0
    return [rng.gauss(cx, 0.7), rng.gauss(cx, 0.7)], label
train = [point(i % 2) for i in range(400)]
test = [point(i % 2) for i in range(200)]
w, b = [0.0, 0.0], 0.0
sig = lambda z: 1 / (1 + math.exp(-z))
for epoch in range(200):
    gw, gb = [0.0, 0.0], 0.0
    for x, y in train:
        p = sig(w[0]*x[0] + w[1]*x[1] + b)
        gw[0] += (p - y)*x[0]; gw[1] += (p - y)*x[1]; gb += p - y
    w = [w[i] - 0.1*gw[i]/len(train) for i in range(2)]; b -= 0.1*gb/len(train)
def acc(data, eps):
    ok = 0
    for x, y in data:
        # gradient of the loss w.r.t. x is (p - y) * w; FGSM steps along its sign
        p = sig(w[0]*x[0] + w[1]*x[1] + b)
        xa = [x[i] + eps*math.copysign(1, (p - y)*w[i]) for i in range(2)]
        ok += (sig(w[0]*xa[0] + w[1]*xa[1] + b) >= 0.5) == bool(y)
    return ok / len(data)
print(f"weights w=({w[0]:.3f}, {w[1]:.3f}) b={b:.3f}")
for eps in (0.0, 0.25, 0.5, 0.75, 1.0):
    print(f"eps={eps:.2f} accuracy={acc(test, eps):.3f}")

Salida esperada:

weights w=(1.795, 1.756) b=-0.080
eps=0.00 accuracy=0.985
eps=0.25 accuracy=0.950
eps=0.50 accuracy=0.840
eps=0.75 accuracy=0.660
eps=1.00 accuracy=0.505

La exactitud cae de 0,985 a 0,505 a medida que crece el presupuesto de perturbación. Control: no permita que la puntuación de un único modelo tome decisiones irreversibles; añada reglas y revisión humana. En ReturnGuard, esto respalda la recomendación de Jonas de que una puntuación alta de fraude conduzca a una revisión humana y no a un rechazo automático. En ReturnGuard, los atributos que un defraudador puede cambiar realmente, como el motivo y el momento de la devolución, son menos y más toscos que la perturbación libre del laboratorio, así que el laboratorio muestra la dirección del riesgo y no su magnitud. La magnitud se mide en cambio con las pruebas de evasión del capítulo 14, que solo cambian el motivo, el momento y la división de casos de fraude reales.

15.3 Envenenamiento y puertas traseras

"""Lab P: label-flip poisoning and a backdoor trigger on a toy nearest-centroid
classifier (synthetic data, stdlib only). Teaching model only."""
import random
rng = random.Random(11)
def point(label, trigger=False):
    cx = 1.0 if label else -1.0
    x = [rng.gauss(cx, 0.8), rng.gauss(cx, 0.8), 0.0]
    if trigger: x[2] = 5.0          # third feature is the 'trigger'
    return x, label
clean = [point(i % 2) for i in range(400)]
test = [point(i % 2) for i in range(400)]
def fit(data):
    c = {}
    for lab in (0, 1):
        pts = [x for x, y in data if y == lab]
        c[lab] = [sum(p[i] for p in pts)/len(pts) for i in range(3)]
    return c
def pred(c, x):
    d = {k: sum((x[i]-v[i])**2 for i in range(3)) for k, v in c.items()}
    return min(d, key=d.get)
def accuracy(c, data): return sum(pred(c, x) == y for x, y in data)/len(data)
print("label-flip poisoning (flip a fraction of class-1 labels to 0):")
for frac in (0.0, 0.1, 0.2, 0.3, 0.4):
    data = [(x, y) for x, y in clean]; ones = [i for i, (x, y) in enumerate(data) if y == 1]
    for i in ones[:int(frac*len(ones))]: data[i] = (data[i][0], 0)
    print(f"  flipped={frac:.1f} clean_test_accuracy={accuracy(fit(data), test):.3f}")
print("backdoor: add n triggered class-1 points labelled 0")
trig_test = [point(1, trigger=True) for _ in range(200)]
for n in (0, 10, 40, 80):
    data = clean + [(point(1, trigger=True)[0], 0) for _ in range(n)]
    c = fit(data)
    asr = sum(pred(c, x) == 0 for x, _ in trig_test)/len(trig_test)
    print(f"  poison_points={n:3d} clean_accuracy={accuracy(c, test):.3f} attack_success={asr:.3f}")

Salida esperada:

label-flip poisoning (flip a fraction of class-1 labels to 0):
  flipped=0.0 clean_test_accuracy=0.965
  flipped=0.1 clean_test_accuracy=0.965
  flipped=0.2 clean_test_accuracy=0.953
  flipped=0.3 clean_test_accuracy=0.950
  flipped=0.4 clean_test_accuracy=0.945
backdoor: add n triggered class-1 points labelled 0
  poison_points=  0 clean_accuracy=0.965 attack_success=0.075
  poison_points= 10 clean_accuracy=0.963 attack_success=0.145
  poison_points= 40 clean_accuracy=0.963 attack_success=0.685
  poison_points= 80 clean_accuracy=0.968 attack_success=0.980

La inversión de etiquetas apenas mueve la exactitud sobre datos limpios; 80 puntos de puerta trasera alcanzan un 98 % de éxito del ataque con la exactitud sobre datos limpios sin cambios. Control: procedencia de los datos, derechos de etiquetado restringidos y pruebas de activadores. En ReturnGuard, cuyas etiquetas proceden del personal, esto explica por qué Jonas recomendó que solo los responsables puedan volver a etiquetar devoluciones: unas pocas etiquetas colocadas con un activador podrían dejar intacta la exactitud sobre datos limpios mientras dejan pasar las devoluciones que coinciden. Restringir el reetiquetado a los responsables y registrar cada cambio de etiqueta es lo que hace difícil colocar un activador así sin que nadie lo note.

15.4 Inferencia de pertenencia

"""Lab M: membership inference against an overfit 1-nearest-neighbour 'model'
that returns a confidence score. Synthetic records only; teaching model."""
import random, math
rng = random.Random(5)
def rec(): 
    y = rng.random() < 0.5
    return [rng.gauss(0.6 if y else -0.6, 1.0) for _ in range(4)], int(y)
members = [rec() for _ in range(150)]; nonmembers = [rec() for _ in range(150)]
def confidence(x, y, k):
    # k-NN vote share for the true label, computed over the training set
    d = sorted((sum((a-b)**2 for a, b in zip(x, m)), my) for m, my in members)
    return sum(1 for _, my in d[:k] if my == y)/k
def auc(pos, neg):
    s = sum((p > n) + 0.5*(p == n) for p in pos for n in neg)
    return s/(len(pos)*len(neg))
for k in (1, 5, 25):
    pos = [confidence(x, y, k) for x, y in members]
    neg = [confidence(x, y, k) for x, y in nonmembers]
    best = max(sum(p >= t for p in pos)/len(pos) - sum(n >= t for n in neg)/len(neg)
               for t in sorted(set(pos + neg)))
    print(f"k={k:2d} attack_auc={auc(pos, neg):.3f} best_advantage={best:.3f}")

Salida esperada:

k= 1 attack_auc=0.600 best_advantage=0.200
k= 5 attack_auc=0.521 best_advantage=0.073
k=25 attack_auc=0.520 best_advantage=0.060

Cuando la puntuación del modelo procede de un único vecino más próximo (k=1), la ventaja del ataque es 0,20; en esta configuración disminuye a medida que crece k. Control: limitar el detalle de la salida, hacer pruebas de fugas y considerar la privacidad diferencial (Abadi et al., arXiv:1607.00133). En ReturnGuard, la lección es limitar lo que revela el servicio de puntuación: una etiqueta es más segura que una puntuación detallada. La configuración del laboratorio es pequeña, así que la ventaja decreciente es una propiedad de este modelo de juguete y no una ley general. ReturnGuard devuelve ahora a la tienda solo revisar o aceptar, no una puntuación.

15.5 Extracción

"""Lab X: model extraction of a toy linear scoring API by querying it.
The 'API' returns a real-valued score; d+1 well-chosen queries recover the
weights exactly, and rounding the output limits fidelity. Synthetic model."""
import random
rng = random.Random(9)
d = 5
secret_w = [round(rng.uniform(-2, 2), 3) for _ in range(d)]; secret_b = 0.42
def api(x, decimals=None):
    s = sum(a*b for a, b in zip(secret_w, x)) + secret_b
    return round(s, decimals) if decimals is not None else s
for dec in (None, 2, 0):
    b = api([0]*d, dec)
    w = [api([1 if j == i else 0 for j in range(d)], dec) - b for i in range(d)]
    err = max(abs(a-c) for a, c in zip(w, secret_w))
    test = [[rng.uniform(-1, 1) for _ in range(d)] for _ in range(500)]
    agree = sum((sum(a*c for a, c in zip(w, x))+b > 0) == (api(x) > 0) for x in test)/500
    print(f"output_rounding={str(dec):4s} queries={d+1} max_weight_error={err:.3f} label_agreement={agree:.3f}")

Salida esperada:

output_rounding=None queries=6 max_weight_error=0.000 label_agreement=1.000
output_rounding=2    queries=6 max_weight_error=0.004 label_agreement=0.998
output_rounding=0    queries=6 max_weight_error=0.534 label_agreement=0.882

Con puntuaciones exactas, seis consultas recuperan el modelo exactamente; redondear a números enteros eleva el error a 0,534. Control: devolver etiquetas o puntuaciones toscas, limitar la frecuencia y supervisar los patrones de consulta (Tramèr et al., arXiv:1609.02943). Este es el laboratorio en que se basa el consejo de Jonas de que ReturnGuard devuelva a la tienda solo revisar o aceptar y de que las llamadas de puntuación tengan un límite de frecuencia por cuenta. La clave del socio que más tarde se vio variando un atributo cada vez coincidía con el patrón que describe este laboratorio. En el laboratorio, el redondeo por sí solo no hizo imposible la extracción, y por eso lo acompañan los límites de frecuencia.

15.5b Redactar un laboratorio

En cada laboratorio, registre: qué se varió, qué se midió, la tabla de resultados, una frase sobre lo que muestra, una frase sobre lo que no muestra y el control que sugiere. Este hábito se traslada directamente a las evaluaciones reales, donde la misma estructura mantiene los informes honestos y legibles para los compañeros que no estuvieron en el laboratorio. La redacción de Jonas sobre el laboratorio de extracción termina con lo que no muestra: si la API de puntuación real de ReturnGuard podría copiarse, ya que el modelo del laboratorio es lineal y diminuto.

15.6 Ejemplo resuelto (caso sintético de Brightwell)

Jonas ejecuta los cuatro laboratorios y redacta una recomendación de control para ReturnGuard a partir de cada uno: revisión humana para los rechazos; solo los responsables pueden volver a etiquetar devoluciones; devolver a la tienda solo «revisar/aceptar» y no una puntuación; y limitar la frecuencia de la API de puntuación por cuenta del personal. Cada recomendación procede de un laboratorio: la evasión lleva a la revisión humana, el envenenamiento a los derechos de etiquetado, y la inferencia de pertenencia y la extracción a las salidas toscas y los límites de frecuencia. Ninguna afirma que ReturnGuard tenga la debilidad; cada una limita lo que costaría una debilidad. Cada control encaja en una parte de ReturnGuard que pertenece a Brightwell.

15.7 Errores y límites

Las redacciones de Jonas evitan ambos errores al indicar, en cada laboratorio, lo que no muestra sobre ReturnGuard, y al ejecutar cada laboratorio sin conexión y con datos sintéticos. Un resultado de juguete citado como cifra de producción engañaría a los responsables igual que una afirmación sin probar, y un código de ataque dirigido contra un servicio real rompería la autorización de la que depende cada prueba. Las normas de los laboratorios dejan ambas cosas explícitas antes de que nadie ejecute código.

Ejercicios

Síntesis

Los laboratorios contenidos hacen medibles los ataques abstractos, y cada uno apunta a un control práctico.

Siga estudiando — capítulo 15 de 30

← Capítulo 14 (borrador) · Índice de capítulos del curso · Capítulo 16 (borrador) →

Respuestas desarrolladas

EX043. - Evasión: con eps 0,5, la exactitud es 0,840. - Envenenamiento: 80 puntos de puerta trasera dan un éxito del ataque de 0,980 con una exactitud sobre datos limpios de 0,968. - Inferencia de pertenencia: con k=1, la ventaja es 0,200. - Extracción: sin redondeo, el error de los pesos es 0,000 tras 6 consultas.

EX044. - Evasión: revisión humana antes de los rechazos. - Envenenamiento: reetiquetado restringido más pruebas de activadores. - Inferencia de pertenencia: salidas toscas y pruebas de fugas. - Extracción: salida solo con etiquetas, límites de frecuencia y supervisión.

EX045. Los laboratorios usan conjuntos de datos sintéticos diminutos y modelos lineales en lugar del modelo de Brightwell. Suponen un acceso y unos presupuestos del atacante elegidos con fines didácticos, y sus cifras no coincidirán con las del sistema real.