CLIP 모델 활용 플로우 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
1. CLIP 임베딩 활용 카테고리 분류 플로우
a. 개요
- 사용자 이미지에 대해 사전 정의된 카테고리 키워드와의 의미적 유사성을 기준으로 분류
- 비슷한 이미지들끼리 먼저 그룹화하여 태깅 일관성 확보 및 불필요한 연산 최소화
- 이후 각 그룹 단위로 대표 임베딩을 추출하여 카테고리 매칭 효율화
b. 사용 모듈
- CLIP (image & text encoder): 이미지 임베딩 + 카테고리 키워드 임베딩
- scikit-learn
cosine_similarity
: 이미지 간 유사도 계산KMeans
또는NearestNeighbors
: 유사 이미지 KNN 그룹화
c. 단계별 상세 플로우
가. 카테고리 키워드 임베딩 사전 구축 (1회성)
category_keywords = ["person", "food", "nature", "architecture", "emotion", ...]
text_features = model.encode_text(clip.tokenize(["a photo of " + c for c in category_keywords]))
text_features /= text_features.norm(dim=-1, keepdim=True)
→ 사전 정의된 카테고리 키워드 리스트를 CLIP 텍스트 인코딩 후 정규화하여 저장
나. 입력 이미지 임베딩
image_features = model.encode_image(preprocessed_image)
image_features /= image_features.norm(dim=-1, keepdim=True)
→ 이미지 1장 또는 배치 입력에 대해 임베딩 추출 및 정규화
다. 이미지 유사도 기반 KNN 그룹화
- 유사한 이미지들끼리 그룹핑 (클러스터링 또는 근접 이웃 방식)
from sklearn.neighbors import NearestNeighbors
nn = NearestNeighbors(n_neighbors=5, metric='cosine')
nn.fit(image_features)
distances, indices = nn.kneighbors(image_features)
→ 또는 AgglomerativeClustering
, KMeans
, DBSCAN
도 대안
라. 대표 임베딩과 카테고리 키워드 간 유사도 계산
similarity = cosine_similarity(group_embeds.cpu().numpy(), text_features.cpu().numpy())
topk_indices = similarity.argsort(axis=1)[:, -k:][:, ::-1]
마. 결과 반환: 카테고리 / 사진 리스트
-
category와 images를 연결해서 반환
-
경로는 URL 형태로 반환 (예:
http://server:8000/img3.jpg
) -
반환 예시:
[ { "category": "food", "images": ["http://server:8000/img1.jpg"] }, { "category": "beach", "images": ["http://server:8000/img2.jpg"] }, { "category": "others", "images": ["http://server:8000/img3.jpg", "http://server:8000/img4.jpg"] } ]
→ 유사한 키워드가 없는 사진은 others로 분류
d. 플로우 요약 문장
- 이 파이프라인은 CLIP 임베딩을 기반으로 입력 이미지 간 유사도를 계산하고,
- KNN 기반으로 비슷한 이미지들을 그룹화한 뒤, 각 그룹에 대해 대표 임베딩을 산출하여
- 사전 정의된 카테고리 키워드와의 코사인 유사도를 통해 카테고리를 매핑한다.
2. CLIP 임베딩 활용 중복 사진 필터링 플로우
a. 개요
- 동일한 장소/장면/구도에서 촬영된 이미지 중 중복 또는 매우 유사한 사진들을 자동으로 그룹핑
- 사용자 UI에서 중복 이미지 제거, 대표 컷 선택, 앨범 정리 자동화에 활용
b. 사용 모듈
- CLIP
- 이미지 임베딩:
model.encode_image(...)
- 이미지 임베딩:
- scikit-learn
- 유사도 계산:
cosine_similarity
- 클러스터링:
DBSCAN
또는AgglomerativeClustering
(유사도 기반)
- 유사도 계산:
c. 단계별 상세 플로우
가. 입력 이미지 임베딩
image_features = model.encode_image(preprocessed_image)
image_features /= image_features.norm(dim=-1, keepdim=True)
→ 이미지 1장 또는 배치 입력에 대해 임베딩 추출 및 정규화
나. 이미지 간 코사인 유사도 행렬 계산
from sklearn.metrics.pairwise import cosine_similarity
similarity_matrix = cosine_similarity(image_features.cpu().numpy())
N x N
행렬 반환 (입력 이미지 N장)
다. 유사 이미지 그룹핑 (DBSCAN 기반)
from sklearn.cluster import DBSCAN
# 임계값 기준: cosine distance = 1 - cosine similarity
db = DBSCAN(eps=0.1, metric="cosine", min_samples=2)
labels = db.fit_predict(image_features.cpu().numpy())
eps=0.1
정도면 similarity가 0.9 이상인 이미지를 같은 그룹으로 봄label = -1
은 단독 이미지로 간주 (outlier)
라. 그룹별 이미지 경로 정리
from collections import defaultdict
grouped_images = defaultdict(list)
for idx, label in enumerate(labels):
if label != -1:
grouped_images[label].append(image_urls[idx])
result = list(grouped_images.values())
마. 결과 반환 형식
[
["http://server:8000/img1.jpg", "http://server:8000/img3.jpg"],
["http://server:8000/img2.jpg", "http://server:8000/img4.jpg"]
]
- 각 리스트는 유사한 이미지로 구성된 그룹을 의미
- 단독 이미지(
label == -1
)는 반환하지 않음
d. 플로우 요약 문장
- 이 파이프라인은 CLIP 이미지 임베딩을 기반으로 전체 이미지 간의 코사인 유사도를 계산하고,
- DBSCAN 클러스터링 알고리즘을 통해 유사도가 높은 이미지들을 자동으로 그룹화한다.
- 결과적으로, 사용자는 중복되거나 거의 동일한 사진들을 묶어서 정리할 수 있으며,
- 대표 사진만을 선택하거나 유사한 사진 중 하나만 남겨 앨범을 간결하게 구성할 수 있다.
3. CLIP 임베딩 활용 하이라이트 스코어링 플로우
a. 개요
- 다수의 사진 중 미적으로 더 뛰어난 사진을 정량적으로 평가
- 하이라이트 자동 선택, 앨범 대표 컷 지정, 요약 앨범 구성 등에 활용
b. 사용 모듈
-
CLIP (image encoder)
→ 미리 학습된 비주얼 임베딩 사용
-
scikit-learn (Prompt 방식 + Linear Probe)
→
cosine_similarity
,LinearRegression
-
PyTorch (Linear 방식)
→
torch.nn.Linear
,torch.nn.functional
torch.optim.Adam
,MSELoss
-
(선택적으로) LAION-Aesthetic or AVA dataset
c. 단계별 상세 플로우
가. 학습용 aesthetic dataset 확보
-
AVA dataset
(이미지, score)
쌍으로 구성된 학습 데이터셋 준비score
: 보통 1~10 사이의 연속형 또는 정수형 평가 점수
나. 학습용 CLIP 임베딩 추출 (오프라인 처리)
# image_features.shape: [num_samples, 512]
train_features = model.encode_image(train_images)
train_features /= train_features.norm(dim=-1, keepdim=True)
다. Linear 회귀 모델 학습
- PyTorch 학습 방식
import torch.nn as nn
class AestheticRegressor(nn.Module):
def __init__(self, dim=512):
super().__init__()
self.linear = nn.Linear(dim, 1)
def forward(self, x):
return self.linear(x).squeeze(1) # shape [B]
model = AestheticRegressor()
loss_fn = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
# 학습 루프 생략 가능
라. 점수 추정 (추론 시)
with torch.no_grad():
scores = model(image_features).cpu().numpy()
마. 결과 반환
- 각 카테고리별로, 이미지 - 점수 쌍을 반환
- 반환 예시:
[
{
"category": "food",
"images": [
{ "image": "http://server:8000/img1.jpg", "score": 0.91 }
]
},
{
"category": "beach",
"images": [
{ "image": "http://server:8000/img2.jpg", "score": 0.86 }
]
}
]
d. 플로우 요약 문장
- 이 파이프라인은 CLIP 이미지 임베딩을 이용하여 Prompt 기반 또는 Linear Probing 기반의 aesthetic 점수를 추정한다.
- Prompt 기반 방식은
"This is a photo with aesthetic score N"
형식의 텍스트와의 유사도를 통해 점수를 추정하며, - Linear Probing 방식은 LAION-Aesthetic이나 AVA 데이터셋으로 학습된 선형 회귀 모델을 통해 더 정교한 점수 예측이 가능하다.
- 결과 점수는 하이라이트 추천, 자동 앨범 구성, 대표 사진 선정 등에 사용된다.
- Prompt 기반 방식은
4. CLIP 임베딩 활용 저품질 이미지 필터링 플로우
a. 개요
- 초점 흐림, 픽셀 깨짐, 과도한 노이즈 등 저품질 이미지를 자동 탐지
- aesthetic과는 별개의 기계적 품질 판단 기준 제공
b. 사용 모듈
sklearn.metrics.pairwise.cosine_similarity
torch
numpy
c. 단계별 상세 플로우
가. 텍스트 임베딩 생성 (프롬프트 쌍)
prompts = [
"a sharp, clear photo", # good_0
"a blurry, out-of-focus photo", # bad_0
"a high-resolution photo", # good_1
"a pixelated, low-resolution photo", # bad_1
"a clean photo",
"a noisy, grainy photo",
"a well-lit photo",
"a poorly lit, underexposed photo",
"a natural-looking photo",
"a photo with compression artifacts"
]
flat_prompts = [p for pair in prompts for p in pair] # length = 10
text_features = model.encode_text(clip.tokenize(flat_prompts))
text_features = text_features.cpu().numpy()
나. 코사인 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity
image_features_np = image_features.cpu().numpy()
similarity = cosine_similarity(image_features_np, text_features)
다. 프롬프트 쌍별 품질 점수 계산
import numpy as np
num_criteria = len(prompts)
quality_scores = np.stack([
similarity[:, i * 2] - similarity[:, i * 2 + 1]
for i in range(num_criteria)
], axis=1) # shape: [N, 5]
라. 저품질 이미지 판별
threshold = 0.2 # 낮은 점수면 저품질로 간주
low_quality_mask = (quality_scores < threshold).any(axis=1)
low_quality_images = [url for i, url in enumerate(image_urls) if low_quality_mask[i]]
마. 결과 반환
- 퀄리티 점수가 threshold 아래인 이미지만 반환
- 반환 예시
[
"http://server:8000/img2.jpg",
"http://server:8000/img3.jpg"
]
d. 플로우 요약 문장
- 이 파이프라인은 사전 추출된 CLIP 임베딩을 이용하여 품질 관련 프롬프트 쌍(예:
"a sharp photo"
vs"a blurry photo"
)과의 유사도를 비교하고,- 초점 흐림, 해상도, 노이즈, 조명, 압축 문제 등 다양한 품질 요소에 대해 개별적으로 점수를 계산한다.