[ Anomaly Detection ] PatchCore

JSM0315·2026년 5월 9일

논문리뷰

목록 보기
25/25

이상치 탐지(Anomaly Detection) 모델을 다루다 보면 항상 가장 먼저, 그리고 가장 크게 부딪히는 벽이 하나 있다. 바로 '정상 데이터'만으로 모델을 학습시켜야 한다는 점이다.
실제 산업 현장이나 데이터를 다룰 때, 결함이 있는 비정상(Anomaly) 데이터는 구하기도 힘들뿐더러 그 형태가 워낙 예측 불가능하고 다양하다. 그래서 결국 정상(Good) 데이터들만 잔뜩 모아놓고 "이게 정상이야! 여기서 조금이라도 벗어나면 다 이상치로 간주해!"라고 모델에게 가르쳐야만 한다. 그런데 문제는, 도대체 이 '정상'의 기준과 경계를 어디까지로 정의해야 하냐는 거다. 정상 데이터만 보고 학습해서 정상과 비정상의 경계를 완벽하게 긋는 것, 이게 이상치 탐지 학습의 가장 큰 어려움이다.
그래서 내가 볼 때 이 챌린지를 정말 스마트하게 풀어낸 방법론이 바로 PatchCore 알고리즘이다.
PatchCore의 아주 심플한 동작 흐름
PatchCore의 뼈대는 생각보다 직관적이다.

1.	처음부터 바닥에서 학습하는 게 아니라, ImageNet처럼 거대한 데이터셋으로 이미 똑똑하게 사전학습(Pre-trained)된 Backbone 모델을 가져온다.
2.	여기에 우리의 정상 이미지들을 쫙 밀어 넣어서 이미지의 특징(Feature Vector)들을 추출해 낸다.
3.	이 추출된 Feature Vector들을 기반으로 자기들만의 거대한 '정상의 좌표계(Feature Space)'를 형성한다.
4.	이제 추론(Inference) 시에 테스트 이미지가 들어오면? 똑같이 Feature Vector를 뽑아보고, 기존에 만들어둔 정상 좌표계들과 거리를 비교한다. 만약 거리가 너무 멀다 싶으면 "어, 너 이상치!" 하고 잡아내는 거다.

하지만 여기서 현실적인 문제가 생긴다. 학습 데이터에서 나온 모든 Feature Vector를 전부 다 저장해 두고, 테스트할 때마다 모든 데이터와 일일이 거리를 비교한다면 연산량이 진짜 터져버린다. 그래서 전체 데이터 중에서 가장 똘똘하고 대표성을 띠는 N개의 Feature Vector만 선별해 내야 하는데, 이게 바로 PatchCore의 진짜 핵심인 Coreset (코어셋)이다.

Feature Map은 어떻게 뽑고 다듬을까?

PatchCore는 모델의 최종 결괏값 하나만 띡 가져다 쓰지 않는다. 이미지의 패턴(Low-level)과 의미적인 추상화(High-level)를 모두 고려하기 위해, 보통 모델의 중간쯤인 Layer 3과 Layer 4 정도에서 Feature Map을 두 개 추출해서 쓴다.
이 두 개를 하나로 합쳐줘야 하는데, 깊은 레이어(Layer 4)에서 나온 Feature Map은 해상도 사이즈가 더 작다. 그래서 이 녀석을 얕은 레이어(Layer 3) 크기에 맞춰서 선형 보간(Bilinear Interpolation)으로 사이즈를 쫙 키워준다. 그런 다음 채널(Channel) 방향으로 그대로 Concat해서 더 깊고 풍부한 Feature Map으로 합쳐버린다.
여기에 실전을 위한 디테일이 하나 더 들어간다. 공장 라인이나 실제 환경에서는 카메라가 미세하게 흔들릴 수도 있고 정렬이 완벽하지 않을 수 있다. 이런 노이즈에 모델이 강건(Robust)해지도록, 합쳐진 Feature Map에 Average Pooling을 한 번 때려줘서 주변 값들을 부드럽게 조정해 준다.

연산량 다이어트의 핵심: Coreset과 Random Projection

이렇게 전처리가 끝난 Feature Map들은 이제 이미지 상의 위치 정보(x,y)(x, y)는 무시하고, 그냥 위치와 상관없는 개별 Feature Vector들의 모음으로 취급한다. 이 Vector들을 학습 데이터 분량만큼 싹 다 긁어모으면 어마어마한 양의 Feature Bank M\mathcal{M}이 만들어진다.

이제 여기서 N개의 Coreset 를 선별해야 한다. Coreset의 목적은 수식으로 보면 단순명료하다. 전체 데이터 M\mathcal{M}에 있는 어떤 포인트든, Coreset 안에 있는 가장 가까운 포인트와의 거리가 '최소'가 되도록, 즉 전체를 가장 잘 대표하는 N개를 고르는 것이다.

그런데 1024차원, 2048차원 하는 무거운 고차원 벡터들끼리 저 거리를 다 계산하면서 Coreset을 찾으려고 하면 세월아 네월아다. 연산이 끝이 안 난다.
여기서 엄청난 테크닉이 하나 들어오는데, 바로 Random Projection 이다. 고차원 공간에서는 임의로(Random) 벡터들을 투영해서 더 작은 차원으로 찌그러뜨려도, 벡터들끼리 거의 직교하는 성질 때문에 원래의 '거리 비율'이 크게 깨지지 않는다는 수학적 원리를 이용한다.

즉, 무거운 원래 채널로 무식하게 거리를 구하는 게 아니라, 128차원 정도로 팍 줄여버린 상태에서 거리 계산을 쫙 돌려버리는 거다. 그렇게 가벼운 상태로 거리를 구한 뒤 "여기서 가장 먼 게 뭔지"만 빠르게 솎아내서 Coreset을 구축한다. 연산량을 미친 듯이 줄이면서도 성능은 챙기는 이 알고리즘의 진짜 핵심 킥이다.

마무리

이렇게 Random Projection과 거리 계산을 거쳐 최종적으로 똘똘한 N개의 Coreset이 선별되면, 이걸 Memory Bank라는 이름으로 딱 저장해 둔다.
결국 실전(Inference)에서는 무거운 학습 데이터 전체가 아니라, 이 가볍고 강력한 Memory Bank 하나만 들고서 새로 들어오는 이미지의 Feature들과 거리를 쓱쓱 비교해가며 빠르고 정확하게 이상치를 찾아내게 된다.
정상 데이터만으로 학습해야 하는 한계를, Pre-trained Feature 공간과 Coreset이라는 아이디어로 너무나도 깔끔하게 풀어낸 방법론이다.

[ 깃허브링크 ] : https://github.com/chungSungMin/AnomalyDetection/tree/main/PatchCore

profile
누구보다 열심히

0개의 댓글