[모두의 연구소] 논문 학습 - Deep SAD (260709)

WonTerry·2026년 7월 9일

Deep Learning

목록 보기
5/32

https://github.com/lukasruff/Deep-SAD-PyTorch

초기 설정

Dataset: mnist
Normal class: 0

즉, 데이터셋 : MNIST
정상 데이터 : 숫자 0 입니다.

0 = 정상
1~9 = 이상치

가 됩니다.

Ratio of labeled normal train samples: 0.00
Ratio of labeled anomalous samples: 0.00

의미는 훈련 데이터에

라벨이 있는 정상 데이터
라벨이 있는 이상 데이터가 하나도 없다는 뜻입니다.

즉, 완전한 Unsupervised 환경입니다.
논문의 기본 설정 그대로입니다.

Pollution ratio of unlabeled train data: 0.00

훈련 데이터 안에는 이상치가 섞여 있지 않습니다.
즉, 훈련 데이터는 0만 존재합니다.

Known anomaly classes: 0

알고 있는 이상 클래스도 없습니다.


1) all_low

모든 테스트 이미지 중에서 score가 가장 작은 이미지들입니다.
즉, 모델이"이건 정말 정상이다." 라고 가장 강하게 확신하는 이미지입니다.

2) all_high

모든 테스트 이미지 중 score가 가장 큰 이미지입니다.
Deep SAD가 "이건 절대로 정상이 아니다." 라고 판단한 이미지입니다.

3) normals_low

이번에는 정답(Label)을 알고 있습니다.
즉, 실제 정상 -> 가장 정상처럼 생긴 이미지를 보여줍니다.
모델이 정상 데이터를 얼마나 잘 학습했는지 보여줍니다.

4) normals_high

이번에는 실제 정상 -> score 내림차순입니다.
즉, 정상인데 모델이 이상하다고 생각한 이미지입니다.
이것이 의미하는 것은 False Positive를 눈으로 확인하는 것입니다.


왜 논문에서 이 그림을 보여주는가?

이 네 장의 이미지는 수치적인 AUC만으로는 알 수 없는 모델의 판단 근거를 시각적으로 검증하기 위한 것입니다.

예를 들어 AUC가 98.5%라고 하더라도 다음 두 모델은 전혀 다를 수 있습니다.

좋은 모델: all_high에는 숫자 1~9만 있고, normals_high에는 약간 찌그러진 0만 있다.
나쁜 모델: all_high에 정상적인 0도 많이 포함되어 있고, normals_high에도 깨끗한 0가 다수 포함되어 있다.

따라서 이 네 장의 이미지는 모델이 정상의 개념을 제대로 학습했는지, 어떤 정상 샘플을 어려워하는지, 이상 샘플을 얼마나 명확하게 구분하는지를 사람이 직관적으로 평가하는 핵심 자료입니다.

즉, 이 코드는 단순히 예쁜 그림을 저장하는 것이 아니라, Deep SAD가 계산한 이상 점수(score)를 실제 이미지와 연결하여 모델의 판단을 해석(Explainability)하기 위한 중요한 시각화 과정이라고 이해하면 됩니다.


코드 실행 결과

INFO:root:Export path is ./
INFO:root:Dataset: mnist
INFO:root:Normal class: 0
INFO:root:Ratio of labeled normal train samples: 0.00
INFO:root:Ratio of labeled anomalous samples: 0.00
INFO:root:Pollution ratio of unlabeled train data: 0.00
INFO:root:Number of known anomaly classes: 0
INFO:root:Network: mnist_LeNet
INFO:root:Eta-parameter: 1.00
INFO:root:Set seed to 0.
INFO:root:Computation device: cpu
INFO:root:Number of threads: 0
INFO:root:Number of dataloader workers: 0
100.0%
100.0%
100.0%
100.0%
INFO:root:Pretraining: True
INFO:root:Pretraining optimizer: adam
INFO:root:Pretraining learning rate: 0.001
INFO:root:Pretraining epochs: 100
INFO:root:Pretraining learning rate scheduler milestones: (0,)
INFO:root:Pretraining batch size: 128
INFO:root:Pretraining weight decay: 1e-06
INFO:root:Starting pretraining...
c:\Dev\2026_Dev\Deep_SAD_260709\src\optim\ae_trainer.py:51: UserWarning: Detected call of `lr_scheduler.step()` before `optimizer.step()`. In PyTorch 1.1.0 and later, you should call them in the opposite order: `optimizer.step()` before `lr_scheduler.step()`.  Failure to do this will result in PyTorch skipping the first value of the learning rate schedule. See more details at https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate
  scheduler.step()
