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 데이터셋으로 학습된 선형 회귀 모델을 통해 더 정교한 점수 예측이 가능하다.
    • 결과 점수는 하이라이트 추천, 자동 앨범 구성, 대표 사진 선정 등에 사용된다.

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")과의 유사도를 비교하고,
    • 초점 흐림, 해상도, 노이즈, 조명, 압축 문제 등 다양한 품질 요소에 대해 개별적으로 점수를 계산한다.