| # ๐ฝ๏ธ ์์ ์ด๋ฏธ์ง ๋ถ๋ฅ ํ๋ก์ ํธ ๊ฐ์ด๋ |
|
|
| ## ๐ ํ์ผ ๊ตฌ์ฑ |
|
|
| | ํ์ผ | ์ญํ | ํ์? | |
| |------|------|-------| |
| | `app.py` | Gradio ์น ๋ฐ๋ชจ | โ
Space ํ์ | |
| | `README.md` | Space ์ค์ (YAML) | โ
Space ํ์ | |
| | `requirements.txt` | ์์กด์ฑ | โ
Space ํ์ | |
| | `configuration_myresnet.py` | MyResNet Config | ์ต์
B์์๋ง ํ์ | |
| | `modeling_myresnet.py` | MyResNet ๋ชจ๋ธ | ์ต์
B์์๋ง ํ์ | |
| | `train_food.py` | Food-101 ํ์ต ์คํฌ๋ฆฝํธ | ๋ก์ปฌ ํ์ต์ฉ | |
|
|
| ## ๐ฏ ๋ ๊ฐ์ง ์ฌ์ฉ ์๋๋ฆฌ์ค |
|
|
| ### ์๋๋ฆฌ์ค 1: ํ์ต ์์ด ๋ฐ๋ก ๋ฐ๋ชจ ์คํ (์ถ์ฒ) โญ |
|
|
| `app.py`๋ ๊ธฐ๋ณธ์ ์ผ๋ก **ํ๊น
ํ์ด์ค ํ๋ธ์ ๊ณต๊ฐ ๋ชจ๋ธ `nateraw/food`**๋ฅผ ์ฌ์ฉํฉ๋๋ค. |
| ์ด ๋ชจ๋ธ์ ์ด๋ฏธ Food-101์์ ํ์ต๋์ด ์ฝ 90% ์ ํ๋๋ฅผ ๋ณด์ฌ์. |
|
|
| **Space ์
๋ก๋ ํ์ผ (3๊ฐ๋ฉด ์ถฉ๋ถ):** |
| 1. `app.py` |
| 2. `README.md` |
| 3. `requirements.txt` |
|
|
| ์ฆ, ์ด ์๋๋ฆฌ์ค์์๋ `configuration_myresnet.py`, `modeling_myresnet.py`๋ฅผ |
| Space์ ์ฌ๋ฆด ํ์๊ฐ ์์ต๋๋ค! |
|
|
| ### ์๋๋ฆฌ์ค 2: ์์ฒด ํ์ตํ MyResNet ์ฌ์ฉ |
|
|
| ์ง์ ResNet์ ํ์ต์์ผ์ ๊ทธ ๋ชจ๋ธ๋ก ๋ฐ๋ชจ๋ฅผ ๋๋ฆฌ๊ณ ์ถ๋ค๋ฉด: |
|
|
| **Step 1: ๋ก์ปฌ์์ ํ์ต** |
| ```bash |
| pip install torch torchvision transformers datasets accelerate |
| python train_food.py |
| ``` |
| โ `./my-resnet18-food101/` ํด๋์ ํ์ต๋ ๋ชจ๋ธ ์ ์ฅ๋จ |
|
|
| **Step 2: ๋ชจ๋ธ ํ๋ธ์ ์
๋ก๋** |
| ```bash |
| huggingface-cli login |
| |
| python -c " |
| from modeling_myresnet import MyResNetForImageClassification |
| from configuration_myresnet import MyResNetConfig |
| |
| MyResNetConfig.register_for_auto_class() |
| MyResNetForImageClassification.register_for_auto_class('AutoModelForImageClassification') |
| |
| model = MyResNetForImageClassification.from_pretrained('./my-resnet18-food101') |
| model.push_to_hub('your-username/my-resnet18-food101') |
| " |
| ``` |
|
|
| **Step 3: Space `app.py`์์ ์ต์
์ ํ** |
| ```python |
| # ์ต์
A ๋ถ๋ถ์ ์ฃผ์ ์ฒ๋ฆฌ |
| # from transformers import AutoImageProcessor, AutoModelForImageClassification |
| # ... |
| |
| # ์ต์
B ์ฃผ์ ํด์ |
| from configuration_myresnet import MyResNetConfig |
| from modeling_myresnet import MyResNetForImageClassification |
| |
| MODEL_ID = "your-username/my-resnet18-food101" |
| model = MyResNetForImageClassification.from_pretrained(MODEL_ID) |
| model.eval() |
| device = "cuda" if torch.cuda.is_available() else "cpu" |
| model = model.to(device) |
| id2label = model.config.id2label |
| ``` |
|
|
| **Step 4: ์ ์ฒ๋ฆฌ ํจ์๋ ์๋ ๋ฒ์ ์ผ๋ก ๋ณ๊ฒฝ** |
| ```python |
| from torchvision.transforms import Compose, Resize, ToTensor, Normalize |
| |
| _transform = Compose([ |
| Resize((224, 224)), |
| ToTensor(), |
| Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), |
| ]) |
| |
| def preprocess(image): |
| return _transform(image.convert("RGB")).unsqueeze(0).to(device) |
| ``` |
|
|
| ## ๐ Food-101์ 101๊ฐ ํด๋์ค |
|
|
| ``` |
| apple_pie, baby_back_ribs, baklava, beef_carpaccio, beef_tartare, |
| beet_salad, beignets, bibimbap, bread_pudding, breakfast_burrito, |
| bruschetta, caesar_salad, cannoli, caprese_salad, carrot_cake, |
| ceviche, cheesecake, cheese_plate, chicken_curry, chicken_quesadilla, |
| chicken_wings, chocolate_cake, chocolate_mousse, churros, clam_chowder, |
| club_sandwich, crab_cakes, creme_brulee, croque_madame, cup_cakes, |
| deviled_eggs, donuts, dumplings, edamame, eggs_benedict, |
| escargots, falafel, filet_mignon, fish_and_chips, foie_gras, |
| french_fries, french_onion_soup, french_toast, fried_calamari, fried_rice, |
| frozen_yogurt, garlic_bread, gnocchi, greek_salad, grilled_cheese_sandwich, |
| grilled_salmon, guacamole, gyoza, hamburger, hot_and_sour_soup, |
| hot_dog, huevos_rancheros, hummus, ice_cream, lasagna, |
| lobster_bisque, lobster_roll_sandwich, macaroni_and_cheese, macarons, miso_soup, |
| mussels, nachos, omelette, onion_rings, oysters, |
| pad_thai, paella, pancakes, panna_cotta, peking_duck, |
| pho, pizza, pork_chop, poutine, prime_rib, |
| pulled_pork_sandwich, ramen, ravioli, red_velvet_cake, risotto, |
| samosa, sashimi, scallops, seaweed_salad, shrimp_and_grits, |
| spaghetti_bolognese, spaghetti_carbonara, spring_rolls, steak, strawberry_shortcake, |
| sushi, tacos, takoyaki, tiramisu, tuna_tartare, waffles |
| ``` |
|
|
| **์ฌ๋ฏธ์๋ ์ฌ์ค**: ๐ฅ **bibimbap (๋น๋น๋ฐฅ)**, ๐ฃ **sushi**, ๐ฅ **gyoza (๋ง๋)**, |
| ๐ **ramen**, ๐ฎ **tacos** ๋ฑ ํ์/์ผ์/์ค์/๋ฉ์์นธ ๋ฑ ๋ค์ํ ๊ตญ๊ฐ ์๋ฆฌ๊ฐ ํฌํจ๋์ด ์์ด์! |
|
|
| ## ๐ก ํ์ต ์๊ฐ/์ ํ๋ ์ฐธ๊ณ |
|
|
| | ๋ฐฉ์ | ์๊ฐ (GPU 1์ฅ) | ์ ํ๋ | |
| |------|---------------|--------| |
| | Scratch ํ์ต (30 epochs) | ์ฝ 6-10์๊ฐ | ์ฝ 60-70% | |
| | Pretrained + Fine-tuning (10 epochs) | ์ฝ 2-4์๊ฐ | ์ฝ 80-85% | |
| | ๊ณต๊ฐ ๋ชจ๋ธ `nateraw/food` ์ฌ์ฉ | 0 | ~90% | |
|
|
| **์ด๋ณด์ ์ถ์ฒ**: ์๋๋ฆฌ์ค 1 (๊ณต๊ฐ ๋ชจ๋ธ ์ฌ์ฉ)๋ก ๋จผ์ Space๋ฅผ ๋์๋ณด๊ณ , |
| ๋์ค์ ๊ด์ฌ ์์ผ๋ฉด ์๋๋ฆฌ์ค 2๋ก ์ง์ ํ์ตํด๋ณด์ธ์! |
|
|
| ## ๐ ์์ฃผ ๊ฒช๋ ๋ฌธ์ |
|
|
| ### 1. ํ์ต ์ OutOfMemory |
| ```python |
| per_device_train_batch_size=64 # 32 ๋๋ 16์ผ๋ก ์ค์ด๊ธฐ |
| gradient_accumulation_steps=2 # ์ด๊ฑธ ๋์ ์ถ๊ฐ |
| ``` |
|
|
| ### 2. Food-101 ๋ค์ด๋ก๋๊ฐ ๋๋ฆผ |
| - Food-101์ ์ฝ 5GB์
๋๋ค |
| - ์ฒซ ๋ค์ด๋ก๋ ํ์๋ `~/.cache/huggingface/datasets/`์ ์บ์๋จ |
| - ๋ค์ด๋ก๋๋ ํ ๋ฒ๋ง ํ๋ฉด ๋ฉ๋๋ค |
|
|
| ### 3. "KeyError: '0'" ์๋ฌ |
| - CIFAR ๋ฒ์ ๊ณผ ๋์ผํ ๋ฌธ์ . `id2label[str(i)]` โ `id2label[i]`๋ก ์์ |
| - ์ด ํ๋ก์ ํธ์ `app.py`๋ ์ด๋ฏธ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ด ์์ |
|
|