ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AI/Vision] 같은 YOLO라도 결과가 천지차이? 제로샷 vs 퓨샷 실전 비교 (Python)
    개발/AI 2026. 1. 20. 11:51
    반응형

    안녕하세요! 요즘 AI 비전 프로젝트로 제로샷과 퓨샷 연구를 진행 중인 개발자입니다.

    오늘은 가장 대중적인 YOLOv8 모델을 예시로, 모델을 재학습(Fine-tuning)시키지 않고도 우리가 원하는 결과를 얻어내는 두 가지 전략을 파이썬 코드로 비교해 보겠습니다.

     

     

     

    1. 제로샷(Zero-Shot): "배운 것만 찾아라"

    제로샷은 모델이 이미 학습한 데이터셋(COCO 등)의 지식만 활용하는 방식입니다. 별도의 힌트 없이 이미지 한 장 던져주고 "뭐가 있는지 찾아봐"라고 시키는 거죠.

    [코드 예시: 표준 YOLOv8 제로샷]

    from ultralytics import YOLO
    import cv2
    
    # 1. 사전 학습된 YOLOv8 모델 로드
    model = YOLO('yolov8n.pt') 
    
    # 2. 이미지 추론 실행 (제로샷!)
    # 모델은 이미 'dog', 'person' 등의 클래스를 알고 있습니다.
    results = model.predict(source='street_dog.jpg', conf=0.25)
    
    # 3. 결과 확인
    for result in results:
        boxes = result.boxes
        for box in boxes:
            label = result.names[int(box.cls)]
            confidence = box.conf[0]
            print(f"Detected: {label} with {confidence:.2f} accuracy")
    
    # 결과 이미지 저장/보기
    result.show()

     

    • 특징: 추가 설정 없이 즉시 사용 가능합니다.
    • 한계: 모델이 '강아지(dog)'는 알지만, 그게 '내 강아지'인지 '특정 품종'인지는 구분하지 못합니다.

     

    2. 퓨샷(Few-Shot): "이 사진들이랑 비슷한 것만 찾아라"

    퓨샷은 탐지하고 싶은 대상의 예시 사진(Support Set)을 몇 장 보여주고, 그 특징을 기반으로 대상을 찾는 방식입니다. 여기서는 YOLO로 객체를 먼저 따낸 뒤, **Cosine Similarity(코사인 유사도)**를 이용해 내가 원하는 대상인지 한 번 더 걸러내는 방식을 예시로 들겠습니다.

    [코드 예시: 특징 비교를 통한 퓨샷 감지]

    import cv2
    import torch
    import numpy as np
    from ultralytics import YOLO
    from scipy.spatial.distance import cosine
    
    # 1. 모델 및 레퍼런스(예시) 이미지 로드
    model = YOLO('yolov8n.pt')
    reference_img = cv2.imread('my_golden_retriever_ref.jpg') # 내가 찾는 타겟의 사진
    
    # 2. 예시 사진에서 특징(Feature Vector) 추출 (간략화된 예시)
    # 실무에서는 임베딩 추출용 모델(ResNet 등)을 별도로 사용하기도 합니다.
    def get_features(img):
        # 여기서는 개념 설명을 위해 모델의 마지막 레이어 출력 등을 가정합니다.
        res = model.predict(img, embed=[10, 11])[0] # 특정 레이어 임베딩 추출
        return res.cpu().numpy()
    
    target_feature = get_features(reference_img)
    
    # 3. 실제 이미지에서 객체 탐지
    target_img = cv2.imread('dog_park.jpg')
    detections = model.predict(target_img, classes=[16]) # 'dog' 클래스만 탐지
    
    # 4. 퓨샷 필터링: 감지된 강아지 중 내 강아지와 유사한 녀석만 선별
    for box in detections[0].boxes:
        x1, y1, x2, y2 = map(int, box.xyxy[0])
        cropped_dog = target_img[y1:y2, x1:x2]
        
        # 감지된 강아지의 특징 추출
        detected_feature = get_features(cropped_dog)
        
        # 내 강아지 사진(Few-shot 예시)과 유사도 비교
        similarity = 1 - cosine(target_feature.flatten(), detected_feature.flatten())
        
        if similarity > 0.85: # 유사도가 85% 이상일 때만!
            print(f"내 강아지 발견! 유사도: {similarity:.2f}")
            cv2.rectangle(target_img, (x1, y1), (x2, y2), (0, 255, 0), 2)

     

     

    [연구 Deep Dive] PCB 기판 부품 탐지, Zero-Shot으로 어디까지 가능할까?

    최근 저는 실제 연구 요청을 받아 PCB(인쇄 회로 기판)의 유사도를 확인하고, 그 위에 박혀 있는 수많은 부품(커패시터, 저항, IC, LED, 커넥터 등)의 종류를 자동으로 판별하는 프로젝트를 진행하고 있습니다.

    보통 이런 산업용 데이터는 라벨링된 데이터를 구하기가 하늘의 별 따기죠. 그래서 제가 선택한 전략이 바로 Florence-2 모델을 활용한 Zero-Shot / Few-Shot 접근법입니다.

     

    1. 왜 Florence-2인가?

    Microsoft에서 공개한 Florence-2는 아주 작은 크기의 모델임에도 불구하고, 텍스트 프롬프트만으로 이미지 속 객체를 찾아내는 성능이 무시무시합니다. 특히 우리가 흔히 쓰는 YOLO는 "강아지, 차" 같은 일반 객체에 강하지만, Florence-2는 "커패시터 찾아줘" 같은 구체적인 지시를 찰떡같이 알아듣거든요.

     

    2. 실전 파이썬 코드 (Zero-Shot Detection)

    Hugging Face의 transformers 라이브러리를 사용해 PCB 부품을 찾는 핵심 로직입니다.

    from transformers import AutoProcessor, AutoModelForCausalLM
    from PIL import Image
    import torch
    
    # 1. 모델 및 프로세서 로드
    model_id = "microsoft/Florence-2-large"
    model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True).eval().cuda()
    processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
    
    # 2. 분석할 PCB 이미지와 찾고 싶은 부품 리스트(Target)
    image = Image.open("pcb_sample.jpg")
    # 우리가 찾고 싶은 부품들을 텍스트로 정의합니다.
    target_list = "capacitors, resistors, integrated circuits, leds, connectors"
    
    # 3. 제로샷 탐지 실행 (<CAPTION_TO_PHRASE_GROUNDING> 태스크 활용)
    prompt = f"<CAPTION_TO_PHRASE_GROUNDING>{target_list}"
    inputs = processor(text=prompt, images=image, return_tensors="pt").to("cuda")
    
    with torch.no_grad():
        generated_ids = model.generate(
            input_ids=inputs["input_ids"],
            pixel_values=inputs["pixel_values"],
            max_new_tokens=1024,
            early_stopping=False,
            do_sample=False,
            num_beams=3,
        )
    
    # 4. 결과 디코딩 및 파싱
    generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    results = processor.post_process_generation(generated_text, task="<CAPTION_TO_PHRASE_GROUNDING>", image_size=(image.width, image.height))
    
    print(results) # 각 부품의 위치(Bbox)와 라벨이 출력됩니다.

     

    3. 연구 중 마주친 현실적인 고민들

    • 해상도 문제: PCB 기판은 아주 작은 부품이 밀집되어 있어, 이미지를 한 번에 넣으면 인식이 잘 안 됩니다. 그래서 이미지를 일정한 크기로 잘라서 분석하는 Tiling(타일링) 기법을 연구 중입니다.
    • 유사도 판단: 단순히 부품을 찾는 걸 넘어, "A 기판과 B 기판이 얼마나 비슷한가?"를 판단하기 위해 추출된 부품들의 위치 정보와 종류를 그래프 데이터로 변환해 비교하는 시도를 하고 있습니다.

     

    개발자 연구 노트: 왜 이 구분이 중요할까요?

    제가 연구하면서 느낀 점은, 현장의 데이터는 우리가 가진 사전 학습 모델(COCO 등)보다 훨씬 다양하다는 것입니다.

    • 제로샷은 범용적인 객체 탐지에 훌륭하지만, 특정 도메인(예: 우리 공장의 특정 불량 부품, 특정 품종의 동물 등)에서는 한계가 명확합니다.
    • 퓨샷은 모델을 매번 새로 학습(Train)시키지 않아도, 몇 장의 사진만으로 타겟을 바꿀 수 있는 엄청난 유연성을 제공합니다.

    결국 "학습 비용을 줄이면서 정확도를 높이는 효율성" 싸움이 이 연구의 핵심인 것 같습니다.

     

     

    AI 개발은 이론도 중요하지만, 이렇게 실제 산업 현장의 문제를 해결해 나가는 과정이 참 매력적인 것 같습니다. 혹시 저처럼 PCB나 정밀 부품 탐지 쪽에 관심 있는 분들이 계신다면 댓글로 아이디어 나눠주세요!

    다음 포스팅에서는 이 데이터들을 활용해 어떻게 Few-Shot으로 정확도를 더 끌어올렸는지 공유해 보겠습니다.

     

    반응형
Designed by Tistory.