V1 로직(CLIP 활용) - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
1. 로직 요약
a. 입력
req.images
: 이미지 파일명 리스트
- 사전 생성된 CLIP 임베딩을 캐시에서 불러옴 (
get_cached_embeddings_parallel
사용)
b. 임베딩 처리
image_features = torch.stack(image_features)
- 모든 이미지의
[N, D]
차원 CLIP 임베딩을 하나의 텐서로 결합
c. 유사도 계산 → 거리 행렬 변환
normed = image_features / image_features.norm(dim=1, keepdim=True)
similarity_matrix = normed @ normed.T
distance_matrix = 1 - similarity_matrix
- Cosine similarity 계산
- 유사도를 1에서 빼서 Cosine distance matrix 생성
d. DBSCAN 클러스터링 (유사한 이미지 묶기)
DBSCAN(eps=0.1, min_samples=2, metric="precomputed")
eps
: 두 이미지가 중복으로 간주되기 위한 최대 거리 (기본값: 0.1)
min_samples
: 동일 그룹으로 판단할 최소 이미지 수 (기본값: 2)
- 거리 행렬 기반 클러스터링 수행 → label 할당 (-1은 noise)
e. 중복 그룹 구성
groups[label].append(image_names[idx])
- 같은 클러스터(label)를 가진 이미지들을 하나의 그룹으로 묶음
- noise(
label == -1
)는 제외됨
f. 최종 결과
{
"message": "success",
"data": [
["img1.jpg", "img2.jpg"],
["img5.jpg", "img8.jpg", "img9.jpg"]
]
}
- 각 중복 그룹을 하나의 리스트로 반환
- 전체 결과는 List[List[str]] 형식
2. 특징 및 장점
항목 |
설명 |
모델 |
OpenAI CLIP 기반 임베딩 사용 |
비교 방식 |
Cosine similarity → distance 변환 후 DBSCAN 적용 |
중복 판단 기준 |
거리 기반 클러스터링 (eps , min_samples 조정 가능) |
성능 |
모든 쌍 간 유사도를 계산하지만, N이 적당하면 실시간 응답 가능 |