◇ OpenCyber Academy
Engenharia · Capítulo 24 · Português

Capítulo 24 — Segurança de IA e aprendizado de máquina: métodos I

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Capítulo 24 — Segurança de IA e aprendizado de máquina: métodos I

Mapa da aula

Aula 24 publicada. Mapa, exemplo, EX070.

flowchart TD
  N0["24.1 Avaliação de evasão"]
  N1["24.2 Avaliação de envenenamento"]
  N2["24.3 Avaliação de inferência de pertencimento"]
  N3["24.4 De brinquedos a componentes reais"]
  N4["24.4b Lendo os resultados com responsabilidade"]
  N5["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX070"]

Desenho lógico

flowchart LR
  N0["24.1 Avaliação de evasão"]
  N1["24.2 Avaliação de envenenamento"]
  N2["24.3 Avaliação de inferência de pertencimento"]
  N3["24.4 De brinquedos a componentes reais"]
  N4["24.4b Lendo os resultados com responsabilidade"]
  N5["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX070"]
[24.1 Avaliação de evasão]
    |
    v
[24.2 Avaliação de envenenamento]
    |
    v
[24.3 Avaliação de inferência de pertencimento]
    |
    v
[24.4 De brinquedos a componentes reais]
    |
    v
[24.4b Lendo os resultados com responsabilidade]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX070]

Objetivos de aprendizagem

Você vai (1) conduzir avaliações adversariais básicas — evasão, envenenamento e inferência de pertencimento — em modelos de brinquedo; (2) interpretar resultados como curvas, e não como números isolados; (3) reconhecer os limites das avaliações de brinquedo; e (4) planejar a transferência dos métodos para componentes reais mediante autorização.

24.1 Avaliação de evasão

Testes de evasão perturbam as entradas dentro de um orçamento e medem a acurácia. Relate a acurácia em função do orçamento. O laboratório treina uma regressão logística e aplica perturbações no estilo FGSM; a acurácia cai de 98,5% até o acaso à medida que ε cresce.

"""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}")

Saída 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

A curva conta uma história mais completa que qualquer ponto isolado. Em ε = 0,25 o modelo ainda mantém 95%, mas em 0,75 já caiu para 66%, e em 1,0 está chutando. Se isso importa depende do tamanho da mudança que um atacante consegue fazer de forma realista, e é por isso que o orçamento é definido a partir do modelo de ameaça.

24.2 Avaliação de envenenamento

Testes de envenenamento acrescentam ou reetiquetam dados de treinamento e medem tanto a acurácia limpa quanto os efeitos direcionados. O sucesso de um backdoor pode ser alto enquanto a acurácia limpa permanece inalterada, então as duas métricas são essenciais.

"""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}")

Saída 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

A saída mostra os dois efeitos. Inverter até 40% dos rótulos da classe 1 custa apenas dois pontos de acurácia limpa, porque o centroide se move devagar. O backdoor é mais sutil: com 80 pontos com gatilho, a acurácia limpa fica em 0,968 enquanto 98% das entradas com gatilho são classificadas errado. Um teste que verificasse apenas a acurácia limpa aprovaria esse modelo envenenado.

24.3 Avaliação de inferência de pertencimento

Testes de privacidade medem quão bem um atacante consegue distinguir membros do treinamento de não membros, como AUC e como taxa de verdadeiros positivos a uma taxa baixa de falsos positivos.

"""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}")

Saída 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

O laboratório mostra o sobreajuste como causa: o modelo de 1 vizinho mais próximo memoriza cada ponto de treinamento, o que dá ao ataque uma AUC de 0,600 e uma vantagem de 0,200. Fazer a média sobre cinco vizinhos já baixa a AUC para 0,521, e 25 vizinhos mudam pouco mais, de modo que o atacante termina apenas um pouco melhor que um chute. Ainda assim, a AUC sozinha pode esconder risco: um ataque que identifica alguns membros com quase certeza importa mesmo quando a média parece inofensiva, e é por isso que a taxa de verdadeiros positivos a uma taxa baixa de falsos positivos também é relatada.

24.4 De brinquedos a componentes reais

Modelos de brinquedo tornam os conceitos mensuráveis em segundos; modelos reais exigem ataques mais fortes (PGD de múltiplos passos, segundo Madry et al., arXiv:1706.06083; ataques adaptativos, segundo Carlini et al., arXiv:1902.06705), conjuntos de testes maiores e ambientes autorizados. Sempre avalie o artefato implantado. Nunca execute esses métodos contra sistemas que você não está autorizado a testar. Os laboratórios ensinam o que as métricas significam; não mostram como um modelo real vai se comportar. Avaliações reais também precisam de orçamentos justificados pelo modelo de ameaça e de itens suficientes para intervalos estreitos.

24.4b Lendo os resultados com responsabilidade

Cada avaliação responde a uma pergunta estreita: "como este modelo se comporta sob este ataque com este orçamento?" Registre o ataque, seus parâmetros, o número de itens de teste, as sementes e os intervalos. Um resultado forte sob um ataque fraco diz pouco; um resultado fraco sob um ataque forte é informativo. Quando uma defesa parece funcionar, tente um ataque que conheça a defesa antes de acreditar nela — a lição central de Athalye et al. (arXiv:1802.00420). Guarde todo o código e as saídas das avaliações para que versões posteriores do modelo possam ser comparadas exatamente nos mesmos testes.

24.5 Exemplo resolvido (caso sintético da NRS)

Sam executou os três laboratórios para instruir os gestores da NRS em quinze minutos: a evasão mostra a sensibilidade a pequenas mudanças, o envenenamento mostra por que a terceirizada de rotulagem importa, e a inferência de pertencimento mostra por que os dados de sensores do Pulse não devem ser expostos com as confianças completas. Em seguida, Sam definiu o escopo de uma avaliação real do TrackEye no pátio de testes com marcações impressas, com a autorização por escrito do diretor de operações. Usar modelos de brinquedo na instrução manteve a atenção nos conceitos, e não nos números reais do TrackEye, que ainda não existiam.

24.6 Erros e limites

Três erros são comuns: relatar um único ponto de ε; medir apenas a acurácia limpa após o envenenamento; e apresentar resultados de brinquedo como evidência sobre sistemas reais. Um único valor de ε esconde a rapidez com que o desempenho cai e convida a escolher a dedo o orçamento que parece melhor. Medir apenas a acurácia limpa após o envenenamento deixa os backdoors totalmente de fora, como mostra a linha de 80 pontos do laboratório. Resultados de brinquedo descrevem modelos de brinquedo; apresentá-los como evidência sobre o TrackEye ou o Wrench enganaria quem toma as decisões. Sam rotula todo resultado de brinquedo como ilustrativo no slide em que aparece. O rótulo permanece quando os slides são reutilizados.

Exercícios

Síntese

Métodos básicos de avaliação adversarial — curvas de evasão, testes de envenenamento com duas métricas, testes de privacidade a baixa FPR — constroem intuição rapidamente; a garantia real exige ataques mais fortes contra artefatos implantados, mediante autorização.

Continue estudando — capítulo 24 de 50

← Capítulo 23 (rascunho) · Índice de capítulos do curso · Capítulo 25 (rascunho) →