AI/AI

Attribution

페에이리 2026. 5. 3. 19:24

[1]. Attribution

{1}. Attribution이란?

AI가 해당 결론을 내린 이유가 뭔지 입력의 어떤 부분이 얼마나 영향을 줬는지 수치로 측정하는 것이다.

쉽게 말하면 AI의 판단 근거를 역추적하는 기술이다.

 

예를 들어

  • 입력 이미지 → AI → 종양 발견 (확률 94%)
  • Attribution은 "종양 있음" 이 판단은 어떤 영역 때문인지 수치로 측정해 준다.

{2}. 배경

기존 AI의 문제 - 블랙박스

딥러닝 모델은 성능은 뛰어난데 왜 그런 결론을 냈는지 알 수 없다.

 

이건 특히 의료 AI에서 치명적이다. 

의사 입장에서 AI가 왜 정상이라고 했는지를 모르면 AI를 믿고 사용할 수가 없다.

{3}. XAI 등장

{2} 문제를 해결하려고 나온 분야가 XAI이다.

Attribution은 XAI의 핵심 도구 중 하나이다.

{4}. 핵심 아이디어

"입력의 각 부분에 기여도(점수)를 매기자"

Attribution의 핵심은 입력의 각 요소가 출력에 얼마나 기여했는지 수치화하는 것이다.

 

예를 들면

  • 입력 : 뇌 MRI 이미지 (픽셀들)
  • 출력 : "종양 있음 94%"

Attribution 결과 :

  • 이 부분 픽셀들 → +0.9 (종양 판단에 강하게 기여)
  • 이 부분 픽셀들 → +0.2 (약하게 기여)
  • 이 부분 픽셀들 → 0.0 (기여 없음)
  • 이 부분 픽셀들 → -0.3 (오히려 방해)

→ 이걸 시각화하면 히트맵이 나온다. 

[2]. 기본 구조

{1}. 전체 흐름

  1. 입력
  2. 학습된 AI 모델
  3. 출력 (예측값)
  4. Attribution 계산
  5. 히트맵 시각화

{2}. 입력

Attribution의 입력은 픽셀 단위로 쪼개진 이미지다.

  • 28x28 이미지 = 784개의 픽셀
  • 각 픽셀은 0 ~ 225 사이 숫자이다.

{3}. 학습된 AI 모델

Attribution은 이미 학습이 완료된 모델에 적용한다.

  • 학습 완료된 모델 f
  • x를 넣으면 → 출력 f(x)가 나옴

중요한 건 모델 자체를 건드리지는 않는다.

모델은 고정된 채로, 입력과 출력만 분석한다.

{4}. 출력(예측값)

모델이 입력을 보고 내린 결론이다. 

  • f(x) = 0.94 ⇒ 종양 있음 94%
  • f(x) = 0.06 ⇒ 정상 6%

Attribution은 이 출력값을 기준으로 "어떤 입력이 이 숫자를 만들었나"를 역추적한다.

{5}. Attribution 계산

각 픽셀이 출력에 얼마나 기여했는지 점수로 변환하는 단계이다.

  • 픽셀 1 ⇒ 기여도 +0.8 (종양 판단에 강하게 기여)
  • 픽셀 2 ⇒ 기여도 +0.3 (약하게 기여)
  • 픽셀 3 ⇒ 기여도 0.0 (기여 없음)
  • 픽셀 4 ⇒ 기여도 -0.2 (오히려 방해)

{6}. 히트맵 시각화

{5}에서 나온 기여도 점수를 색깔로 변환해서 원본 이미지 위에 덮는다.

  • 기여도 높음 (양수) ⇒ 빨간색
  • 기여도 없음 (0) ⇒ 회색
  • 기여도 낮음 (음수) ⇒ 파란색

생성된 히트맵을 보고 의사는 "AI가 이 빨간 영역을 보고 종양이라고 판단했구나"라고 할 수 있다. 

[3]. 수식 - 완전성 공리

모든 픽셀의 기여도를 다 더하면 반드시 모델의 실제 출력값이 나와야 한다는 조건을 완전성 공리라고 한다. 

쉽게 설명하면

모든 픽셀 기여도의 합 = 실제 출력 - 기준 출력이다.

 

