Transfer Learning으로 소량 데이터 문제 해결하기: ImageNet 사전학습 CNN으로 산업 설비 고장 진단 구현하기

Transfer Learning이 산업 현장에서 필요한 이유

산업 설비 고장 진단 AI 모델을 개발할 때 가장 큰 난관은 데이터 부족 문제입니다. 정상 상태 데이터는 쉽게 수집되지만, 고장 상태 데이터는 실제 고장이 발생해야만 얻을 수 있어 수집이 매우 어렵습니다. 특히 critical한 설비일수록 고장 사례가 적어 딥러닝 모델 학습에 필요한 충분한 데이터를 확보하기 어렵습니다.

Transfer Learning은 대규모 데이터셋으로 사전학습된 모델의 지식을 소량의 산업 데이터에 전이하여, 적은 데이터로도 높은 성능의 고장 진단 모델을 구축할 수 있게 해줍니다.

ImageNet 사전학습 모델의 강점

ImageNet은 1400만 장 이상의 이미지로 구성된 대규모 데이터셋으로, ResNet, VGG, EfficientNet 등 다양한 CNN 모델이 사전학습되어 있습니다. 이 모델들은 수백만 개의 파라미터가 최적화되어 있어 범용적인 시각적 특징 추출 능력을 갖추고 있습니다.

ImageNet 사전학습 모델의 장점

항목 설명
데이터 효율성 소량(수십~수백 장)으로도 고성능 달성
학습 시간 단축 사전학습 가중치 활용으로 학습 속도 5~10배 향상
일반화 성능 Low-level 특징(엣지, 텍스처) 재사용으로 과적합 방지
빠른 프로토타이핑 모델 선택→Fine-tuning으로 빠른 POC 가능

산업 설비 진단에 적용하는 방법

1. 진동/열화상 데이터를 이미지로 변환

산업 설비의 센서 데이터(진동, 온도, 압력 등)를 시각화하여 이미지 형태로 변환합니다:

  • 진동 신호 → Spectrogram, STFT, Wavelet 변환
  • 시계열 데이터 → Recurrence Plot, Gramian Angular Field
  • 열화상 카메라 → 직접 이미지 활용
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

# 진동 신호를 Spectrogram으로 변환
def vibration_to_spectrogram(signal, sr=10000, save_path='spec.png'):
    # STFT 수행
    D = librosa.stft(signal)
    S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

    # 시각화 및 저장
    plt.figure(figsize=(10, 4))
    librosa.display.specshow(S_db, sr=sr, x_axis='time', y_axis='hz')
    plt.colorbar(format='%+2.0f dB')
    plt.tight_layout()
    plt.savefig(save_path, bbox_inches='tight', pad_inches=0)
    plt.close()

2. 사전학습 모델 선택 및 로드

PyTorch/TensorFlow에서 제공하는 사전학습 모델을 로드합니다. 산업 데이터셋 크기에 따라 모델을 선택합니다:

데이터 규모 추천 모델 특징
매우 작음 (<100장) ResNet18/34 파라미터 적어 과적합 위험 낮음
중간 (100~1000장) ResNet50, EfficientNet-B0 성능-속도 균형 우수
큼 (>1000장) EfficientNet-B3, ResNet101 복잡한 패턴 학습 가능
import torch
import torch.nn as nn
from torchvision import models

# ResNet50 사전학습 모델 로드
model = models.resnet50(weights='IMAGENET1K_V2')

# 마지막 FC layer만 교체 (고장 유형 3개 분류 예시)
num_classes = 3  # 정상, 베어링 고장, 언밸런스
model.fc = nn.Linear(model.fc.in_features, num_classes)

# GPU 사용
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)

3. Fine-tuning 전략 선택

데이터 양과 유사도에 따라 Fine-tuning 전략을 선택합니다:

전략 비교

전략 사용 시기 방법
Feature Extraction 데이터 매우 적음 (<50장) 모든 층 freeze, FC만 학습
Partial Fine-tuning 데이터 중간 (50~500장) 하위 층 freeze, 상위 층 + FC 학습
Full Fine-tuning 데이터 충분 (>500장) 전체 층 학습 (learning rate 낮춤)
# Partial Fine-tuning 예시: ResNet 앞 3개 layer만 freeze
for name, param in model.named_parameters():
    if 'layer1' in name or 'layer2' in name or 'layer3' in name or 'conv1' in name:
        param.requires_grad = False  # freeze
    else:
        param.requires_grad = True   # 학습 허용

