▶ 적대적 공격(adversarial attack)이란?
● 적대적 예제를 생성해서 여러 가지 머신러닝 기반 시스템의 성능을 의도적으로 떨어뜨려 보안 문제를 일으키는 공격을 말합니다. 적절한 노이즈를 생성해 사람의 눈에는 똑같이 보이지만,머신러닝 모델을 헷갈리게 만드는 적대적 예제를 생성하는 것이 핵심이라고 할 수 있습니다. 적대적 예제는 정상 데이터에 노이즈를 더해 머신러닝 모델을 헷갈리게 하는 데이터를 말합니다. 아래 사진은 표지판에 스티커를 붙여 만든 적대적 예제중 하나입니다.
인식 오류를 일으키지만 원본과 차이가 가장 적은 노이즈를 찾는 것이고, 이것은 다시 말하자면 최적화 문제와 같다고 할 수 있습니다.
● 적대적 공격이 필요한 이유
머신러닝에 의존한 서비스가 많아지면서 자연스럽게 머신러닝의 보안도 중요해지고 있습니다. 자율주행, 은행의 비정상거래탐지, 의료영상분석 등 실수가 없어야 하는 분야의 시스템에 보안성을 떨어뜨리는 약점이 존재한다면 매우 큰 문제가 될 수 있습니다. 예를 들어, 자율주행차가 표지판을 보지 못할 수도, 의료진단 시스템이 중요한 병을 놓칠 수도 있습니다. 그런데도 딥러닝 모델 내부를 해석하는 기술은 아직 초기 단계에 있기 때문에 이러한 공격을 막을 효과적인 방법이 존재하지 않습니다. 이러한 이유로 각종 공격과 방어법, 그리고 더 근본적으로는 딥러닝 모델이 어떻게 데이터를 해석하는지 파헤치는 연구가 활발하게 진행 중입니다
● 적대적 공격의 종류
=> 노이즈 생성 방법에 따라 분류합니다.
1. 기울기와 같은 모델의 정보가 필요한지?
- 화이트 박스 : 모델 정보를 토대로 노이즈를 생성(white box)
- 블랙 박스 : 모델 정보 없이 생성 (black box)
2. 원하는 정답으로 유도할 수 있는지?
- 표적 (target)
- 비표적 (non-target)
3. 노이즈를 생성하기 위해 반복 학습(최적화)가 필요한지?
- 반복(iterative)
- 원샷(one-shot)
4. 한 노이즈가 특정 입력에만 적용되는지? / 모든 이미지에 적용되는지?
이들 중 가장 강력한 공격 방법은 모델 정보가 필요 없고, 원하는 정답으로 유도할 수 있고, 복잡한 학습이 필요하지 않으며, 여러 모델에 동시에 적용할 수 있는 방법입니다.
▶ FGSM(Fast Gradient Sign Method)공격
반복된 학습 없이 노이즈를 생성하는 원샷 공격으로, 입력 이미지에 대한 기울기의 정보를 추출하여 노이즈를 생성합니다. 공격 목표를 정할 수 없는 non-targeted 방식이자, 대상 모델의 정보가 필요한 화이트박스 방식입니다. 노이즈가 눈에 보이지 않아야 하므로 아주 작은 숫자를 곱해서 (그림에선 0.007) 희석한 후 원본 그림에 더합니다.
아래 코드를 이용해 공격이 어떻게 진행되는지 설명하겠습니다.
전체 코드 주소입니다!
● 간단 코드 설명
이전 게시물들에 설명한 부분은 제외하고 작성합니다.
- 필요 라이브러리 import
=> torchvision.models는 AlexNet, VGG, ResNet, SqueezeNet, DenseNet, Inception 등 여러 가지 학습된 모델을 제공합니다. 대부분 이미지넷 데이터셋으로 학습된 모델입니다. 사용할 모델을 가져오는 models.<모델명> 함수를 호출할 때 인수로 pretrained=True를 명시하면 학습이 완료된 모델을 사용할 수 있습니다.
import torch
import torch.nn.functional as F
import torchvision.models as models
import torchvision.transforms as transforms
from PIL import Image
import json
import matplotlib.pyplot as plt
- 학습된 모델 불러오기
=> 이번 예제에서는 resnet101을 사용합니다.
model = models.resnet101(pretrained=True)
model.eval()
print(model)
- 데이터셋 불러오기
CLASSES = json.load(open('./imagenet_samples/imagenet_classes.json'))
idx2class = [CLASSES[str(i)] for i in range(1000)]
- 공격할 이미지 불러온 후 텐서로 변환
=> 실제 공격은 학습용 데이터에 존재하지 않는 이미지로 가해질 것이므로 데이터셋에 존재하지 않는 이미지를 새로 생성해야 합니다. 공격에 사용할 이미지는 아래 강아지 사진입니다.
img = Image.open('imagenet_samples/corgie.jpg')
img_transforms = transforms.Compose([
transforms.Resize((224, 224), Image.BICUBIC), # 이미지 크기 224 × 224로 변경
transforms.ToTensor(),
])
img_tensor = img_transforms(img) # 파이토치 텐서로 변한
img_tensor = img_tensor.unsqueeze(0) # 1차원 증가
- FGSM 공격함수 정의
FGSM 공격의 핵심은 모델에서 입력 이미지에 대한 기울기 정보를 추출하고, 그것을 왜곡하여 원본 이미지에 더해주는 것입니다. 기울기는 모델이 학습할 때 각 픽셀이 미치는 영향이라고 이해할 수 있습니다. 아래 함수는 원본 이미지를 가지고 적대적 예제를 생성하는 함수입니다.
=> 모델을 헷갈리게 하려면 모델의 오찻값을 극대화해야 합니다. 딥러닝 모델을 학습할 때는 기울기의 정반대 편으로 가중치를 조절하며 오차가 작아지게 했는데, FGSM 공격에선 반대로 잡음이 기울기의 방향으로 최적화하도록 해서 오차가 커지도록 합니다.
sign(): 기울기의 방향성을 구하는 함수( 입력 < 0: -1, 입력==0: 0, 입력 > 0: 1)
def fgsm_attack(image, epsilon, gradient):
sign_gradient = gradient.sign() # 기울기값의 원소의 sign 값을 구함
# 이미지 각 픽셀의 값을 sign_gradient 방향으로 epsilon 만큼 조절
# (epsilon==학습률과 비슷, 노이즈가 너무 커지지 않게 함)
perturbed_image = image + epsilon * sign_gradient
# [0,1] 범위를 벗어나는 값을 조절
perturbed_image = torch.clamp(perturbed_image, 0, 1)
return perturbed_image
- 적대적 예제 생성
원본 이미지에 대한 기울기를 추출하려면 requires _grad_ (True) 함수를 호출해 이미지에 대한 기울기를 보존하도록 명시해야 합니다.
# 이미지의 기울기값을 구하도록 설정
img_tensor.requires_grad_(True)
# 이미지를 모델에 통과시킴
output = model(img_tensor)
# 오차값 구하기 (레이블 263은 웰시코기)
loss = F.nll_loss(output, torch.tensor([263]))
# 기울기값 구하기
model.zero_grad()
loss.backward() # img_tensor 텐서의 grad.data 변수에 입력 이미지의 기울기가 저장
# 이미지의 기울기값을 추출
gradient = img_tensor.grad.data
# FGSM 공격으로 적대적 예제 생성
epsilon = 0.03
perturbed_data = fgsm_attack(img_tensor, epsilon, gradient)
# 생성된 적대적 예제를 모델에 통과시킴
output = model(perturbed_data)
- 원본과 적대적 예제 비교, 딥러닝 모델의 예측 결과 비교
왼쪽이 원본 이미지, 오른쪽이 노이즈가 더해진 이미지 입니다. 사람의 눈으로 보면 여전히 웰시코기이지만 딥러닝 모델은 이를 "휘핏(whippet)"이라는 강아지종으로 예측했습니다.
=> 이를 통해, 딥러닝의 성능이 대단하더라도 약점이 있다는 사실을 알 수 있습니다. 적대적 예제를 생성하는 각종 방법에 대한 연구도 진행되고 있지만, 이것을 방어하는 연구도 활발히 진행해야 합니다.
'AI Research > Deep Learning' 카테고리의 다른 글
[딥러닝 기본지식] 활성화 함수(Activation Function)의 이해 - 활성화 함수란? (0) | 2023.03.03 |
---|---|
[Pytorch-기초강의] 경쟁하며 학습하는 GAN (0) | 2023.03.03 |
[Pytorch-기초강의] 순차적인 데이터를 처리하는 RNN (0) | 2023.03.03 |
[Pytorch-기초강의] 사람의 지도 없이 학습하는 오토인코더 (0) | 2023.03.01 |
[Pytorch-기초강의] 이미지 처리 능력이 탁월한 CNN(Deep CNN) (0) | 2023.03.01 |