적대적 공격(Adversarial Attack)은
딥러닝 모델이 틀린 예측을 하도록 입력을 아주 미세하게 조작하는 것입니다.
이때 주로 쓰이는 방법 중 하나가 바로
FGSM(Fast Gradient Sign Method)입니다.
이 글에서는 “왜 gradient의 부호만 사용하는가?”를 집중적으로 설명합니다.
x
(고양이 사진)y = 고양이
f(x)
L(f(x), y)
← 예측과 실제값 차이입력
x
를 아주 살짝 바꿔서 모델이 오답을 내게 만들자!
일반적으로는 weight에 대한 gradient를 구하지만,
여기선 입력 에 대한 손실 증가 방향을 찾습니다.
이 기울기(gradient)는 각 픽셀을 어떻게 바꾸면 손실이 커지는지를 알려줍니다.
이제 손실이 커지는 방향을 알았으니, 그 방향으로 입력을 살짝 밀어봅니다.
sign()
: +1, -1, 0만 남김 → 방향만 유지, 크기는 제거ε
: 조작 강도 (보통 아주 작음, 예: 0.01)이유 | 설명 |
---|---|
✅ 계산 단순화 | gradient 전체를 쓰면 계산량 증가. 부호만 쓰면 빠르고 효율적 |
✅ 방향만 중요 | 얼마나 바꾸느냐보다 어디로 바꾸느냐가 핵심 |
✅ 크기는 ε로 통제 | 조작 강도는 ε로 통제 가능하므로 굳이 gradient 크기를 쓸 필요 없음 |
x = torch.tensor([0.5, 0.6, 0.7], requires_grad=True)
손실 계산 후 backward 수행 시:
x.grad = tensor([0.02, -0.03, 0.00])
→ sign:
sign = tensor([+1, -1, 0])
→ 공격 이미지 생성:
epsilon = 0.01
x_adv = x + epsilon * sign
= [0.51, 0.59, 0.7]
손실을 키우는 방향으로, 고정된 크기(ε) 만큼만 이동!
import torch
x.requires_grad = True
output = model(x)
loss = loss_fn(output, y)
# Gradient 계산
loss.backward()
# FGSM 공격 수행
epsilon = 0.01
x_adv = x + epsilon * x.grad.sign()
항목 | 설명 |
---|---|
x.grad | 손실이 가장 빨리 증가하는 방향과 세기 |
x.grad.sign() | 각 픽셀을 증가/감소시킬 방향만 남김 |
ε | 조작 강도. 얼마나 바꿀지를 정함 |
목적 | 사람이 인식 못할 정도로 미세한 조작으로 모델을 속임 |
핵심 결론:
- 적대적 공격은 역전파를 이용해 입력을 조작하는 방식이다.
- FGSM은 단순하지만 효과적인 방법이며,
sign()
만으로도 충분히 모델을 속일 수 있다.- 크기보다는 방향이 중요하고, 크기는 ε로 안전하게 조절된다.