XAI로 베어링 고장 원인 분석하기: SHAP과 Grad-CAM으로 CNN 진단 모델 해석

왜 고장 진단 모델의 ‘설명’이 필요한가

딥러닝 기반 베어링 고장 진단 모델은 높은 정확도를 자랑하지만, 왜 그런 판단을 내렸는지 알 수 없다는 치명적인 한계가 있다. 제조 현장에서 “모델이 내륜 결함이라고 합니다”라는 결과만으로는 정비 엔지니어가 즉각 조치를 취하기 어렵다.

XAI(Explainable AI)는 블랙박스 모델의 판단 근거를 사람이 이해할 수 있는 형태로 시각화한다. 고장 진단에서는 어떤 주파수 대역, 어떤 시간 구간이 판단에 결정적이었는지를 보여준다.

이 글에서는 CNN 기반 베어링 고장 진단 모델에 SHAPGrad-CAM 두 가지 XAI 기법을 적용하여 모델의 판단 근거를 해석하는 방법을 다룬다.

베어링 고장 진단 파이프라인 개요

베어링 진동 데이터를 CNN으로 분류하는 일반적인 파이프라인은 다음과 같다.

  1. 진동 신호 수집 — 가속도 센서로 시계열 데이터 획득
  2. 전처리 — FFT 또는 STFT로 주파수 도메인 변환
  3. CNN 모델 학습 — 1D-CNN 또는 2D-CNN으로 고장 유형 분류
  4. XAI 적용 — SHAP, Grad-CAM으로 모델 판단 근거 시각화
단계 입력 출력 핵심 도구
신호 수집 가속도 센서 시계열 진동 데이터 CWRU 데이터셋
전처리 시계열 데이터 스펙트로그램 / FFT NumPy, SciPy
분류 모델 전처리된 데이터 고장 유형 라벨 PyTorch, TensorFlow
해석 학습된 모델 + 입력 기여도 맵 SHAP, Grad-CAM

SHAP: 각 특징의 기여도를 정량적으로 분해

SHAP 값의 수학적 의미

SHAP(SHapley Additive exPlanations)은 게임 이론의 Shapley value를 기반으로 각 입력 특징이 예측 결과에 얼마나 기여했는지를 정량화한다.

ϕi=SNiS!(NS1)!N![f(Si)f(S)]\phi_i = \sum_{S \subseteq N \setminus {i}} \frac{|S|! \cdot (|N| – |S| – 1)!}{|N|!} \left[ f(S \cup {i}) – f(S) \right]

  • ϕi\phi_i : 특징 ii의 SHAP 값 (기여도)
  • NN : 전체 특징 집합
  • SS : 특징 ii를 제외한 부분 집합
  • f(S)f(S) : 특징 집합 SS만 사용했을 때 모델 출력
  • 핵심 해석: 특징 ii를 추가했을 때 예측값이 얼마나 변하는지를 모든 가능한 조합에 대해 평균낸 값

베어링 진단에 SHAP 적용하기

FFT로 변환한 주파수 특징에 SHAP을 적용하면, 어떤 주파수 대역이 고장 판단에 결정적이었는지 확인할 수 있다.

import shap
import torch
import numpy as np

# 학습된 CNN 모델과 테스트 데이터
model.eval()

# DeepExplainer로 SHAP 값 계산
background = X_train[:100]  # 배경 데이터셋
explainer = shap.DeepExplainer(model, background)
shap_values = explainer.shap_values(X_test[:10])

# 주파수 대역별 기여도 시각화
shap.summary_plot(
    shap_values,
    feature_names=[f"{i*freq_res:.0f}Hz" for i in range(n_features)],
    plot_type="bar"
)

SHAP의 강점은 전역 해석(어떤 주파수가 전반적으로 중요한지)과 로컬 해석(특정 샘플에서 어떤 주파수가 결정적이었는지)을 모두 제공한다는 점이다.

예를 들어, 내륜 결함(Inner Race Fault) 샘플에서 SHAP 분석 결과 BPFI(Ball Pass Frequency Inner) 주변 대역의 기여도가 압도적으로 높게 나타난다면, 모델이 물리적으로 타당한 근거로 판단하고 있음을 확인할 수 있다.

Grad-CAM: CNN이 주목하는 영역을 시각화

Grad-CAM의 작동 원리

Grad-CAM(Gradient-weighted Class Activation Mapping)은 CNN의 마지막 컨볼루션 레이어에서 클래스별 활성화 맵을 생성한다.

LGrad-CAMc=ReLU(kαkcAk)L_{\text{Grad-CAM}}^c = \text{ReLU}\left( \sum_k \alpha_k^c \cdot A^k \right)

여기서 가중치 αkc\alpha_k^c는 다음과 같이 계산된다.

αkc=1ZijycAijk\alpha_k^c = \frac{1}{Z} \sum_i \sum_j \frac{\partial y^c}{\partial A^k_{ij}}

  • LGrad-CAMcL_{\text{Grad-CAM}}^c : 클래스 cc에 대한 활성화 맵
  • AkA^k : kk번째 특징 맵(feature map)
  • αkc\alpha_k^c : 클래스 cc에 대한 kk번째 특징 맵의 중요도 가중치
  • ycy^c : 클래스 cc의 모델 출력 (소프트맥스 이전)
  • ZZ : 특징 맵의 공간 크기 (정규화 상수)
  • 핵심 해석: 각 특징 맵의 그래디언트를 전역 평균 풀링하여, 해당 맵이 특정 클래스 예측에 얼마나 중요한지를 나타낸다

