์๋ ํ์ธ์. ์ค๋์ ๊ธฐ๋ณธ์ ์ธ ๋ฉํฐ๋ชจ๋ฌ AI ๋ชจ๋ธ์ธ, CLIP์ ์ฌ์ฉํด ๋ณด๋ ํํ ๋ฆฌ์ผ์ ๊ฐ์ ธ์์ด์!
์ฌ์ค ์์ฆ์ ๋ฅ๋ฌ๋ ํ๋ ์์ํฌ๊ฐ ๋ฐ์ ํด์ ๊ต์ฅํ ์์ฝ๊ฒ AI ๋ชจ๋ธ์ ๋ค๋ค๋ณผ ์ ์๋๋ฐ์. CLIP ๊ณผ ๊ฐ์ ํธ๋์คํฌ๋จธ ๊ธฐ๋ฐ์ ๋ชจ๋ธ๋ ํ๊น ํ์ด์ค API๋ฅผ ์ฌ์ฉํ๋ฉด ๊ต์ฅํ ์ฝ๊ฒ ์ฌ์ฉํด ๋ณผ ์ ์์ด์. ํนํ ํ์ตํ์ง ์๊ณ pre-trained(์ฌ์ ํ์ต๋) ๋ชจ๋ธ์ ์ฌ์ฉํ๋ค๋ฉด ๋๋์ฑ ์ฝ๊ฒ ์ฃ ?
*CLIP : Contrastive Language-Image Pretraining
๊ทธ๋์ ์ค๋์ ์ฝ๋ฉ์ ํ ์ค ๋ชจ๋ฅด๋ ๋น๊ฐ๋ฐ์๋ ์์ฝ๊ฒ ๋ฐ๋ผํ ์ ์๋ ํํ ๋ฆฌ์ผ์ ๋ง๋ค์ด ์๋ต๋๋ค ~~ ๐ค
์ฌ์ค ์ฝ๋๊ฐ ์งง์์ ๋ญ ๋ง๋ค์๋ค๊ณ ํ ์ ์๋ ์์ค๋ ์๋๊ธด ํด์ ใ ใ
CLIP Model
๊ทธ๋๋ ๊ฐ๋จํ๊ฒ ๋ผ๋ CLIP ๋ชจ๋ธ์ด ๋ฌด์์ธ์ง๋ ์์๋ณด๊ณ ๋์ด๊ฐ๋ฉด ์ข๊ฒ ์ฃ ?
- CLIP ๋ชจ๋ธ์ ํ ์คํธ์ ์ด๋ฏธ์ง๋ฅผ ๋์์ ์ดํดํ๋ AI ๋ชจ๋ธ์ด์์.
- OpenAI์์ ๊ฐ๋ฐํ ์ด ๋ชจ๋ธ์ ํ ์คํธ ์ค๋ช ๊ณผ ์ด๋ฏธ์ง๊ฐ ์์ ์ด๋ฃจ๋ ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ์ฌ ํ์ต๋์์ผ๋ฉฐ, ์ด๋ฏธ์ง์ ํ ์คํธ๋ฅผ ์ฐ๊ฒฐํ๋ ์๋ฒ ๋ฉ ๊ณต๊ฐ์ ๋ง๋ค์ด๋ด์ฃ .
- ์ด๋ฅผ ํตํด CLIP์ ์ด๋ฏธ์ง์ ๋ํ ํ ์คํธ ์ค๋ช ์ ์์ฑํ๊ฑฐ๋ ํ ์คํธ ์ค๋ช ์ ๋ง๋ ์ด๋ฏธ์ง๋ฅผ ์ฐพ๋ ์์ ์ ์ํํ ์ ์์ด์!
- ์ฆ, ๋ชจ๋ธ์ ์ด๋ฏธ์ง์ ์ฌ๋ฌ ํ ์คํธ ์ฟผ๋ฆฌ๋ฅผ ํจ๊ป ์ ๋ ฅํ๋ฉด ์ด๋ฏธ์ง์ ๊ฐ์ฅ ์ ์ฌํ ํ ์คํธ ์ฟผ๋ฆฌ๋ฅผ ๋ฐํํด ์ฃผ๋ ๊ฒ์ด์ฃ !
ํํ ๋ฆฌ์ผ
ํํ ๋ฆฌ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ๊ธ ์ฝ๋ฉ(Google Colab) ํ๊ฒฝ์์ ์งํ๋๋๋ฐ์.
๊ตฌ๊ธ ์ฝ๋ฉ์ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ์ Jupyter ๋ ธํธ๋ถ ํ๊ฒฝ์ผ๋ก, ์ฌ์ฉ์๊ฐ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์คํํ ์ ์๋ ํ๋ซํผ์ด์์. ๊ทผ๋ฐ ๋ญ ์ฌ์ค ์ด๊ฒ ์ค์ํ ๊ฑด ์๋๊ณ ... ๋ฌด๋ฃ์ด๊ณ GPU, TPU ๋ฑ์ ์์์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ค์น๊ฐ ํ์์๊ณ ๋์ผํ ํ๊ฒฝ์ ๊ตฌ์ฑํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ํํ ๋ฆฌ์ผ ํ๊ฒฝ์ผ๋ก ์ฌ์ฉํ๋ ค๊ณ ํด์ ใ ใ .
๋น๊ฐ๋ฐ์ ๋ถ๋ค์ ๊ฐ๋ฐํ๊ฒฝ์ ๊ตฌ์ฑํ๋ค๊ฐ ํฌ๊ธฐํ ์๋ ์๊ฑฐ๋ ์... ๊ฐ๋ ๊ฐ๋ฐ์๋ค๋ ๊ฐ๋ฐ ํ๊ฒฝ ์ธํ ํ๋ค๊ฐ ๋ฉํ ๋๊ฐ๊ธฐ๋ ํด์ ใ ใ
ํํ ๋ฆฌ์ผ์ ์๋ ๊นํ ๋งํฌ์์ ์ฝ๋๋ฅผ ๋ณต์ฌํ์ ์ ๊ตฌ๊ธ ์ฝ๋ฉ์์ ์คํํด ๋ณด์๋ฉด ๋ผ์!
ํํ ๋ฆฌ์ผ ์ฝ๋ โก๏ธ CLIP_tutorial
0. Transformers ํจํค์ง ์ค์น
- ์ฐ์ CLIP, KoCLIP ๊ณตํต์ ์ผ๋ก ํ๊น ํ์ด์ค์ transformers ํจํค์ง๋ฅผ ์ค์นํด ์ค์ผ ํด์!
๐ CLIP : ์์ด ๋ฒ์
1. ํจํค์ง ์ํฌํธ ๋ฐ ๋ชจ๋ธ ๋ก๋
- ์ฝ๋์์ ์ฌ์ฉํ ๊ธฐ๋ณธ์ ์ธ ํจํค์ง๋ฅผ ์ํฌํธํ๊ณ (์ฌ์ฉํ ์ฌ๋ฃ๋ค์ ๋ฏธ๋ฆฌ ํ ์ด๋ธ์ ์ฌ๋ ค๋๋ค๊ณ ์๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค์ฉ)
- ํ๊น ํ์ด์ค CLIP ๋ชจ๋ธ์ ๋ถ๋ฌ์ค๋ ๊ณผ์ ์ด์์
2. ์ด๋ฏธ์ง ๋ก๋
- ์น์์ ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ค๋ ๊ณผ์ ์ธ๋ฐ์. ์ฌ์ค ํด๋์ ์ด๋ฏธ์ง๋ฅผ ์ฌ๋ ค์ ๋ถ๋ฌ์ฌ ์๋ ์์ด์.
- ํ์ฌ ํํ ๋ฆฌ์ผ์์๋ ์น url๋ก ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ค๊ณ ์ ๋ถ๋ฌ์์ก๋์ง ํ ๋ฒ ํ์ธํ๋ ์ฝ๋์์.
- ๊ณ ์์ด ๋ ๋ง๋ฆฌ์ ๋ฆฌ๋ชจ์ปจ์ด ๋ณด์ด๋ ๊ตฐ์
3. ํ ์คํธ ์ฟผ๋ฆฌ ์ง์
- ์ด์ ํ ์คํธ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ํ๋ ๋จ๊ณ์ธ๋ฐ์.
- ์ด๋ฏธ์ง์์ ์์๋๋ ํ ์คํธ๋ฅผ ๋ฆฌ์คํธ ํํ๋ก ์ค๋นํ๋ ๊ฑฐ์์.
- ์์ ์์๋ "a photo of a cat", "a photo of a dog" ๋ ๊ฐ์ง๋ง ์์ง๋ง ๋ ๋ง์ด ์ฌ๋ฌ ๋๋ฌผ์ ์ ๋ ฅํด๋ ์ข์์.
- ๋๋ฌผ์ด ์๋๋ผ ์๋์ฐจ(car), ์ฌ๋(human) ๋ฑ๋ ๊ฐ๋ฅํ๊ฒ ์ฃ ?
4. ๋ชจ๋ธ ์ ๋ ฅ ์์ฑ ๋ฐ ์ธํผ๋ฐ์ค + ๊ฒฐ๊ณผ ํ์ธ
- ์ด์ ์ต์ข ์ ์ผ๋ก ์์ ์ค๋นํ ์ด๋ฏธ์ง์ ํ ์คํธ ์ฟผ๋ฆฌ๋ค๋ก ๋ชจ๋ธ ์ ๋ ฅ์ ์์ฑํ๊ณ , ๋ชจ๋ธ์ ์ ๋ ฅํ๋ ๊ณผ์ ์ด์์.
- ๋ชจ๋ธ ์ถ๋ ฅ์ ํ ์ ํํ๋ก ๋์ค๋๋ฐ, confidence score๊ฐ ๊ฐ์ฅ ๋๊ฒ ๋์ค๋ ํ ์คํธ๊ฐ ์ด๋ฏธ์ง์ ๊ฐ์ฅ ์ ์ฌํ ํ ์คํธ๋ผ๊ณ ๋ณด๋ฉด ๋ผ์
- ๋ฌด์จ ๋ง์ธ์ง ์ ๋ชจ๋ฅด์๊ฒ ๋ค๋ฉด, pred_text์ ์ต์ข ์์ธก๊ฐ์ด ๋์ค๊ฒ ์ค์ ํด ๋์๋ต๋๋ค ~!
์์ ์์๋ "a photo of a cat" ์ด๋ผ๋ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค์. ์ด๋ฏธ์ง์ ๊ณ ์์ด๊ฐ ์์ผ๋ ์ ์์ธกํ ๊ฒ์ด์ฃ ? ใ ใ
๐ KoCLIP : ํ๊ธ ๋ฒ์
ํ๊น ํ์ด์ค์๋ CLIP์ ํ๊ธ ๋ฒ์ ์ธ KoCLIP๋ ์ฌ๋ผ๊ฐ ์๋๋ฐ์. ์ด๋ ๋ ํผ์งํ ๋ฆฌ๊ฐ ์กด์ฌํด์ผ๋ง ์ฌ์ฉํ ์ ์์ด์. ํฌ์คํ ํ๋ ํ ์์ ์๋ ๊ณ์ ์ ์ง๊ฐ ๋๊ณ ์์ผ๋, ์๋ง ์ ๋์ํ ๊ฑฐ์์. CLIP๊ณผ ๋ค๋ฅด๊ฒ ํ ์คํธ ์ฟผ๋ฆฌ๋ฅผ ํ๊ธ๋ก ์ค๋ ๋๋ต๋๋ค. ๋๋จธ์ง ๋ถ๋ถ์ ๋์ผํด์!
1. ํจํค์ง ์ํฌํธ ๋ฐ ๋ชจ๋ธ ๋ก๋
2. ์ด๋ฏธ์ง ๋ก๋
3. ํ ์คํธ ์ฟผ๋ฆฌ ์ง์
- ์ฌ๊ธฐ ํ ์คํธ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ํ๋ ๋ถ๋ถ์์ ํ๊ธ๋ก ์ง์ ํ๋ฉด ๋ผ์. ์กฐ๊ธ ๋ ๊ฐ๋จํ์ฃ ?
- ๊ณผ์ผ๋ก ์์๋ฅผ ๋ฐ๊พธ๋ฉด "์ฌ๊ณผ", "๋ฐ๋๋", "ํ ๋งํ " ์ ๊ฐ์ ํ ์คํธ ์ฟผ๋ฆฌ ๋ฆฌ์คํธ๋ฅผ ์ง์ ํ ์๋ ์๊ฒ ์ฃ ?
4. ๋ชจ๋ธ ์ ๋ ฅ ์์ฑ ๋ฐ ์ธํผ๋ฐ์ค + ๊ฒฐ๊ณผ ํ์ธ
- ๊ฒฐ๊ณผ ๋ํ ํ๊ธ๋ก "๊ณ ์์ด ๋ ๋ง๋ฆฌ"๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค์!
Python ํ์ผ ์์
๋ฌผ๋ก py ํ์ด์ฌ ํ์ผ๋ก ๊ตฌ์ฑํ ์์ ๋ ์์ด์. ์๋ ์์ ๋ ํด๋์์ 'dog.png' ๋ผ๋ ๊ฐ์์ง ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์์ ํ ์คํธํด ๋ณด๋ ์์ ์ธ๋ฐ์.
vscode์ ๊ฐ์ IDE์์ ์๋์ ๊ฐ์ ํ์ด์ฌ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธํ์๋ฉด ์กฐ๊ธ๋ ๋ค์ํ๊ฒ ํ์ฉํด ๋ณผ ์ ์์๊ฑฐ์์!!
๋์ ์ฝ๋๋ฅผ ์กฐ๊ธ ๋ ๋ง์ง ์ค ์์์ผ๊ฒ ์ฃ ? ใ ใ
์๋ ๋ ์ฝ๋๋ ๊นํ ์์ ์ ๊ณตํ๊ณ ์์ผ๋ ์ฐธ๊ณ ํด ์ฃผ์ธ์ !
CLIP
from PIL import Image
import torch
from transformers import CLIPProcessor, CLIPModel
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
## ์ด๋ฏธ์ง ๊ฒฝ๋ก ์ง์
image_path = 'dog.png'
image = Image.open(image_path).convert('RGB')
## ํ
์คํธ ์ฟผ๋ฆฌ ์ง์
text_query = ["a photo of a cat", "a photo of a dog"]
inputs = processor(text=text_query, images=image, return_tensors="pt", padding=True)
outputs = model(**inputs)
logits_per_image = outputs.logits_per_image
probs = logits_per_image.softmax(dim=1)
pred_idx = torch.argmax(probs[0]).item()
pred_text = text_query[pred_idx]
print(f'pred : {pred_text}')
KoCLIP
import torch
from PIL import Image
from transformers import AutoModel, AutoProcessor
repo = "Bingsu/clip-vit-large-patch14-ko"
model = AutoModel.from_pretrained(repo)
processor = AutoProcessor.from_pretrained(repo)
## ์ด๋ฏธ์ง ๊ฒฝ๋ก ์ง์
image_path = 'dog.png'
image = Image.open(image_path).convert('RGB')
## ํ
์คํธ ์ฟผ๋ฆฌ ์ง์
text_query = ["๊ณ ์์ด ์ฌ์ง", "๊ฐ์์ง ์ฌ์ง"]
inputs = processor(text=text_query, images=image, return_tensors="pt", padding=True)
with torch.inference_mode():
outputs = model(**inputs)
logits_per_image = outputs.logits_per_image
probs = logits_per_image.softmax(dim=1)
pred_idx = torch.argmax(probs[0])
pred_text = text_query[pred_idx]
print(pred_text)
์ ์ค๋์ CLIP, KoCLIP์ ์คํํด ๋ณด๋ ํํ ๋ฆฌ์ผ์ ๋ค๋ค๋ดค๋๋ฐ์. ์๊ฐ๋ณด๋ค ์ ๋ง ๊ฐ๋จํ๊ฒ AI ๋ชจ๋ธ์ ์ฌ์ฉํด ๋ณผ ์ ์์ฃ ?
์ด๋ฏธ์ง์ ํ ์คํธ ์ฟผ๋ฆฌ๋ง ์์ ํ๋ค๋ฉด ์ฌ๋ฌ๋ถ์ด ์์ ์์ฌ๋ก ๋ชจ๋ธ์ ์ฌ์ฉํด ๋ณผ ์ ์์ผ๋ ์ฌ๋ฌ๋ถ๋ ๋ค์ํ๊ฒ ํ์ฉํด ๋ณด์ธ์!
๊ถ๊ธํ ์ ์ด ์์ผ์๋ฉด ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์ :)