Spaces:
Sleeping
Sleeping
File size: 5,125 Bytes
2720e2f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | # ββ Gradio μ€μΉ ββββββββββββββββββββββββββ
import gradio as gr
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from PIL import Image
from datasets import load_dataset
# ββ ν΄λμ€ μ΄λ¦ κ°μ Έμ€κΈ° ββββββββββββββββββ
dataset = load_dataset("food101", split="train[:1%]")
class_names = dataset.features['label'].names
# ββ λͺ¨λΈ μ μ (λκ°μ΄ λΆμ¬λ£κΈ°) βββββββββββ
class BottleneckBlock(nn.Module):
expansion = 4
def __init__(self, in_channels, mid_channels, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, mid_channels, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(mid_channels)
self.conv2 = nn.Conv2d(mid_channels, mid_channels, kernel_size=3,
stride=stride, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(mid_channels)
self.conv3 = nn.Conv2d(mid_channels, mid_channels * self.expansion,
kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(mid_channels * self.expansion)
self.relu = nn.ReLU(inplace=True)
self.shortcut = nn.Sequential()
if stride != 1 or in_channels != mid_channels * self.expansion:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, mid_channels * self.expansion,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(mid_channels * self.expansion)
)
def forward(self, x):
identity = x
out = self.relu(self.bn1(self.conv1(x)))
out = self.relu(self.bn2(self.conv2(out)))
out = self.bn3(self.conv3(out))
out += self.shortcut(identity)
out = self.relu(out)
return out
class ResNet50(nn.Module):
def __init__(self, num_classes=101):
super().__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.relu = nn.ReLU(inplace=True)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self.layer1 = self._make_layer( 64, 64, blocks=3, stride=1)
self.layer2 = self._make_layer(256, 128, blocks=4, stride=2)
self.layer3 = self._make_layer(512, 256, blocks=6, stride=2)
self.layer4 = self._make_layer(1024, 512, blocks=3, stride=2)
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
self.fc = nn.Linear(2048, num_classes)
def _make_layer(self, in_channels, mid_channels, blocks, stride):
layers = [BottleneckBlock(in_channels, mid_channels, stride=stride)]
for _ in range(1, blocks):
layers.append(BottleneckBlock(mid_channels * 4, mid_channels))
return nn.Sequential(*layers)
def forward(self, x):
x = self.maxpool(self.relu(self.bn1(self.conv1(x))))
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x
# ββ λͺ¨λΈ λΆλ¬μ€κΈ° βββββββββββββββββββββββββ
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = ResNet50(num_classes=101)
model.load_state_dict(
torch.load('resnet50_food101.pth', map_location=device)
)
model = model.to(device)
model.eval()
# ββ μ μ²λ¦¬ ββββββββββββββββββββββββββββββββ
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
# ββ μμΈ‘ ν¨μ βββββββββββββββββββββββββββββ
def predict(image):
# PIL μ΄λ―Έμ§ β ν
μ λ³ν
img_tensor = transform(image).unsqueeze(0).to(device)
# unsqueeze(0) = (3,224,224) β (1,3,224,224) λ°°μΉ μ°¨μ μΆκ°
with torch.no_grad():
output = model(img_tensor)
probs = torch.softmax(output, dim=1) # μ μ β νλ₯
top5 = probs.topk(5) # μμ 5κ°
# κ²°κ³Ό λμ
λλ¦¬λ‘ λ°ν
result = {}
for i in range(5):
label = class_names[top5.indices[0][i].item()]
prob = top5.values[0][i].item()
result[label] = prob
return result
# ββ Gradio μΈν°νμ΄μ€ ββββββββββββββββββββββ
demo = gr.Interface(
fn=predict, # μμΈ‘ ν¨μ
inputs=gr.Image(type="pil"), # μ
λ ₯: μ΄λ―Έμ§
outputs=gr.Label(num_top_classes=5), # μΆλ ₯: μμ 5κ° ν΄λμ€
title="π Food-101 λΆλ₯κΈ°",
description="μμ μ¬μ§μ μ¬λ¦¬λ©΄ μ΄λ€ μμμΈμ§ λ§μΆ°μ€μ! (101κ°μ§ μμ λΆλ₯)",
examples=[], # μμ μ΄λ―Έμ§ (μμΌλ©΄ μΆκ°)
)
demo.launch() |