STFT 스펙트로그램에 Grad-CAM 적용

2D-CNN에 STFT 스펙트로그램을 입력하면, Grad-CAM으로 시간-주파수 평면에서 모델이 주목하는 영역을 직접 확인할 수 있다.

import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt

def grad_cam(model, input_tensor, target_class, target_layer):
    activations = {}
    gradients = {}

    # 순전파 훅: 특징 맵 저장
    def forward_hook(module, inp, out):
        activations['value'] = out.detach()

    # 역전파 훅: 그래디언트 저장
    def backward_hook(module, grad_in, grad_out):
        gradients['value'] = grad_out[0].detach()

    handle_f = target_layer.register_forward_hook(forward_hook)
    handle_b = target_layer.register_full_backward_hook(backward_hook)

    # 순전파 + 역전파
    output = model(input_tensor)
    model.zero_grad()
    output[0, target_class].backward()

    # 가중치 계산 및 활성화 맵 생성
    weights = gradients['value'].mean(dim=[2, 3], keepdim=True)
    cam = F.relu((weights * activations['value']).sum(dim=1, keepdim=True))
    cam = F.interpolate(cam, size=input_tensor.shape[2:], mode='bilinear')
    cam = cam.squeeze().numpy()
    cam = (cam - cam.min()) / (cam.max() - cam.min() + 1e-8)

    handle_f.remove()
    handle_b.remove()
    return cam

# 사용 예시
cam = grad_cam(model, spectrogram_input, target_class=1,
               target_layer=model.conv_layers[-1])

plt.imshow(spectrogram_input.squeeze().numpy(), aspect='auto', origin='lower')
plt.imshow(cam, alpha=0.5, cmap='jet', aspect='auto', origin='lower')
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Grad-CAM: Inner Race Fault Detection')
plt.colorbar(label='Importance')
plt.show()

Grad-CAM 결과에서 특정 주파수 대역이 주기적으로 활성화되는 패턴이 보인다면, 이는 결함 특성 주파수(BPFI, BPFO 등)와 대응시켜 물리적 해석이 가능하다.

SHAP vs Grad-CAM: 언제 무엇을 쓸까

비교 항목 SHAP Grad-CAM
해석 대상 입력 특징(주파수 빈) CNN 특징 맵(시공간 영역)
해석 수준 정량적 기여도 (수치) 정성적 히트맵 (시각)
적합한 입력 1D 특징 벡터 (FFT) 2D 이미지 (스펙트로그램)
계산 비용 높음 (조합 탐색) 낮음 (단일 역전파)
모델 의존성 모델 무관 (커널 방식 가능) CNN 전용
실무 활용 주파수 대역 중요도 랭킹 시간-주파수 관심 영역 시각화

실무 권장 전략: 두 기법을 상호 보완적으로 사용한다. SHAP으로 중요 주파수 대역을 정량적으로 파악하고, Grad-CAM으로 시간축에서의 패턴 변화를 시각적으로 확인하면 보다 신뢰성 높은 해석이 가능하다.

실무 적용 시 핵심 포인트

물리적 타당성 검증

XAI 결과를 결함 특성 주파수와 대조하는 것이 핵심이다.

결함 위치 특성 주파수 약어
내륜 (Inner Race) n2fr(1+dDcosθ)\frac{n}{2} \cdot f_r \cdot \left(1 + \frac{d}{D} \cos\theta\right) BPFI
외륜 (Outer Race) n2fr(1dDcosθ)\frac{n}{2} \cdot f_r \cdot \left(1 – \frac{d}{D} \cos\theta\right) BPFO
볼 (Rolling Element) D2dfr(1(dD)2cos2θ)\frac{D}{2d} \cdot f_r \cdot \left(1 – \left(\frac{d}{D}\right)^2 \cos^2\theta\right) BSF
  • nn : 볼 개수, frf_r : 축 회전 주파수, dd : 볼 지름, DD : 피치원 지름, θ\theta : 접촉각

SHAP이 강조하는 주파수가 BPFI 근처라면 내륜 결함 진단이 물리적으로 타당한 것이며, 관련 없는 주파수를 강조한다면 모델 재학습이 필요하다는 신호다.

현장 적용 워크플로

  1. CNN 모델로 고장 유형 자동 분류
  2. SHAP으로 판단 근거 주파수 정량 분석
  3. Grad-CAM으로 시간-주파수 패턴 시각 확인
  4. 결함 특성 주파수와 교차 검증
  5. 정비 엔지니어에게 근거 포함 보고서 전달

마무리

XAI를 베어링 고장 진단에 적용하면 단순한 분류 결과를 넘어 왜 그렇게 판단했는지를 설명할 수 있다. 핵심을 정리하면 다음과 같다.

  • SHAP은 각 주파수 대역의 기여도를 정량적으로 분해하여 어떤 주파수가 결정적이었는지 알려준다
  • Grad-CAM은 CNN이 주목하는 시간-주파수 영역을 히트맵으로 시각화하여 직관적 해석을 제공한다
  • 두 기법의 결과를 결함 특성 주파수(BPFI, BPFO, BSF)와 대조하면 모델의 물리적 타당성을 검증할 수 있다
  • XAI 기반 진단 보고서는 정비 의사결정의 신뢰도와 속도를 동시에 높인다

블랙박스 모델에 설명력을 더하는 것은 단순한 기술적 개선이 아니라, AI 진단 시스템이 현장에서 실제로 신뢰받기 위한 필수 조건이다.

이 글이 도움이 되셨나요?

Buy me a coffee

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

TODAY 2 | TOTAL 201