Spaces:
Sleeping
Sleeping
test
Browse files- app.py +74 -0
- models/__pycache__/freshness_model.cpython-311.pyc +0 -0
- models/freshness_model.py +45 -0
- models/label_encoder_type.pkl +3 -0
- models/multi_output_model.pth +3 -0
- requirements.txt +5 -0
app.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
import joblib
|
3 |
+
from torchvision import transforms
|
4 |
+
from PIL import Image
|
5 |
+
from models.freshness_model import MultiOutputModel
|
6 |
+
import torch.nn.functional as F # For applying sigmoid
|
7 |
+
import gradio as gr
|
8 |
+
import json
|
9 |
+
|
10 |
+
# Define the paths
|
11 |
+
MODEL_PATH = 'models/multi_output_model.pth'
|
12 |
+
LABEL_ENCODER_TYPE_PATH = 'models/label_encoder_type.pkl'
|
13 |
+
|
14 |
+
# Load the label encoder
|
15 |
+
label_encoder_type = joblib.load(LABEL_ENCODER_TYPE_PATH)
|
16 |
+
|
17 |
+
# Load the model
|
18 |
+
model = MultiOutputModel(num_classes_type=len(label_encoder_type.classes_))
|
19 |
+
model.load_state_dict(torch.load(MODEL_PATH))
|
20 |
+
model.eval() # Set the model to evaluation mode
|
21 |
+
|
22 |
+
# Define the image transformations
|
23 |
+
transform = transforms.Compose([
|
24 |
+
transforms.Resize((224, 224)), # Resize to match the input size of the model
|
25 |
+
transforms.ToTensor(),
|
26 |
+
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # Normalize using ImageNet stats
|
27 |
+
])
|
28 |
+
|
29 |
+
def preprocess_image(image: Image.Image):
|
30 |
+
"""Preprocess the input image."""
|
31 |
+
return transform(image).unsqueeze(0) # Add batch dimension
|
32 |
+
|
33 |
+
def run_inference(image: Image.Image):
|
34 |
+
"""Run inference on a single image."""
|
35 |
+
# Preprocess the image
|
36 |
+
input_tensor = preprocess_image(image)
|
37 |
+
|
38 |
+
# Move to device (GPU if available)
|
39 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
40 |
+
model.to(device)
|
41 |
+
input_tensor = input_tensor.to(device)
|
42 |
+
|
43 |
+
# Forward pass
|
44 |
+
with torch.no_grad():
|
45 |
+
type_output, freshness_output = model(input_tensor)
|
46 |
+
|
47 |
+
# Apply sigmoid to freshness output (to get probability)
|
48 |
+
freshness_output = torch.sigmoid(freshness_output.squeeze()) # Sigmoid for binary classification
|
49 |
+
|
50 |
+
# Decode predictions
|
51 |
+
_, predicted_type_idx = torch.max(type_output, 1)
|
52 |
+
predicted_type = label_encoder_type.inverse_transform([predicted_type_idx.item()])
|
53 |
+
|
54 |
+
output = {}
|
55 |
+
output['type'] = str(predicted_type[0])
|
56 |
+
output['freshness'] = str(float(freshness_output.item()))
|
57 |
+
|
58 |
+
json_output = json.dumps(output)
|
59 |
+
return str(json_output)
|
60 |
+
|
61 |
+
|
62 |
+
# Define Gradio input and output components
|
63 |
+
image_input = gr.Image(type="pil")
|
64 |
+
|
65 |
+
# Create the Gradio interface
|
66 |
+
demo = gr.Interface(
|
67 |
+
fn=run_inference,
|
68 |
+
inputs=image_input,
|
69 |
+
outputs='text',
|
70 |
+
title="Frshness prediction",
|
71 |
+
description="Upload an image, and the model will detect objects and return the number of objects along with the image showing the bounding boxes."
|
72 |
+
)
|
73 |
+
|
74 |
+
demo.launch(share=True)
|
models/__pycache__/freshness_model.cpython-311.pyc
ADDED
Binary file (2.44 kB). View file
|
|
models/freshness_model.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
import torch.nn as nn
|
3 |
+
import torchvision.models as models
|
4 |
+
|
5 |
+
class MultiOutputModel(nn.Module):
|
6 |
+
def __init__(self, num_classes_type):
|
7 |
+
super(MultiOutputModel, self).__init__()
|
8 |
+
|
9 |
+
# Load a pretrained ResNet model
|
10 |
+
self.resnet = models.resnet50(pretrained=True)
|
11 |
+
|
12 |
+
# Freeze ResNet layers if needed
|
13 |
+
for param in self.resnet.parameters():
|
14 |
+
param.requires_grad = False
|
15 |
+
|
16 |
+
# Get the in_features from the fully connected layer of ResNet
|
17 |
+
in_features = self.resnet.fc.in_features
|
18 |
+
|
19 |
+
# Modify the fully connected layer for type classification
|
20 |
+
self.resnet.fc = nn.Linear(in_features, 512)
|
21 |
+
|
22 |
+
self.type_head = nn.Sequential(
|
23 |
+
nn.Linear(512, 512), # Adding another fully connected layer
|
24 |
+
nn.ReLU(), # Activation function for the new layer
|
25 |
+
nn.Dropout(0.3), # Optional dropout for regularization
|
26 |
+
nn.Linear(512, num_classes_type) # Output layer
|
27 |
+
)
|
28 |
+
|
29 |
+
self.freshness_head = nn.Sequential(
|
30 |
+
nn.Linear(512, 256),
|
31 |
+
nn.ReLU(),
|
32 |
+
nn.Dropout(0.4),
|
33 |
+
nn.Linear(256, 128), # Adding a new layer for more complexity
|
34 |
+
nn.ReLU(), # Activation for the new layer
|
35 |
+
nn.Linear(128, 1) # Final output layer
|
36 |
+
)
|
37 |
+
|
38 |
+
def forward(self, x):
|
39 |
+
x = self.resnet(x)
|
40 |
+
# Type classification
|
41 |
+
type_output = self.type_head(x)
|
42 |
+
# Freshness classification
|
43 |
+
freshness_output = self.freshness_head(x)
|
44 |
+
|
45 |
+
return type_output, freshness_output
|
models/label_encoder_type.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:e72ac49b06237b7d64aea3e11ea1ed9b18f35a7206423528008d3d057001f563
|
3 |
+
size 675
|
models/multi_output_model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2829d0af93570ce2623866e3d3cdd6752be278948fe92b9672f0d6387bd79db6
|
3 |
+
size 100282609
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
joblib
|
2 |
+
torch
|
3 |
+
torchvision
|
4 |
+
pillow
|
5 |
+
gradio
|