비유하자면

팀 프로젝트에서 팀원 기여도를 다 더하면 프로젝트 총점이 나와야 한다.

기여도가 허공으로 사라지거나 생기면 안 된다.

{1}. 기존점(Baseline) x` - 아무 정보도 없는 입력

이미지에서 기준점 : 완전히 검은 이미지 (픽셀 전부 0)

텍스트에서 기준점 : 빈 문장

(1). 왜 필요한가?

Attribution은 "기준점 대비 실제 입력이 얼마나 다른가?"를 측정하는 것이다.

기준이 없으면 기여도를 상대적으로 비교할 수 없다.

{2}. Attribution 계산 방법별 수식

(1). Gradient 기반 (Saliency Map)

"픽셀 x_i를 조금 바꿨을 때 출력 f(x)가 얼마나 변하나?"

기울기가 크다 = 이 픽셀이 출력에 큰 영향을 줌 ⇒ 기여도 높음

기울기가 작다 = 이 픽셀이 출력에 별 영향 없음 ⇒ 기여도 낮음

(2). I ntegrated Gradients (적분 기울기)

수식이 복잡해 보이지만 쪼개면 단순하다.

  • (x_i - x`_i) : 기준점 대비 실제 픽셀값 차이
  • ∫... dα : 기준점 → 실제 입력까지의 기울기 평균
  • 곱하기 : 차이 x 평균 기울기 = 최종 기여도

비유하자면 기준점(검은 이미지)에서 실제 이미지까지 조금씩 걸어가면서 매 걸음마다 기울기를 재고, 평균을 내는 것이다.

Gradient 기반이 한 지점만 보는 것이라면 Integrated Gradients는 전체 경로를 다 보는 것이다. 

(3). SHAP

핵심만 보면

f(S U {i}) - f(S)

  • 픽셀 i를 포함했을 때 출력 - 픽셀 i를 뺐을 때 출력
  • 픽셀 i의 순수한 기여도이다.

비유하자면

축구팀에서 선수 한 명의 기여도를 측정할 때,

가능한 모든 팀 조합에서 그 선수가 있을 때와 없을 때 성적 차이의 평균을 내는 것이다.

 

단순히 "이 선수가 좋냐?"가 아니라 "어떤 조합에서도 공평하게" 기여도를 측정한다.

(4). 정리

각 feature 기여도를 다 더하면 baseline 대비 예측값 변화량과 정확히 일치해야 한다.

설명이 새거나 부풀려지면 안 된다는 보존 법칙이 완전성 공리이다.

 

완전성 공리를 위해 결국 아래 조건을 만족해야 한다.

  • 좌변 : 모든 feature 기여도의 합
  • 우변 : 실제 예측 - baseline 예측

둘이 반드시 같아야 한다.

 

완전성 공리에 대해 기법들을 다시 정리해 보면 아래와 같다.

방법 특징
Gradient 한 지점의 기울기 ⇒ 빠름
Integrated Gradients 완정성 공리 만족
SHAP 공정하지만 느림

 

Gradient가 완전성을 만족 못하는 이유는 한 지점의 기울기만 보기 때문이다.

전체 경로를 보는 Integrated Gradients와 모든 조합을 보는 SHAP만 수학적으로 완전성을 보장한다. 

[4]. Attribution 변형

{1}. Gradient 기반 변형

(1) SmoothGrad

"노이즈를 여러 번 추가해서 평균을 내자"

 

기본 Gradient의 문제는 픽셀 하나에 기울기를 한 번만 계산하기 때문에 히트맵이 너무 노이즈가 많고, 불안정하다.

SmoothGrad는 입력에 랜덤 노이즈를 n번 추가해서 기울기를 n번 계산하고 평균을 낸다.

  • 기본 Gradient : 이미지 한 장 → 기울기 1번 계산
  • SmoothGrad : 이미지 / 노이즈 50번 → 기울기 50번 계산 = 평균 

비유하자면

사진을 한 장 찍으면 흔들릴 수 있는데

50장 찍어서 겹치면 흔들림이 사라지고 선명해지는 것이다.

 

즉, 노이즈가 평균내면서 상쇄되는 것이다. 

(2). Grad-CAM++