c:\Users\wonta\anaconda3\envs\py311_pytorch\Lib\site-packages\torch\optim\lr_scheduler.py:744: UserWarning: To get the last learning rate computed by the scheduler, please use `get_last_lr()`.
  _warn_get_lr_called_within_step(self)
INFO:root:  LR scheduler: new learning rate is 0.0001
INFO:root:| Epoch: 001/100 | Train Time: 1.543s | Train Loss: 0.229734 |
INFO:root:| Epoch: 002/100 | Train Time: 1.677s | Train Loss: 0.161604 |
INFO:root:| Epoch: 003/100 | Train Time: 1.692s | Train Loss: 0.121042 |
INFO:root:| Epoch: 004/100 | Train Time: 1.782s | Train Loss: 0.099012 |
INFO:root:| Epoch: 005/100 | Train Time: 1.585s | Train Loss: 0.086876 |
INFO:root:| Epoch: 006/100 | Train Time: 1.627s | Train Loss: 0.079059 |
INFO:root:| Epoch: 007/100 | Train Time: 1.831s | Train Loss: 0.073267 |
INFO:root:| Epoch: 008/100 | Train Time: 1.974s | Train Loss: 0.068564 |
INFO:root:| Epoch: 009/100 | Train Time: 2.226s | Train Loss: 0.064706 |
INFO:root:| Epoch: 010/100 | Train Time: 2.224s | Train Loss: 0.061515 |
INFO:root:| Epoch: 011/100 | Train Time: 1.860s | Train Loss: 0.058748 |
INFO:root:| Epoch: 012/100 | Train Time: 2.436s | Train Loss: 0.056267 |
INFO:root:| Epoch: 013/100 | Train Time: 2.839s | Train Loss: 0.053947 |
INFO:root:| Epoch: 014/100 | Train Time: 2.758s | Train Loss: 0.051669 |
INFO:root:| Epoch: 015/100 | Train Time: 2.476s | Train Loss: 0.049514 |
INFO:root:| Epoch: 016/100 | Train Time: 2.408s | Train Loss: 0.047552 |
INFO:root:| Epoch: 017/100 | Train Time: 2.663s | Train Loss: 0.045684 |
INFO:root:| Epoch: 018/100 | Train Time: 2.472s | Train Loss: 0.043932 |
INFO:root:| Epoch: 019/100 | Train Time: 2.720s | Train Loss: 0.042248 |
INFO:root:| Epoch: 020/100 | Train Time: 4.265s | Train Loss: 0.040675 |
INFO:root:| Epoch: 021/100 | Train Time: 4.241s | Train Loss: 0.039201 |
INFO:root:| Epoch: 022/100 | Train Time: 4.177s | Train Loss: 0.037835 |
INFO:root:| Epoch: 023/100 | Train Time: 3.996s | Train Loss: 0.036563 |
INFO:root:| Epoch: 024/100 | Train Time: 3.678s | Train Loss: 0.035364 |
INFO:root:| Epoch: 025/100 | Train Time: 4.238s | Train Loss: 0.034223 |
INFO:root:| Epoch: 026/100 | Train Time: 4.111s | Train Loss: 0.033170 |
INFO:root:| Epoch: 027/100 | Train Time: 4.125s | Train Loss: 0.032164 |
INFO:root:| Epoch: 028/100 | Train Time: 3.704s | Train Loss: 0.031197 |
INFO:root:| Epoch: 029/100 | Train Time: 4.052s | Train Loss: 0.030281 |
INFO:root:| Epoch: 030/100 | Train Time: 3.996s | Train Loss: 0.029421 |
INFO:root:| Epoch: 031/100 | Train Time: 3.866s | Train Loss: 0.028651 |
INFO:root:| Epoch: 032/100 | Train Time: 3.938s | Train Loss: 0.027935 |
INFO:root:| Epoch: 033/100 | Train Time: 3.647s | Train Loss: 0.027260 |
INFO:root:| Epoch: 034/100 | Train Time: 2.555s | Train Loss: 0.026645 |
INFO:root:| Epoch: 035/100 | Train Time: 2.873s | Train Loss: 0.026033 |
INFO:root:| Epoch: 036/100 | Train Time: 2.528s | Train Loss: 0.025494 |
INFO:root:| Epoch: 037/100 | Train Time: 2.602s | Train Loss: 0.025005 |
INFO:root:| Epoch: 038/100 | Train Time: 2.485s | Train Loss: 0.024512 |
INFO:root:| Epoch: 039/100 | Train Time: 2.537s | Train Loss: 0.024058 |
INFO:root:| Epoch: 040/100 | Train Time: 2.465s | Train Loss: 0.023627 |
INFO:root:| Epoch: 041/100 | Train Time: 2.399s | Train Loss: 0.023215 |
INFO:root:| Epoch: 042/100 | Train Time: 2.165s | Train Loss: 0.022823 |
INFO:root:| Epoch: 043/100 | Train Time: 2.101s | Train Loss: 0.022461 |
INFO:root:| Epoch: 044/100 | Train Time: 2.405s | Train Loss: 0.022126 |
INFO:root:| Epoch: 045/100 | Train Time: 2.183s | Train Loss: 0.021776 |
INFO:root:| Epoch: 046/100 | Train Time: 2.064s | Train Loss: 0.021501 |
INFO:root:| Epoch: 047/100 | Train Time: 2.131s | Train Loss: 0.021164 |
INFO:root:| Epoch: 048/100 | Train Time: 2.498s | Train Loss: 0.020875 |
INFO:root:| Epoch: 049/100 | Train Time: 2.391s | Train Loss: 0.020627 |
INFO:root:| Epoch: 050/100 | Train Time: 2.490s | Train Loss: 0.020338 |
INFO:root:| Epoch: 051/100 | Train Time: 2.418s | Train Loss: 0.020089 |
INFO:root:| Epoch: 052/100 | Train Time: 2.385s | Train Loss: 0.019832 |
INFO:root:| Epoch: 053/100 | Train Time: 2.311s | Train Loss: 0.019604 |
INFO:root:| Epoch: 054/100 | Train Time: 2.373s | Train Loss: 0.019401 |
INFO:root:| Epoch: 055/100 | Train Time: 2.333s | Train Loss: 0.019164 |
INFO:root:| Epoch: 056/100 | Train Time: 2.784s | Train Loss: 0.018973 |
INFO:root:| Epoch: 057/100 | Train Time: 2.275s | Train Loss: 0.018745 |
INFO:root:| Epoch: 058/100 | Train Time: 2.667s | Train Loss: 0.018568 |
INFO:root:| Epoch: 059/100 | Train Time: 1.845s | Train Loss: 0.018371 |
INFO:root:| Epoch: 060/100 | Train Time: 2.573s | Train Loss: 0.018160 |
INFO:root:| Epoch: 061/100 | Train Time: 2.460s | Train Loss: 0.017996 |
INFO:root:| Epoch: 062/100 | Train Time: 2.517s | Train Loss: 0.017793 |
INFO:root:| Epoch: 063/100 | Train Time: 3.110s | Train Loss: 0.017629 |
INFO:root:| Epoch: 064/100 | Train Time: 4.162s | Train Loss: 0.017474 |
INFO:root:| Epoch: 065/100 | Train Time: 3.592s | Train Loss: 0.017315 |
INFO:root:| Epoch: 066/100 | Train Time: 3.444s | Train Loss: 0.017128 |
INFO:root:| Epoch: 067/100 | Train Time: 2.388s | Train Loss: 0.016967 |
INFO:root:| Epoch: 068/100 | Train Time: 2.418s | Train Loss: 0.016831 |
INFO:root:| Epoch: 069/100 | Train Time: 3.636s | Train Loss: 0.016658 |
INFO:root:| Epoch: 070/100 | Train Time: 4.120s | Train Loss: 0.016536 |
INFO:root:| Epoch: 071/100 | Train Time: 3.120s | Train Loss: 0.016404 |
INFO:root:| Epoch: 072/100 | Train Time: 3.732s | Train Loss: 0.016229 |
INFO:root:| Epoch: 073/100 | Train Time: 3.455s | Train Loss: 0.016113 |
INFO:root:| Epoch: 074/100 | Train Time: 2.365s | Train Loss: 0.015963 |
INFO:root:| Epoch: 075/100 | Train Time: 2.515s | Train Loss: 0.015817 |
INFO:root:| Epoch: 076/100 | Train Time: 2.528s | Train Loss: 0.015738 |
INFO:root:| Epoch: 077/100 | Train Time: 3.121s | Train Loss: 0.015592 |
INFO:root:| Epoch: 078/100 | Train Time: 2.661s | Train Loss: 0.015484 |
INFO:root:| Epoch: 079/100 | Train Time: 3.145s | Train Loss: 0.015356 |
INFO:root:| Epoch: 080/100 | Train Time: 3.727s | Train Loss: 0.015226 |
INFO:root:| Epoch: 081/100 | Train Time: 2.590s | Train Loss: 0.015107 |
INFO:root:| Epoch: 082/100 | Train Time: 3.820s | Train Loss: 0.015011 |
INFO:root:| Epoch: 083/100 | Train Time: 2.976s | Train Loss: 0.014907 |
INFO:root:| Epoch: 084/100 | Train Time: 2.524s | Train Loss: 0.014807 |
INFO:root:| Epoch: 085/100 | Train Time: 2.389s | Train Loss: 0.014718 |
INFO:root:| Epoch: 086/100 | Train Time: 2.616s | Train Loss: 0.014603 |
INFO:root:| Epoch: 087/100 | Train Time: 2.594s | Train Loss: 0.014518 |
INFO:root:| Epoch: 088/100 | Train Time: 2.841s | Train Loss: 0.014426 |
INFO:root:| Epoch: 089/100 | Train Time: 2.536s | Train Loss: 0.014364 |
INFO:root:| Epoch: 090/100 | Train Time: 3.261s | Train Loss: 0.014262 |
INFO:root:| Epoch: 091/100 | Train Time: 2.883s | Train Loss: 0.014154 |
INFO:root:| Epoch: 092/100 | Train Time: 2.620s | Train Loss: 0.014088 |
INFO:root:| Epoch: 093/100 | Train Time: 2.527s | Train Loss: 0.014014 |
INFO:root:| Epoch: 094/100 | Train Time: 2.924s | Train Loss: 0.013915 |
INFO:root:| Epoch: 095/100 | Train Time: 2.853s | Train Loss: 0.013829 |
INFO:root:| Epoch: 096/100 | Train Time: 2.337s | Train Loss: 0.013781 |
INFO:root:| Epoch: 097/100 | Train Time: 2.225s | Train Loss: 0.013711 |
INFO:root:| Epoch: 098/100 | Train Time: 2.377s | Train Loss: 0.013647 |
INFO:root:| Epoch: 099/100 | Train Time: 2.403s | Train Loss: 0.013538 |
INFO:root:| Epoch: 100/100 | Train Time: 2.554s | Train Loss: 0.013489 |
INFO:root:Pretraining Time: 278.029s
INFO:root:Finished pretraining.
INFO:root:Testing autoencoder...
INFO:root:Test Loss: 0.041194
INFO:root:Test AUC: 99.28%
INFO:root:Test Time: 2.808s
INFO:root:Finished testing autoencoder.
INFO:root:Training optimizer: adam
INFO:root:Training learning rate: 0.001
INFO:root:Training epochs: 50
INFO:root:Training learning rate scheduler milestones: (0,)
INFO:root:Training batch size: 128
INFO:root:Training weight decay: 1e-06
INFO:root:Initializing center c...
INFO:root:Center c initialized.
INFO:root:Starting training...
c:\Dev\2026_Dev\Deep_SAD_260709\src\optim\DeepSAD_trainer.py:62: UserWarning: Detected call of `lr_scheduler.step()` before `optimizer.step()`. In PyTorch 1.1.0 and later, you should call them in the opposite order: `optimizer.step()` before `lr_scheduler.step()`.  Failure to do this will result in PyTorch skipping the first value of the learning rate schedule. See more details at https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate
  scheduler.step()
