My Vision, Computer Vision

이미지와 텍스트 유사도 측정하기, Open AI CLIP(Colab 가능) 본문

WorkPlace

이미지와 텍스트 유사도 측정하기, Open AI CLIP(Colab 가능)

gyuilLim 2024. 3. 27. 20:03
 

GitHub - openai/CLIP: CLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image

CLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image - openai/CLIP

github.com

이 글은 위 Github을 참고하여 작성했습니다.


  • 본 글에서는 Open AI의 CLIP 모델 사용법을 알려드리려고 합니다.
  • CLIP은 이미지와 텍스트를 혼합하여 학습시킨 모델입니다.
  • 이미지와 텍스트를 입력하면 이미지와 텍스트 간의 유사도를 출력해 줍니다.
  • Google Colab T4(15GB) 환경에서 실행가능하며, 약 5GB 정도의 GPU memory를 사용합니다.

1. Install

CLIP 패키지와 그 외 필요한 패키지들을 다운로드합니다.

pip install ftfy regex tqdm
pip install git+https://github.com/openai/CLIP.git​

 

2. CLIP 실행

이 코드를 실행하기 전에 8번 라인의 이미지 경로를 test 하고 싶은 이미지의 경로로 수정해주어야 합니다. 

import torch
import clip
from PIL import Image

device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device) # 원하는 이미지 경로로 수정
text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)

with torch.no_grad():
    image_features = model.encode_image(image)
    text_features = model.encode_text(text)
    
    logits_per_image, logits_per_text = model(image, text)
    probs = logits_per_image.softmax(dim=-1).cpu().numpy()

print("Label probs:", probs)  # prints: [[0.9927937  0.00421068 0.00299572]]

 

 

위 코드는 "CLIP.png" 이미지를 불러와 세 개의 텍스트 "a diagram", "a dog", "a cat" 와의 유사도를 출력해 주는 코드입니다.

3. 코드 설명

import torch
import clip
from PIL import Image
  • torch, clip, PIL Image를 import 해줍니다.

 

device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
  • cuda와 cpu 중 사용할 device를 정해줍니다.(cuda는 gpu를 의미)
  • ViT-B/32를 backbone network로 사용하는 CLIP모델을 불러와 model에 저장해 줍니다.
  • preprocess는 입력 이미지에 대한 전처리 메서드입니다.
  • preprocess는 ToTensor와 Resize(224, 224)로 구성되어 있습니다.

 

image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device)
text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)
  • 'CLIP.png" 이미지를 불러와 preprocess를 해준 다음, 차원을 늘려준 후(batch) device에 할당해 줍니다.
  • 유사도를 알고자 하는 텍스트에 대해 tokenize를 적용해 준 후 device에 할당해 줍니다.
  • tokenize는 clip의 tokenize를 사용하고 77차원으로 임베딩해줍니다.

 

with torch.no_grad():
    image_features = model.encode_image(image)
    text_features = model.encode_text(text)
    
    logits_per_image, logits_per_text = model(image, text)
    probs = logits_per_image.softmax(dim=-1).cpu().numpy()

print("Label probs:", probs)  # prints: [[0.9927937  0.00421068 0.00299572]]
  • imagetext를 각각 512차원으로 encoding 해줍니다. (image : 1 * 512, text : 3 * 512)
  • 모델의 입력값으로 imagetext를 전달해 줍니다.
  • 모델의 출력값은 imagetext에 대한 logits(예측값)입니다.
  • 예측값에 softmax를 적용하여 확률로 만들어준 다음 cpu에 할당하고 numpy로 변환해 줍니다.
  • 최종적으로 모델은 입력 이미지에 대해 입력 텍스트 3개의 유사도를 출력합니다.
728x90