이미지 피처 추출

이미지 피처 추출 (Image feature extraction)

이미지 피처 추출은 이미지가 주어졌을 때 의미론적으로 유의미한 피처를 추출하는 작업입니다. 이미지 유사도(similarity)와 이미지 검색(retrieval)을 포함해 많은 사용 사례가 있습니다.

출처: 문서

본문

또한 대부분의 컴퓨터 비전 모델은 작업별 헤드(이미지 분류, 객체 탐지 등)를 제거하고 피처를 얻는 방식으로 이미지 피처 추출에 사용할 수 있습니다. 이런 피처는 에지 검출, 코너 검출 등 더 높은 수준에서 매우 유용합니다. 또한 모델의 깊이에 따라 실제 세계에 대한 정보(예: 고양이의 생김새)를 담고 있기도 합니다. 따라서 이런 출력은 특정 데이터셋에서 새로운 분류기를 훈련하는 데 사용할 수 있습니다.

이 가이드에서 다룰 내용은 다음과 같습니다.

  • image-feature-extraction pipeline 위에 간단한 이미지 유사도 시스템을 구축하는 법을 배웁니다.
  • 모델을 직접 추론(inference)하는 방식으로 동일한 작업을 수행합니다.

image-feature-extraction Pipeline으로 이미지 유사도 계산하기

고양이가 그물 위에 앉아 있는 이미지 두 장이 있습니다. 그중 하나는 생성된(생성형 AI로 만든) 이미지입니다.

from PIL import Image
import requests

img_urls = ["https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png", "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.jpeg"]
image_real = Image.open(requests.get(img_urls[0], stream=True).raw).convert("RGB")
image_gen = Image.open(requests.get(img_urls[1], stream=True).raw).convert("RGB")

pipeline이 어떻게 동작하는지 살펴보겠습니다. 먼저 pipeline을 초기화합니다. 모델을 전달하지 않으면 pipeline은 google/vit-base-patch16-224로 자동 초기화됩니다. 유사도를 계산하려면 pool을 True로 설정해 주세요.

import torch
from transformers import pipeline
from accelerate import Accelerator
# automatically detects the underlying device type (CUDA, CPU, XPU, MPS, etc.)
device = Accelerator().device
pipe = pipeline(task="image-feature-extraction", model="google/vit-base-patch16-384", device=device, pool=True)

pipe로 추론하려면 두 이미지를 모두 전달하세요.

outputs = pipe([image_real, image_gen])

출력에는 두 이미지의 풀링된(pooled) 임베딩이 포함됩니다.

# get the length of a single output
print(len(outputs[0][0]))
# show outputs
print(outputs)

# 768
# [[[-0.03909236937761307, 0.43381670117378235, -0.06913255900144577,

유사도 점수를 얻으려면 이를 유사도 함수에 전달해야 합니다.

from torch.nn.functional import cosine_similarity

similarity_score = cosine_similarity(torch.Tensor(outputs[0]),
                                     torch.Tensor(outputs[1]), dim=1)

print(similarity_score)

# tensor([0.6043])

풀링 전의 마지막 hidden state를 얻으려면 기본값이 False인 pool 매개변수에 값을 전달하지 마세요. 이 hidden state는 모델의 피처를 기반으로 새로운 분류기나 모델을 훈련하는 데 유용합니다.

pipe = pipeline(task="image-feature-extraction", model="google/vit-base-patch16-224", device=device)
outputs = pipe(image_real)

출력은 풀링되지 않았으므로 마지막 hidden state를 얻습니다. 여기서 첫 번째 차원은 배치 크기이고, 마지막 두 차원은 임베딩 형태입니다.

import numpy as np
print(np.array(outputs).shape)
# (1, 197, 768)

AutoModel로 피처와 유사도 얻기

transformers의 AutoModel 클래스를 사용해 피처를 얻을 수도 있습니다. AutoModel은 작업별 헤드 없이 어떤 transformers 모델이든 로드하며, 이를 사용해 피처를 얻을 수 있습니다.

from transformers import AutoImageProcessor, AutoModel

processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224")
model = AutoModel.from_pretrained("google/vit-base-patch16-224").to(device)

추론을 위한 간단한 함수를 작성해 보겠습니다. 먼저 입력을 processor에 전달하고, 그 출력을 model에 전달할 것입니다.

def infer(image):
  inputs = processor(image, return_tensors="pt").to(device)
  outputs = model(**inputs)
  return outputs.pooler_output

이 함수에 이미지들을 직접 전달하면 임베딩을 얻을 수 있습니다.

embed_real = infer(image_real)
embed_gen = infer(image_gen)

임베딩에 대해 다시 유사도를 계산할 수 있습니다.

from torch.nn.functional import cosine_similarity

similarity_score = cosine_similarity(embed_real, embed_gen, dim=1)
print(similarity_score)

# tensor([0.6061], device='cuda:0', grad_fn=<SumBackward1>)

더 알아보기 (Learn more)