c:\Users\wonta\anaconda3\envs\py311_pytorch\Lib\site-packages\torch\optim\lr_scheduler.py:744: UserWarning: To get the last learning rate computed by the scheduler, please use `get_last_lr()`.
  _warn_get_lr_called_within_step(self)
INFO:root:  LR scheduler: new learning rate is 0.0001
INFO:root:| Epoch: 001/050 | Train Time: 2.133s | Train Loss: 5.692480 |
INFO:root:| Epoch: 002/050 | Train Time: 1.573s | Train Loss: 2.068738 |
INFO:root:| Epoch: 003/050 | Train Time: 1.569s | Train Loss: 1.419598 |
INFO:root:| Epoch: 004/050 | Train Time: 1.712s | Train Loss: 1.028813 |
INFO:root:| Epoch: 005/050 | Train Time: 1.563s | Train Loss: 0.792035 |
INFO:root:| Epoch: 006/050 | Train Time: 1.559s | Train Loss: 0.637628 |
INFO:root:| Epoch: 007/050 | Train Time: 1.744s | Train Loss: 0.529437 |
INFO:root:| Epoch: 008/050 | Train Time: 1.826s | Train Loss: 0.450265 |
INFO:root:| Epoch: 009/050 | Train Time: 1.681s | Train Loss: 0.389629 |
INFO:root:| Epoch: 010/050 | Train Time: 1.498s | Train Loss: 0.341908 |
INFO:root:| Epoch: 011/050 | Train Time: 1.659s | Train Loss: 0.303112 |
INFO:root:| Epoch: 012/050 | Train Time: 1.657s | Train Loss: 0.271664 |
INFO:root:| Epoch: 013/050 | Train Time: 1.732s | Train Loss: 0.244635 |
INFO:root:| Epoch: 014/050 | Train Time: 1.748s | Train Loss: 0.222225 |
INFO:root:| Epoch: 015/050 | Train Time: 1.680s | Train Loss: 0.203111 |
INFO:root:| Epoch: 016/050 | Train Time: 1.599s | Train Loss: 0.186451 |
INFO:root:| Epoch: 017/050 | Train Time: 1.589s | Train Loss: 0.171833 |
INFO:root:| Epoch: 018/050 | Train Time: 1.743s | Train Loss: 0.159504 |
INFO:root:| Epoch: 019/050 | Train Time: 1.705s | Train Loss: 0.148345 |
INFO:root:| Epoch: 020/050 | Train Time: 1.696s | Train Loss: 0.138427 |
INFO:root:| Epoch: 021/050 | Train Time: 1.719s | Train Loss: 0.129799 |
INFO:root:| Epoch: 022/050 | Train Time: 2.905s | Train Loss: 0.121808 |
INFO:root:| Epoch: 023/050 | Train Time: 3.502s | Train Loss: 0.114867 |
INFO:root:| Epoch: 024/050 | Train Time: 3.710s | Train Loss: 0.108429 |
INFO:root:| Epoch: 025/050 | Train Time: 3.188s | Train Loss: 0.102752 |
INFO:root:| Epoch: 026/050 | Train Time: 3.502s | Train Loss: 0.097417 |
INFO:root:| Epoch: 027/050 | Train Time: 3.909s | Train Loss: 0.092627 |
INFO:root:| Epoch: 028/050 | Train Time: 3.494s | Train Loss: 0.088134 |
INFO:root:| Epoch: 029/050 | Train Time: 4.087s | Train Loss: 0.084029 |
INFO:root:| Epoch: 030/050 | Train Time: 4.239s | Train Loss: 0.080216 |
INFO:root:| Epoch: 031/050 | Train Time: 3.945s | Train Loss: 0.076715 |
INFO:root:| Epoch: 032/050 | Train Time: 2.997s | Train Loss: 0.073509 |
INFO:root:| Epoch: 033/050 | Train Time: 3.147s | Train Loss: 0.070351 |
INFO:root:| Epoch: 034/050 | Train Time: 3.490s | Train Loss: 0.067577 |
INFO:root:| Epoch: 035/050 | Train Time: 2.747s | Train Loss: 0.064820 |
INFO:root:| Epoch: 036/050 | Train Time: 2.797s | Train Loss: 0.062311 |
INFO:root:| Epoch: 037/050 | Train Time: 2.927s | Train Loss: 0.059844 |
INFO:root:| Epoch: 038/050 | Train Time: 3.144s | Train Loss: 0.057702 |
INFO:root:| Epoch: 039/050 | Train Time: 2.786s | Train Loss: 0.055606 |
INFO:root:| Epoch: 040/050 | Train Time: 3.038s | Train Loss: 0.053579 |
INFO:root:| Epoch: 041/050 | Train Time: 2.939s | Train Loss: 0.051726 |
INFO:root:| Epoch: 042/050 | Train Time: 3.114s | Train Loss: 0.049987 |
INFO:root:| Epoch: 043/050 | Train Time: 2.800s | Train Loss: 0.048249 |
INFO:root:| Epoch: 044/050 | Train Time: 3.193s | Train Loss: 0.046634 |
INFO:root:| Epoch: 045/050 | Train Time: 3.050s | Train Loss: 0.045022 |
INFO:root:| Epoch: 046/050 | Train Time: 3.013s | Train Loss: 0.043596 |
INFO:root:| Epoch: 047/050 | Train Time: 3.071s | Train Loss: 0.042217 |
INFO:root:| Epoch: 048/050 | Train Time: 2.943s | Train Loss: 0.040852 |
INFO:root:| Epoch: 049/050 | Train Time: 2.715s | Train Loss: 0.039731 |
INFO:root:| Epoch: 050/050 | Train Time: 1.360s | Train Loss: 0.038394 |
INFO:root:Training Time: 127.296s
INFO:root:Finished training.
INFO:root:Starting testing...
INFO:root:Test Loss: 0.149700
INFO:root:Test AUC: 98.52%
INFO:root:Test Time: 1.730s
INFO:root:Finished testing.
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개의 댓글