Deep SAD 코드 분석 Part II (260711)

WonTerry·2026년 7월 11일

Deep Learning

목록 보기
10/27

코드 제약: MNIST_Dataset 클래스의 설계

datasets/mnist.py 코드 확인:

self.normal_classes = tuple([normal_class])
self.outlier_classes = list(range(0, 10))
self.outlier_classes.remove(normal_class)
self.outlier_classes = tuple(self.outlier_classes)   # <- normal_class를 제외한 "나머지 전부"가 이상치

if n_known_outlier_classes == 0:
    self.known_outlier_classes = ()
elif n_known_outlier_classes == 1:
    self.known_outlier_classes = tuple([known_outlier_class])   # <- 지정한 1개 클래스만 "라벨 있음"
else:
    self.known_outlier_classes = tuple(random.sample(self.outlier_classes, n_known_outlier_classes))  # <- 2개 이상이면 랜덤 샘플링

핵심 제약 두 가지:

  1. outlier_classes(이상치로 취급되는 클래스 집합)는 항상 "정상 클래스를 제외한 나머지 전부"로 하드코딩되어 있습니다. 즉 MNIST에서 normal_class=0이면 이상치는 자동으로 1~9 전부가 됩니다. "이상 클래스를 1, 2로만 한정"하는 옵션 자체가 CLI에 없습니다.
  2. known_outlier_class(라벨이 있는 이상치 클래스)를 CLI에서 직접 지정할 수 있는 건 n_known_outlier_classes=1일 때뿐입니다. n_known_outlier_classes가 2 이상이면 특정 클래스를 지정하는 게 아니라 random.sample(...)무작위로 그만큼 클래스를 뽑습니다. 즉 "1, 2를 이상치로 쓰고 그중 3을 라벨" 같은 조합은 애초에 표현할 방법이 없습니다. (3은 1, 2와 별개의 클래스이기도 하고요)

CLI만으로 할 수 있는 것

--normal_class 0 --known_outlier_class 3 --n_known_outlier_classes 1로 실행하면:

  • 정상 클래스: 0
  • 이상치 클래스: 1~9 전부 (2뿐 아니라 3,4,5...9도 포함)
  • 그중 라벨(known)이 붙는 클래스: 3번만

즉 "1, 2, 3만 이상치로 쓰고 싶다"는 의도와는 다르게, 실제로는 1~9 전체가 이상치 풀에 들어가고 3번만 라벨이 붙습니다.

만일 코드 수정을 한다면, mnist.py 수정

outlier_classes를 원하는 클래스 집합으로 제한하도록 고치면 됩니다.

# 기존
self.outlier_classes = list(range(0, 10))
self.outlier_classes.remove(normal_class)
self.outlier_classes = tuple(self.outlier_classes)

# 수정 (이상치를 1, 2, 3으로만 제한)
self.outlier_classes = (1, 2, 3)

그리고 이후 로직은 그대로 두면, --known_outlier_class 3 --n_known_outlier_classes 1을 줬을 때 known_outlier_classes = (3,)이 되고, create_semisupervised_setting 함수가 outlier_classes=(1,2,3) 중에서 3번만 라벨을 붙이고 1, 2는 라벨 없는(unlabeled) 이상치로 남깁니다. 테스트셋도 outlier_classes 기준으로 이상/정상을 나누므로, 이렇게 하면 테스트 시점에도 1,2,3만 이상치로, 나머지(4~9)는 데이터셋에서 사실상 배제되지는 않고 여전히 로드되지만(0~9 전부 로드), 타겟 변환(target_transform)이 outlier_classes 멤버십 기준이라 4~9는 "이상치도 정상도 아닌" 애매한 라벨(0/False)로 잡힐 수 있으므로, 완전히 깔끔하게 하려면 train/test set 로드 시점에 4~9 샘플 자체를 걸러내는 필터링도 추가하는 게 안전합니다.

다른 데이터셋 파일들도 구조가 동일하므로, 다른 데이터셋에서 같은 걸 하고 싶다면 해당 datasets/*.py에서 같은 패턴을 찾아 수정하면 됩니다.

정리

  • 그대로 CLI만 쓰면: 이상치는 항상 "정상 클래스 제외 전부", 라벨 있는 클래스는 1개만 지정 가능 (2개 이상은 랜덤).
  • 딱 원하시는 "이상치=1,2,3(라벨은 3만)" 구성을 하려면 datasets/mnist.pyself.outlier_classes 부분을 직접 고쳐야 합니다.

profile
Hello, I'm Terry! 👋 Enjoy every moment of your life! 🌱 My current interests are Signal processing, Machine learning, Python, Database, LLM & RAG, MCP & ADK, Multi-Agents, Physical AI, ROS2...

0개의 댓글