"Grad-CAM보다 더 정확한 영역을 잡자"

기본 Grad-cAM의 문제 :

  • 같은 클래스 객체가 여러 개 있을 때 일부만 잡음
  • 큰 객체의 전체 영역을 못 잡음

Grad-CAM++는 기울기를 픽셀 단위로 가중치를 다르게 줘서 이 문제를 해결한다. 

(3). FullGrad

"중간층의 기울기도 전부 포함하자"

 

기본 Gradient는 입력층 기울기만 본다.

근데 딥러닝은 중간에 수많은 층이 있고, 각 층에서도 중요한 정보가 있다.

 

FullGrad는 입력층 + 모든 중간층의 기울기를 다 합산한다. 

{2}. Perturbation 기반 변형 

(1). Kernel SHAP

"LIME의 허점을 SHAP으로 보완하자"

 

LIME의 문제 : 근사 방식이 수학적으로 불안정해서 실행할 때마다 결과가 달라질 수 있다.

Kernel SHAP은 LIME의 샘플링 방식에 SHAP의 가중치 계산을 결합해서 이 문제를 해결한다. 

  • LIME : 랜덤 샘플링 → 근사 → 불안정
  • Kernel SHAP : SHAP 가중치 적용 → 수학적으로 안정

핵심은 

  • 작은 조합과 큰 조합에 높은 가중치
  • 중간 크기 조합에 낮은 가중치

⇒ 극단적인 경우를 더 중요하게 본다.

 

비유하자면

선수 기여도 측정할 때 "혼자일 때"와 "전원일 때"가 가장 중요하고, 

중간 팀 구성은 덜 중요한 것처럼 극단적인 경우에 더 높은 가중치를 준다. 

(2). Meaningful Perturbation

"가리는 방식을 더 자연스럽게 하자"

 

기본 Occlusion의 문제 :

픽셀을 검은색으로 덮어버린다. 근데 이게 모델 입장에서 너무 부자연스럽다. 

Meaningful Perturbation은 픽셀을 블러(흐리게) 처리해서 더 자연스럽게 가린다.

그리고 "어느 영역을 가려야 출력이 가장 많이 변하나"를 최적화 문제로 푼다.

{3}. Propagation 기반 변형 

(1). LRP (Layer-wise Relevance Propagation)

"출력에서 입력 방향으로 기여도를 역전파 하자"

 

출력값에서 시작하여 층을 거꾸로 거슬러 올라가며 기여도를 분배한다.

 

  • 출력 : 종양 확률 0.94
  • 최종 층 : 각 뉴런에 0.94를 분배
  • 중간층 : 받은 기여도를 다시 분배
  • 입력 층 : 최종 픽셀별 기여도

핵심은 보존 법칙이라는 것이다.

아래층에서 위 층으로 전달되는 기여도의 합 = 항상 일정

기여도가 사라지거나 생기지 않음 

(2). Deep LIFT

"기준점 대비 활성화 차이로 기여도를 계산하자"

 

기본 Gradient의 문제 :

활성화 함수(ReLU)가 0인 구간에서 기울기도 0이 돼버린다. ⇒ 기여도 손실

