klibaner commited on
Commit
3bc6b95
·
verified ·
1 Parent(s): f084345

Upload 4 files

Browse files
Files changed (4) hide show
  1. INSTRUCTIONS.txt +7 -0
  2. README.md +28 -7
  3. app.py +114 -0
  4. requirements.txt +3 -0
INSTRUCTIONS.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ 1. Create a Hugging Face Space: SDK = Gradio, hardware = CPU Basic.
2
+ 2. Extract this ZIP on your computer.
3
+ 3. Upload app.py, requirements.txt and README.md to the root of the Space.
4
+ 4. Upload your saved model file cifar10_cnn.pt to the same root.
5
+ 5. Commit the changes and wait for the build to complete.
6
+
7
+ Do not upload this ZIP itself as a single file: first extract it.
README.md CHANGED
@@ -1,13 +1,34 @@
1
  ---
2
- title: Cifar
3
- emoji: 🏢
4
- colorFrom: purple
5
- colorTo: red
6
  sdk: gradio
7
- sdk_version: 6.19.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: CIFAR-10 Image Classifier
3
+ emoji: 🖼️
4
+ colorFrom: blue
5
+ colorTo: purple
6
  sdk: gradio
 
 
7
  app_file: app.py
8
  pinned: false
9
  ---
10
 
11
+ # CIFAR-10 Image Classifier
12
+
13
+ This is an educational image classifier trained on CIFAR-10.
14
+
15
+ It predicts one of 10 labels:
16
+
17
+ - airplane
18
+ - automobile
19
+ - bird
20
+ - cat
21
+ - deer
22
+ - dog
23
+ - frog
24
+ - horse
25
+ - ship
26
+ - truck
27
+
28
+ ## Required model file
29
+
30
+ Place `cifar10_cnn.pt` in this repository root, next to `app.py`.
31
+
32
+ ## Note
33
+
34
+ The model was trained on small 32×32 CIFAR-10 images. It may make mistakes on normal phone photos.
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import gradio as gr
4
+ import torch
5
+ import torch.nn as nn
6
+ from torchvision import transforms
7
+
8
+
9
+ class SimpleCNN(nn.Module):
10
+ # This must match the network trained in the original notebook.
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.features = nn.Sequential(
14
+ nn.Conv2d(3, 32, kernel_size=3, padding=1),
15
+ nn.ReLU(),
16
+ nn.MaxPool2d(2),
17
+ nn.Conv2d(32, 64, kernel_size=3, padding=1),
18
+ nn.ReLU(),
19
+ nn.MaxPool2d(2),
20
+ nn.Conv2d(64, 128, kernel_size=3, padding=1),
21
+ nn.ReLU(),
22
+ nn.MaxPool2d(2),
23
+ )
24
+ self.classifier = nn.Sequential(
25
+ nn.Flatten(),
26
+ nn.Linear(128 * 4 * 4, 256),
27
+ nn.ReLU(),
28
+ nn.Dropout(0.30),
29
+ nn.Linear(256, 10),
30
+ )
31
+
32
+ def forward(self, x):
33
+ return self.classifier(self.features(x))
34
+
35
+
36
+ MODEL_PATH = Path(__file__).with_name("cifar10_cnn.pt")
37
+ DEVICE = torch.device("cpu")
38
+
39
+ TRANSFORM = transforms.Compose([
40
+ transforms.Resize((32, 32)),
41
+ transforms.ToTensor(),
42
+ transforms.Normalize(
43
+ (0.4914, 0.4822, 0.4465),
44
+ (0.2470, 0.2435, 0.2616),
45
+ ),
46
+ ])
47
+
48
+
49
+ def load_model():
50
+ if not MODEL_PATH.exists():
51
+ raise FileNotFoundError(
52
+ "Файл cifar10_cnn.pt не найден. Загрузите его в корень Space рядом с app.py."
53
+ )
54
+ try:
55
+ checkpoint = torch.load(MODEL_PATH, map_location=DEVICE, weights_only=True)
56
+ except TypeError:
57
+ checkpoint = torch.load(MODEL_PATH, map_location=DEVICE)
58
+
59
+ model = SimpleCNN().to(DEVICE)
60
+ model.load_state_dict(checkpoint["model_state_dict"])
61
+ model.eval()
62
+
63
+ classes = checkpoint.get(
64
+ "classes",
65
+ ["airplane", "automobile", "bird", "cat", "deer",
66
+ "dog", "frog", "horse", "ship", "truck"],
67
+ )
68
+ return model, classes
69
+
70
+
71
+ MODEL, CLASSES = load_model()
72
+
73
+
74
+ def predict(image):
75
+ if image is None:
76
+ return {}, "Загрузите изображение."
77
+
78
+ x = TRANSFORM(image.convert("RGB")).unsqueeze(0).to(DEVICE)
79
+ with torch.no_grad():
80
+ probabilities = torch.softmax(MODEL(x), dim=1)[0].cpu()
81
+
82
+ values, indices = torch.topk(probabilities, k=3)
83
+ results = {
84
+ CLASSES[index.item()]: float(value)
85
+ for value, index in zip(values, indices)
86
+ }
87
+ label = CLASSES[indices[0].item()]
88
+ confidence = float(values[0]) * 100
89
+ return results, f"Модель считает, что это: **{label}** ({confidence:.1f}%)."
90
+
91
+
92
+ with gr.Blocks() as demo:
93
+ gr.Markdown(
94
+ """# 🖼️ Распознавание изображений — CIFAR-10
95
+
96
+ Загрузите фото. Модель выберет наиболее похожий класс: **самолёт, автомобиль, птица, кот, олень, собака, лягушка, лошадь, корабль или грузовик**.
97
+
98
+ > Это учебная модель, обученная на маленьких изображениях CIFAR-10. На обычных фото она может ошибаться."""
99
+ )
100
+
101
+ with gr.Row():
102
+ image_input = gr.Image(
103
+ label="Загрузите изображение",
104
+ type="pil",
105
+ sources=["upload", "webcam"],
106
+ )
107
+ result = gr.Label(label="Три наиболее вероятных класса", num_top_classes=3)
108
+
109
+ explanation = gr.Markdown()
110
+ button = gr.Button("Распознать", variant="primary")
111
+ button.click(predict, inputs=image_input, outputs=[result, explanation])
112
+
113
+ if __name__ == "__main__":
114
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ torch
2
+ torchvision
3
+ pillow