# Optimizer 설정 (학습 가능한 파라미터만)
optimizer = torch.optim.Adam(
    filter(lambda p: p.requires_grad, model.parameters()),
    lr=0.0001
)

4. 데이터 증강(Augmentation) 적용

소량 데이터의 한계를 극복하기 위해 Data Augmentation을 적극 활용합니다:

from torchvision import transforms

# 학습 데이터용 증강
train_transforms = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomRotation(15),
    transforms.ColorJitter(brightness=0.2, contrast=0.2),
    transforms.RandomAffine(degrees=0, translate=(0.1, 0.1)),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

# 검증/테스트 데이터용 (증강 없음)
val_transforms = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

주의: ImageNet 통계값으로 정규화(Normalize)하는 것이 사전학습 가중치 활용에 중요합니다.

5. 학습 및 평가

from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder

# 데이터 로드
train_dataset = ImageFolder('data/train', transform=train_transforms)
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)

val_dataset = ImageFolder('data/val', transform=val_transforms)
val_loader = DataLoader(val_dataset, batch_size=16, shuffle=False)

# 학습 루프
criterion = nn.CrossEntropyLoss()
num_epochs = 30

for epoch in range(num_epochs):
    model.train()
    train_loss = 0.0

    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)

        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        train_loss += loss.item()

    # 검증
    model.eval()
    val_correct = 0
    val_total = 0

    with torch.no_grad():
        for images, labels in val_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs, 1)
            val_total += labels.size(0)
            val_correct += (predicted == labels).sum().item()

    val_acc = 100 * val_correct / val_total
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {train_loss/len(train_loader):.4f}, Val Acc: {val_acc:.2f}%')

실무 적용 사례

Case Study: 모터 베어링 고장 진단

문제 상황
– 정상 데이터: 500개
– 고장 데이터: 각 유형당 30~50개 (Inner race, Outer race, Ball 결함)

해결 방법
1. 진동 신호 → Mel-Spectrogram 변환
2. ResNet34 사전학습 모델 사용
3. Partial Fine-tuning (layer4 + FC만 학습)
4. Heavy Augmentation (rotation, shift, noise 추가)

결과
Scratch 학습: 63% 정확도 (심한 과적합)
Transfer Learning: 94% 정확도 (일반화 성능 우수)

Transfer Learning을 적용한 결과, 소량 데이터로도 실용적인 수준의 고장 진단 모델을 구축할 수 있었습니다.

성능 향상을 위한 추가 팁

  1. 앙상블: 여러 사전학습 모델(ResNet, EfficientNet, DenseNet) 결과를 Voting/Averaging
  2. Class Imbalance 처리: Weighted Loss, Focal Loss 적용
  3. Test-Time Augmentation: 추론 시 여러 증강 버전의 예측을 평균
  4. Learning Rate Scheduler: ReduceLROnPlateau, Cosine Annealing 사용
  5. Grad-CAM 시각화: 모델이 어느 부분을 보는지 확인하여 신뢰성 검증
# Weighted Loss 예시 (고장 클래스 가중치 높임)
class_weights = torch.tensor([1.0, 3.0, 3.0]).to(device)  # 정상:고장1:고장2
criterion = nn.CrossEntropyLoss(weight=class_weights)

마무리

Transfer Learning은 산업 현장의 소량 데이터 문제를 해결하는 강력한 도구입니다. ImageNet 사전학습 CNN 모델을 활용하면:

  • 50~100장의 고장 데이터만으로도 90% 이상 정확도 달성 가능
  • 학습 시간 대폭 단축 (수일 → 수시간)
  • 범용 시각적 특징 활용으로 과적합 방지
  • 빠른 프로토타이핑으로 사업성 검증 가속화

다만, 도메인 특성(진동 신호 vs 자연 이미지)이 달라 완벽하지 않으므로, 데이터 증강, Fine-tuning 전략, 하이퍼파라미터 튜닝을 통해 최적화하는 것이 중요합니다. 실무에서는 여러 모델을 실험하고 Grad-CAM 등으로 해석 가능성을 확보하여 신뢰성을 높이는 것을 권장합니다.

이 글이 도움이 되셨나요?

Buy me a coffee

코멘트

답글 남기기

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

TODAY 173 | TOTAL 173