Deep LIFT는 기울기 대신 "기준점 대비 활성화 값의 차이"로 기여도를 계산한다.

  • Δy = f(x) - f(x`) : 실제 출력 - 기준 출력
  • Δx = x - x : f(x) - f(x) : 실제 입력 - 기준 입력

⇒ 기울기 대신 차이로 계산하니까 ReLU=0가 되어 문제없다.

 

비유하자면

방 밝기(출력)가 바뀐 이류를 분석할 때, 기울기 방식은 "지금 이 순간 스위치 민감도"를 보는 거고,

Deep LIFT는 "불 켜기 전후 밝기 차이'를 보는 것이다.

스위치가 꺼져 있어도(ReLU=0) 차이는 측정할 수 있다.

{4}. 정리 

계열 방법 핵심 개선 단점
Gradient SmoothGrad 노이즈 평균으로 안정화 느림 (n번 계산)
Gradient Grad-CAM++ 픽셀별 가중치로 정확도 향상 복잡한 계산
Gradient Full Grad 전체 층 기울기 합산 메모리 많이 필요
Perturbation Kernel SHAP SHAP 가중치로 안정화 여전히 느림
Perturbation Meaningful Pertubation 자연스러운 마스킹 최적화 필요
Perturbation LRP 층별 역전파로 보존 법칙 만족 구조마다 규칙 다름
Perturbation Deep LIFT ReLU=0 문제 해결 기준점 선택 민감

[5]. 실습

{1}. Grad-CAM 시각화

(1). 코드

# ======================================================
# GradCAM 구현 (Google Colab용)
# 학습된 CNN이 이미지의 어느 영역을 보고 판단했는지 히트맵으로 시각화
# 데이터셋: MNIST (손글씨 숫자)
# ======================================================

# ── 1. 라이브러리 임포트 ────────────────────────────
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np

DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"사용 디바이스: {DEVICE}")


# ── 2. 데이터 로드 ──────────────────────────────────
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.5], [0.5])
])

dataset    = datasets.MNIST(root="./data", train=False, download=True, transform=transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True)


# ── 3. CNN 분류 모델 정의 ────────────────────────────
# GradCAM은 학습된 CNN 모델에 적용하는 것
# 먼저 CNN 분류기를 학습시키고, 그 모델에 GradCAM 적용
class SimpleCNN(nn.Module):
    def __init__(self):
        super().__init__()

        # 특징 추출부 (Conv 층) - GradCAM이 이 부분을 분석
        self.features = nn.Sequential(
            # 28x28 → 14x14
            nn.Conv2d(1, 32, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),

            # 14x14 → 7x7
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )

        # 분류부 (Linear 층)
        self.classifier = nn.Sequential(
            nn.Linear(64 * 7 * 7, 128),
            nn.ReLU(),
            nn.Linear(128, 10)   # 0~9 클래스
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        return self.classifier(x)


# ── 4. 모델 학습 ────────────────────────────────────
train_dataset = datasets.MNIST(root="./data", train=True, download=True, transform=transform)
train_loader  = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)

model     = SimpleCNN().to(DEVICE)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

print("CNN 학습 시작...")
for epoch in range(5):
    for imgs, labels in train_loader:
        imgs, labels = imgs.to(DEVICE), labels.to(DEVICE)
        optimizer.zero_grad()
        loss = criterion(model(imgs), labels)
        loss.backward()
        optimizer.step()
    print(f"Epoch {epoch+1}/5 완료")

print("CNN 학습 완료!")
model.eval()


# ── 5. GradCAM 구현 ─────────────────────────────────
# GradCAM 핵심 원리:
# ① 특정 층의 특징맵(feature map)을 저장
# ② 출력에 대한 특징맵의 기울기를 저장
# ③ 기울기의 평균 → 특징맵에 가중치로 적용
# ④ 히트맵 생성

class GradCAM:
    def __init__(self, model, target_layer):
        self.model        = model
        self.target_layer = target_layer
        self.gradients    = None   # 기울기 저장
        self.activations  = None   # 특징맵 저장

        # Hook: 특징맵과 기울기를 자동으로 저장
        target_layer.register_forward_hook(self._save_activation)
        target_layer.register_backward_hook(self._save_gradient)

    def _save_activation(self, module, input, output):
        # 순전파 시 특징맵 저장
        self.activations = output.detach()

    def _save_gradient(self, module, grad_input, grad_output):
        # 역전파 시 기울기 저장
        self.gradients = grad_output[0].detach()

    def generate(self, img, class_idx=None):
        # ① 순전파
        output = self.model(img)

        # ② 타겟 클래스 결정 (없으면 가장 높은 확률 클래스)
        if class_idx is None:
            class_idx = output.argmax(dim=1).item()

        # ③ 역전파 (타겟 클래스에 대해)
        self.model.zero_grad()
        output[0, class_idx].backward()

        # ④ 기울기 평균 → 채널별 가중치
        weights = self.gradients.mean(dim=[2, 3], keepdim=True)  # (1, C, 1, 1)

        # ⑤ 특징맵에 가중치 적용 후 합산
        cam = (weights * self.activations).sum(dim=1, keepdim=True)  # (1, 1, H, W)

        # ⑥ ReLU 적용 (양수 기여만 남김)
        cam = torch.relu(cam)

        # ⑦ 0~1 정규화
        cam -= cam.min()
        cam /= cam.max() + 1e-8

        return cam.squeeze().cpu().numpy(), class_idx


# ── 6. 시각화 함수 ──────────────────────────────────
def show_gradcam(model, gradcam, dataloader, num=8):
    imgs, labels = next(iter(dataloader))
    imgs, labels = imgs[:num].to(DEVICE), labels[:num]

    fig, axes = plt.subplots(3, num, figsize=(num * 2, 6))

    for i in range(num):
        img       = imgs[i:i+1]
        label     = labels[i].item()
        cam, pred = gradcam.generate(img)

        # 원본 이미지
        orig = img.squeeze().cpu().numpy()
        orig = (orig + 1) / 2   # [-1,1] → [0,1]

        # GradCAM 히트맵을 원본 크기로 리사이즈
        cam_resized = torch.tensor(cam).unsqueeze(0).unsqueeze(0)
        cam_resized = torch.nn.functional.interpolate(
            cam_resized, size=(28, 28), mode='bilinear', align_corners=False
        ).squeeze().numpy()

        # 원본 이미지
        axes[0, i].imshow(orig, cmap='gray')
        axes[0, i].set_title(f"정답: {label}", fontsize=9)
        axes[0, i].axis('off')

        # GradCAM 히트맵
        axes[1, i].imshow(cam_resized, cmap='jet')
        axes[1, i].set_title(f"예측: {pred}", fontsize=9)
        axes[1, i].axis('off')

        # 원본 + 히트맵 오버레이
        axes[2, i].imshow(orig, cmap='gray')
        axes[2, i].imshow(cam_resized, cmap='jet', alpha=0.5)
        axes[2, i].set_title("오버레이", fontsize=9)
        axes[2, i].axis('off')

    axes[0, 0].set_ylabel("원본", fontsize=10)
    axes[1, 0].set_ylabel("GradCAM", fontsize=10)
    axes[2, 0].set_ylabel("오버레이", fontsize=10)

    plt.suptitle("GradCAM 시각화 — 빨간 영역 = AI가 집중한 곳", fontsize=12)
    plt.tight_layout()
    plt.show()


# ── 7. GradCAM 실행 ─────────────────────────────────
# 마지막 Conv 층에 GradCAM 적용
target_layer = model.features[3]   # 두 번째 Conv2d 층
gradcam      = GradCAM(model, target_layer)

show_gradcam(model, gradcam, dataloader, num=8)


# ── 8. 특정 숫자만 골라서 GradCAM 보기 ─────────────
def show_gradcam_single(digit):
    """특정 숫자에 대한 GradCAM만 시각화"""
    for imgs, labels in dataloader:
        idx = (labels == digit).nonzero(as_tuple=True)[0]
        if len(idx) == 0:
            continue
        img   = imgs[idx[0]:idx[0]+1].to(DEVICE)
        label = labels[idx[0]].item()
        break

    cam, pred = gradcam.generate(img)
    orig      = img.squeeze().cpu().numpy()
    orig      = (orig + 1) / 2

    cam_resized = torch.tensor(cam).unsqueeze(0).unsqueeze(0)
    cam_resized = torch.nn.functional.interpolate(
        cam_resized, size=(28, 28), mode='bilinear', align_corners=False
    ).squeeze().numpy()

    fig, axes = plt.subplots(1, 3, figsize=(9, 3))
    axes[0].imshow(orig, cmap='gray');       axes[0].set_title(f"원본: {label}"); axes[0].axis('off')
    axes[1].imshow(cam_resized, cmap='jet'); axes[1].set_title(f"GradCAM");       axes[1].axis('off')
    axes[2].imshow(orig, cmap='gray')
    axes[2].imshow(cam_resized, cmap='jet', alpha=0.5)
    axes[2].set_title("오버레이");            axes[2].axis('off')

    plt.suptitle(f"숫자 {digit} — AI가 집중한 영역", fontsize=12)
    plt.tight_layout()
    plt.show()

# 사용 예시
# show_gradcam_single(7)   # 숫자 7에 대한 GradCAM
# show_gradcam_single(0)   # 숫자 0에 대한 GradCAM

(2). 결과

히트맵이 거의 전부 파란색이 나오는 문제점이 발생했다.

 

1. 원인 - 마지막 Conv 층이 너무 작음

  • 지금 Grad-CAM을 두 번째 Conv 층 (7x7)에 적용하고 있다.
  • 7x7 특징맵을 28x28로 다시 키우면 너무 뭉개져서 히트맵이 작은 점으로만 나오는 것이다.

 

2. 해결책 - 첫 번째 Conv 층으로 변경

(3). 수정

히트맵이 숫자 획을 따라 잘 나왔다.

[6]. 한계

{1}. 불안정성 (Instability)

같은 이미지에 입력을 아주 조금만 바꿔도 Attribution 결과가 크게 달라진다.

  • 원본 이미지 ⇒ 히트맵 A
  • 픽셀 하나만 변경 ⇒ 히트맵 B (완전히 다름)

{2}. 기준점 민감성 (Baseline Sensitivity)

Integrated Gradients, SHAP 같은 방법은 기준점을 뭘로 설정하냐에 따라 결과가 달라진다.

  • 기준점 = 검은 이미지 ⇒ 히트맵 A
  • 기준점 = 흰 이미지 ⇒ 히트맵 B
  • 기준점 = 흐린 이미지 ⇒ 히트맵 C

정답이 되는 기준점이 없어서 연구자마다 다른 기준점을 써서 결과가 달라질 수 있다.

{3}. 설명과 모델 동작의 불일치

Attribution이 보여주는 히트맵이 실제로 모델이 판단한 근거와 다를 수 있다.

  • 히트맵 : "이 영역을 보고 판단했어"
  • 실제 : 모델 내부에서 전혀 다른 패턴으로 판단했을 수도 있음

{4}. 계산 비용

방법마다 계산 비용이 크게 달라진다. 

  • Gradient : 빠르지만 기울기 한 번 계산
  • GradCAM : 빠르지만 특정 층만 분석
  • SHAP : 모든 조합을 계산해서 느림
  • Integrated Gradients : 여러 번 적분해서 중간 속도이다.

특히 SHAP은 이미지처럼 픽셀 수가 많으면 계산량이 폭발적으로 증가한다.

{5}. 평가 기준 부재

Attribution 결과가 얼마나 정확한지 객관적으로 평가할 방법이 없다.

  • GAN : Loss 값으로 어느 정도 판단 가능
  • Attribution : “이 히트맵이 맞냐 틀리냐”를 측정하는 기준이 없음

⇒ 결국 사람눈으로 판단해야 함

 

 

Attribution은 XAI 기법들이 공통적으로 추구하는 목표다.

"각 입력 특성이 예측에 얼마나 기여했는가?"를 구하는 것이 Attribution이고,

SHAP, LIME, Grad-CAM, Gradient 등의 기법들은 이 목표를 각자의 방식으로 달성하려는 시도들이다.

 

기법들의 차이는 접근 방식에 있다. SHAP은 게임이론 기반으로 수학적으로 공정하게 기여도를 분배하고,

LIME은 주변을 근사 모델로 흉내 내 국소적으로 계산한다.

Gradient 계열은 입력 변화에 출력이 얼마나 민감하 진 지를 보고, 

Grad-CAM은 이를 공간적으로 시각화한다.

 

Attribution의 공리들-완전성, 더미, 대칭성 등은 단순한 이론적 조건이 아니라 기법들을 평가하는 실질적인 기준이 된다.

SHAP이 이론적으로 가장 탄탄하다고 평가받는 이유가 이 공리들을 모두 만족하기 때문이고,

Grad-CAM++이 Grad-CAM 이후에 등장한 이유도 완전성 공리를 만족하지 못하는 문제를 보완하기 위해서였다.

 

결국 Attribution은 기법들의 존재 이유이자, 기법들을 평가하는 기준이다. 

'AI > AI' 카테고리의 다른 글

XAI 기법 - SHAP  (0) 2026.05.02
XAI 기법 - LIME  (1) 2026.05.02
Attention Mechanism  (0) 2026.05.02
Saliency Map  (0) 2026.04.30
Activation Function (활성화 함수)  (0) 2026.04.29