Spaces:
Sleeping
Sleeping
Commit
·
90ecf2e
1
Parent(s):
57a938e
Upload 6 files
Browse files- app.py +10 -10
- class_names.txt +32 -101
- model.py +53 -20
- model_1.pth +3 -0
app.py
CHANGED
@@ -3,7 +3,7 @@ import gradio as gr
|
|
3 |
import os
|
4 |
import torch
|
5 |
|
6 |
-
from model import
|
7 |
from timeit import default_timer as timer
|
8 |
from typing import Tuple, Dict
|
9 |
|
@@ -14,14 +14,14 @@ with open("class_names.txt", "r") as f: # reading them in from class_names.txt
|
|
14 |
### 2. Model and transforms preparation ###
|
15 |
|
16 |
# Create model
|
17 |
-
|
18 |
-
num_classes=
|
19 |
)
|
20 |
|
21 |
|
22 |
-
|
23 |
torch.load(
|
24 |
-
f="
|
25 |
map_location=torch.device("cpu"), # load to CPU
|
26 |
)
|
27 |
)
|
@@ -38,13 +38,13 @@ def predict(img) -> Tuple[Dict, float]:
|
|
38 |
start_time = timer()
|
39 |
|
40 |
# Transform the target image and add a batch dimension
|
41 |
-
img =
|
42 |
|
43 |
# Put model into evaluation mode and turn on inference mode
|
44 |
-
|
45 |
with torch.inference_mode():
|
46 |
# Pass the transformed image through the model and turn the prediction logits into prediction probabilities
|
47 |
-
pred_probs = torch.softmax(
|
48 |
|
49 |
# Create a prediction label and prediction probability dictionary for each prediction class (this is the required format for Gradio's output parameter)
|
50 |
pred_labels_and_probs = {class_names[i]: float(pred_probs[0][i]) for i in range(len(class_names))}
|
@@ -58,8 +58,8 @@ def predict(img) -> Tuple[Dict, float]:
|
|
58 |
### 4. Gradio app ###
|
59 |
|
60 |
# Create title, description and article strings
|
61 |
-
title = "
|
62 |
-
description = "A
|
63 |
article = ""
|
64 |
|
65 |
# Create examples list from "examples/" directory
|
|
|
3 |
import os
|
4 |
import torch
|
5 |
|
6 |
+
from model import create_model
|
7 |
from timeit import default_timer as timer
|
8 |
from typing import Tuple, Dict
|
9 |
|
|
|
14 |
### 2. Model and transforms preparation ###
|
15 |
|
16 |
# Create model
|
17 |
+
model_created, model_transforms = create_model(
|
18 |
+
num_classes=len(class_names),
|
19 |
)
|
20 |
|
21 |
|
22 |
+
model_created.load_state_dict(
|
23 |
torch.load(
|
24 |
+
f="model_1.pth",
|
25 |
map_location=torch.device("cpu"), # load to CPU
|
26 |
)
|
27 |
)
|
|
|
38 |
start_time = timer()
|
39 |
|
40 |
# Transform the target image and add a batch dimension
|
41 |
+
img = model_transforms(img).unsqueeze(0)
|
42 |
|
43 |
# Put model into evaluation mode and turn on inference mode
|
44 |
+
model_created.eval()
|
45 |
with torch.inference_mode():
|
46 |
# Pass the transformed image through the model and turn the prediction logits into prediction probabilities
|
47 |
+
pred_probs = torch.softmax(model_created(img), dim=1)
|
48 |
|
49 |
# Create a prediction label and prediction probability dictionary for each prediction class (this is the required format for Gradio's output parameter)
|
50 |
pred_labels_and_probs = {class_names[i]: float(pred_probs[0][i]) for i in range(len(class_names))}
|
|
|
58 |
### 4. Gradio app ###
|
59 |
|
60 |
# Create title, description and article strings
|
61 |
+
title = "World Puzzle Solver"
|
62 |
+
description = "A World Puzzle Solver app that uses a PyTorch model to predict the letters in a target image."
|
63 |
article = ""
|
64 |
|
65 |
# Create examples list from "examples/" directory
|
class_names.txt
CHANGED
@@ -1,101 +1,32 @@
|
|
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 |
-
dumplings
|
34 |
-
edamame
|
35 |
-
eggs_benedict
|
36 |
-
escargots
|
37 |
-
falafel
|
38 |
-
filet_mignon
|
39 |
-
fish_and_chips
|
40 |
-
foie_gras
|
41 |
-
french_fries
|
42 |
-
french_onion_soup
|
43 |
-
french_toast
|
44 |
-
fried_calamari
|
45 |
-
fried_rice
|
46 |
-
frozen_yogurt
|
47 |
-
garlic_bread
|
48 |
-
gnocchi
|
49 |
-
greek_salad
|
50 |
-
grilled_cheese_sandwich
|
51 |
-
grilled_salmon
|
52 |
-
guacamole
|
53 |
-
gyoza
|
54 |
-
hamburger
|
55 |
-
hot_and_sour_soup
|
56 |
-
hot_dog
|
57 |
-
huevos_rancheros
|
58 |
-
hummus
|
59 |
-
ice_cream
|
60 |
-
lasagna
|
61 |
-
lobster_bisque
|
62 |
-
lobster_roll_sandwich
|
63 |
-
macaroni_and_cheese
|
64 |
-
macarons
|
65 |
-
miso_soup
|
66 |
-
mussels
|
67 |
-
nachos
|
68 |
-
omelette
|
69 |
-
onion_rings
|
70 |
-
oysters
|
71 |
-
pad_thai
|
72 |
-
paella
|
73 |
-
pancakes
|
74 |
-
panna_cotta
|
75 |
-
peking_duck
|
76 |
-
pho
|
77 |
-
pizza
|
78 |
-
pork_chop
|
79 |
-
poutine
|
80 |
-
prime_rib
|
81 |
-
pulled_pork_sandwich
|
82 |
-
ramen
|
83 |
-
ravioli
|
84 |
-
red_velvet_cake
|
85 |
-
risotto
|
86 |
-
samosa
|
87 |
-
sashimi
|
88 |
-
scallops
|
89 |
-
seaweed_salad
|
90 |
-
shrimp_and_grits
|
91 |
-
spaghetti_bolognese
|
92 |
-
spaghetti_carbonara
|
93 |
-
spring_rolls
|
94 |
-
steak
|
95 |
-
strawberry_shortcake
|
96 |
-
sushi
|
97 |
-
tacos
|
98 |
-
takoyaki
|
99 |
-
tiramisu
|
100 |
-
tuna_tartare
|
101 |
-
waffles
|
|
|
1 |
+
A
|
2 |
+
B
|
3 |
+
C
|
4 |
+
D
|
5 |
+
E
|
6 |
+
F
|
7 |
+
G
|
8 |
+
H
|
9 |
+
I
|
10 |
+
J
|
11 |
+
K
|
12 |
+
L
|
13 |
+
M
|
14 |
+
N
|
15 |
+
O
|
16 |
+
P
|
17 |
+
Q
|
18 |
+
R
|
19 |
+
S
|
20 |
+
T
|
21 |
+
U
|
22 |
+
V
|
23 |
+
W
|
24 |
+
X
|
25 |
+
Y
|
26 |
+
Z
|
27 |
+
Á
|
28 |
+
É
|
29 |
+
Í
|
30 |
+
Ñ
|
31 |
+
Ó
|
32 |
+
Ú
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model.py
CHANGED
@@ -1,34 +1,67 @@
|
|
1 |
import torch
|
2 |
import torchvision
|
3 |
-
|
4 |
from torch import nn
|
5 |
|
6 |
|
7 |
-
def
|
8 |
-
seed:int=42):
|
9 |
-
"""Creates
|
10 |
|
11 |
Args:
|
12 |
-
num_classes (int, optional): number of classes in the classifier head.
|
13 |
-
Defaults to
|
14 |
seed (int, optional): random seed value. Defaults to 42.
|
15 |
|
16 |
Returns:
|
17 |
-
model (torch.nn.Module): vit feature extractor model.
|
18 |
transforms (torchvision.transforms): vit image transforms.
|
19 |
"""
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
1 |
import torch
|
2 |
import torchvision
|
|
|
3 |
from torch import nn
|
4 |
|
5 |
|
6 |
+
def create_model(num_classes: int = 32,
|
7 |
+
seed: int = 42):
|
8 |
+
"""Creates a feature extractor model and transforms.
|
9 |
|
10 |
Args:
|
11 |
+
num_classes (int, optional): number of classes in the classifier head.
|
12 |
+
Defaults to 32.
|
13 |
seed (int, optional): random seed value. Defaults to 42.
|
14 |
|
15 |
Returns:
|
16 |
+
model (torch.nn.Module): vit feature extractor model.
|
17 |
transforms (torchvision.transforms): vit image transforms.
|
18 |
"""
|
19 |
+
IMG_SIZE = 28
|
20 |
+
transforms = transforms.Compose([
|
21 |
+
transforms.Resize((IMG_SIZE, IMG_SIZE)),
|
22 |
+
transforms.Grayscale(num_output_channels=1),
|
23 |
+
transforms.ToTensor()])
|
24 |
|
25 |
+
# Create a convolutional neural network
|
26 |
+
class Model(nn.Module):
|
27 |
+
def __init__(self, input_shape: int, hidden_units: int, output_shape: int):
|
28 |
+
super().__init__()
|
29 |
+
self.block_1 = nn.Sequential(
|
30 |
+
nn.Conv2d(in_channels=input_shape,
|
31 |
+
out_channels=hidden_units,
|
32 |
+
kernel_size=3, # how big is the square that's going over the image?
|
33 |
+
stride=1, # default
|
34 |
+
padding=1), # options = "valid" (no padding) or "same" (output has same shape as input) or int for specific number
|
35 |
+
nn.ReLU(),
|
36 |
+
nn.Conv2d(in_channels=hidden_units,
|
37 |
+
out_channels=hidden_units,
|
38 |
+
kernel_size=3,
|
39 |
+
stride=1,
|
40 |
+
padding=1),
|
41 |
+
nn.ReLU(),
|
42 |
+
nn.MaxPool2d(kernel_size=2,
|
43 |
+
stride=2) # default stride value is same as kernel_size
|
44 |
+
)
|
45 |
+
self.block_2 = nn.Sequential(
|
46 |
+
nn.Conv2d(hidden_units, hidden_units, 3, padding=1),
|
47 |
+
nn.ReLU(),
|
48 |
+
nn.Conv2d(hidden_units, hidden_units, 3, padding=1),
|
49 |
+
nn.ReLU(),
|
50 |
+
nn.MaxPool2d(2)
|
51 |
+
)
|
52 |
+
self.classifier = nn.Sequential(
|
53 |
+
nn.Flatten(),
|
54 |
+
nn.Linear(in_features=hidden_units*7*7,
|
55 |
+
out_features=output_shape)
|
56 |
+
)
|
57 |
|
58 |
+
def forward(self, x: torch.Tensor):
|
59 |
+
# x = self.block_1(x)
|
60 |
+
# print(x.shape)
|
61 |
+
# x = self.block_2(x)
|
62 |
+
# print(x.shape)
|
63 |
+
# x = self.classifier(x)
|
64 |
+
# print(x.shape)
|
65 |
+
x = self.classifier(self.block_2(self.block_1(x)))
|
66 |
+
return x
|
67 |
+
return Model, transforms
|
model_1.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:09d5f31bc58b2ae0b7b58d3730491a2708db1245fbaf688d1d6a3cb1b613ba3d
|
3 |
+
size 77575
|