| import torch |
| from torchvision.models import efficientnet_b0, EfficientNet_B0_Weights |
| import torchvision.transforms as transforms |
| from PIL import Image |
| import torch.nn.functional as F |
| import json |
| import os |
| import sys |
|
|
| |
| |
| |
| CLASS_MAP_FILENAME = 'labels_map.txt' |
| class_name_map = None |
|
|
| |
| try: |
| if not os.path.exists(CLASS_MAP_FILENAME): |
| |
| raise FileNotFoundError(f"[์ค๋ฅ] ํด๋์ค ์ด๋ฆ ํ์ผ('{CLASS_MAP_FILENAME}')์ ์ฐพ์ ์ ์์ต๋๋ค. API ์๋ฒ๋ฅผ ์์ํ ์ ์์ต๋๋ค.") |
|
|
| with open(CLASS_MAP_FILENAME, 'r') as f: |
| class_map_json = json.load(f) |
|
|
| |
| |
| |
| labels_list = [] |
| for k, v in class_map_json.items(): |
| if k.isdigit() and 0 <= int(k) < 1000: |
| if isinstance(v, list) and len(v) > 1: |
| labels_list.append(v[1]) |
| elif isinstance(v, str): |
| labels_list.append(v) |
| else: |
| |
| labels_list.append(f"Unknown Class Index {k}") |
| |
| |
| |
| class_name_map = {i: name for i, name in enumerate(labels_list)} |
| |
| |
| if len(class_name_map) != 1000: |
| print(f"[๊ฒฝ๊ณ ] ๋ก๋๋ ํด๋์ค ์: {len(class_name_map)}๊ฐ. ImageNet (1000๊ฐ)๊ณผ ๋ค๋ฆ
๋๋ค. ํ์ธํด ์ฃผ์ธ์.") |
|
|
| print(f"ImageNet ํด๋์ค ๋งต ๋ก๋ ์ฑ๊ณต. (์ด {len(class_name_map)}๊ฐ)") |
| |
| except FileNotFoundError as e: |
| |
| raise e |
| except Exception as e: |
| |
| print(f"[์ค๋ฅ] ํด๋์ค ๋งต ๋ก๋ ์ค ์๊ธฐ์น ์์ ์ค๋ฅ ๋ฐ์: {e}") |
| class_name_map = None |
| |
| raise RuntimeError(f"ํด๋์ค ๋งต ๋ก๋ ์ค๋ฅ: {e}") |
|
|
| |
| |
| |
|
|
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
|
|
| |
| |
| try: |
| |
| weights = EfficientNet_B0_Weights.DEFAULT |
| model = efficientnet_b0(weights=weights).to(device).eval() |
| preprocess = weights.transforms() |
| print("EfficientNetB0 ๋ชจ๋ธ ๋ฐ ์ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ ๋ก๋ ์ฑ๊ณต.") |
| except Exception as e: |
| print(f"[์ค๋ฅ] EfficientNetB0 ๋ชจ๋ธ ๋ก๋ ์ค ์ค๋ฅ ๋ฐ์: {e}") |
| |
| model = None |
| preprocess = None |
| raise RuntimeError(f"๋ชจ๋ธ ๋ก๋ ์ค๋ฅ: {e}") |
|
|
|
|
| |
| |
| |
|
|
| def classify_image_pil(img: Image.Image) -> list: |
| """ |
| ์ฃผ์ด์ง PIL Image ๊ฐ์ฒด๋ฅผ EfficientNetB0 ๋ชจ๋ธ๋ก ๋ถ๋ฅํ๊ณ |
| Top-5 ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์คํธ๋ก ๋ฐํํฉ๋๋ค. |
| """ |
| if class_name_map is None or not model: |
| raise RuntimeError("๋ชจ๋ธ ๋๋ ํด๋์ค ๋งต์ด ์์ง ๋ก๋๋์ง ์์์ต๋๋ค.") |
|
|
| try: |
| |
| img = img.convert('RGB') |
| input_tensor = preprocess(img) |
| input_batch = input_tensor.unsqueeze(0).to(device) |
|
|
| |
| with torch.no_grad(): |
| output = model(input_batch) |
|
|
| |
| probabilities = F.softmax(output[0], dim=0) |
| |
| top_prob, top_catid = torch.topk(probabilities, 5) |
|
|
| results = [] |
| for i in range(top_prob.size(0)): |
| idx = top_catid[i].item() |
| |
| |
| class_name = class_name_map.get(idx, f"์ ์ ์๋ ํด๋์ค (ID: {idx})") |
| |
| results.append({ |
| "rank": i + 1, |
| "class_name": class_name, |
| "class_index": idx, |
| "probability": top_prob[i].item() |
| }) |
| |
| return results |
|
|
| except Exception as e: |
| |
| raise RuntimeError(f"์ด๋ฏธ์ง ๋ถ๋ฅ ์ค PyTorch/CUDA ์ค๋ฅ ๋ฐ์: {e}") |
|
|