Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -33,7 +33,7 @@ from html_templates import (
|
|
33 |
)
|
34 |
from urllib.parse import quote
|
35 |
from ultralytics import YOLO
|
36 |
-
from device_manager import DeviceManager
|
37 |
import asyncio
|
38 |
import traceback
|
39 |
|
@@ -536,6 +536,8 @@ dog_breeds = ["Afghan_Hound", "African_Hunting_Dog", "Airedale", "American_Staff
|
|
536 |
"Wire-Haired_Fox_Terrier"]
|
537 |
|
538 |
|
|
|
|
|
539 |
class MultiHeadAttention(nn.Module):
|
540 |
|
541 |
def __init__(self, in_dim, num_heads=8):
|
@@ -568,7 +570,6 @@ class BaseModel(nn.Module):
|
|
568 |
|
569 |
def __init__(self, num_classes, device='cuda' if torch.cuda.is_available() else 'cpu'):
|
570 |
super().__init__()
|
571 |
-
self.device_mgr = DeviceManager()
|
572 |
self.device = self.device_mgr.get_optimal_device()
|
573 |
self.backbone = efficientnet_v2_m(weights=EfficientNet_V2_M_Weights.IMAGENET1K_V1)
|
574 |
self.feature_dim = self.backbone.classifier[1].in_features
|
@@ -585,7 +586,6 @@ class BaseModel(nn.Module):
|
|
585 |
|
586 |
self.to(device)
|
587 |
|
588 |
-
@device_handler
|
589 |
def forward(self, x):
|
590 |
x = x.to(self.device)
|
591 |
features = self.backbone(x)
|
@@ -594,7 +594,6 @@ class BaseModel(nn.Module):
|
|
594 |
return logits, attended_features
|
595 |
|
596 |
# Initialize model
|
597 |
-
device_mgr = DeviceManager()
|
598 |
num_classes = len(dog_breeds)
|
599 |
|
600 |
# Initialize base model
|
@@ -623,31 +622,40 @@ def preprocess_image(image):
|
|
623 |
|
624 |
return transform(image).unsqueeze(0)
|
625 |
|
626 |
-
@device_handler
|
627 |
async def predict_single_dog(image):
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
probs = F.softmax(logits, dim=1)
|
634 |
-
|
635 |
-
# 其餘代碼保持不變
|
636 |
-
top5_prob, top5_idx = torch.topk(probs, k=5)
|
637 |
-
breeds = [dog_breeds[idx.item()] for idx in top5_idx[0]]
|
638 |
-
probabilities = [prob.item() for prob in top5_prob[0]]
|
639 |
-
|
640 |
-
sum_probs = sum(probabilities[:3])
|
641 |
-
relative_probs = [f"{(prob/sum_probs * 100):.2f}%" for prob in probabilities[:3]]
|
642 |
|
643 |
-
|
644 |
-
|
645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
|
647 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
|
649 |
|
650 |
-
@device_handler
|
651 |
async def detect_multiple_dogs(image, conf_threshold=0.3, iou_threshold=0.55):
|
652 |
results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
|
653 |
dogs = []
|
|
|
33 |
)
|
34 |
from urllib.parse import quote
|
35 |
from ultralytics import YOLO
|
36 |
+
from device_manager import DeviceManager
|
37 |
import asyncio
|
38 |
import traceback
|
39 |
|
|
|
536 |
"Wire-Haired_Fox_Terrier"]
|
537 |
|
538 |
|
539 |
+
device_mgr = DeviceManager()
|
540 |
+
|
541 |
class MultiHeadAttention(nn.Module):
|
542 |
|
543 |
def __init__(self, in_dim, num_heads=8):
|
|
|
570 |
|
571 |
def __init__(self, num_classes, device='cuda' if torch.cuda.is_available() else 'cpu'):
|
572 |
super().__init__()
|
|
|
573 |
self.device = self.device_mgr.get_optimal_device()
|
574 |
self.backbone = efficientnet_v2_m(weights=EfficientNet_V2_M_Weights.IMAGENET1K_V1)
|
575 |
self.feature_dim = self.backbone.classifier[1].in_features
|
|
|
586 |
|
587 |
self.to(device)
|
588 |
|
|
|
589 |
def forward(self, x):
|
590 |
x = x.to(self.device)
|
591 |
features = self.backbone(x)
|
|
|
594 |
return logits, attended_features
|
595 |
|
596 |
# Initialize model
|
|
|
597 |
num_classes = len(dog_breeds)
|
598 |
|
599 |
# Initialize base model
|
|
|
622 |
|
623 |
return transform(image).unsqueeze(0)
|
624 |
|
|
|
625 |
async def predict_single_dog(image):
|
626 |
+
"""
|
627 |
+
Predicts the dog breed using only the classifier.
|
628 |
+
"""
|
629 |
+
try:
|
630 |
+
image_tensor = preprocess_image(image).to(device_mgr.get_optimal_device())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
631 |
|
632 |
+
with torch.no_grad():
|
633 |
+
outputs = model(image_tensor) # 同步調用
|
634 |
+
logits = outputs[0] if isinstance(outputs, tuple) else outputs
|
635 |
+
probs = F.softmax(logits, dim=1)
|
636 |
+
|
637 |
+
top5_prob, top5_idx = torch.topk(probs, k=5)
|
638 |
+
breeds = [dog_breeds[idx.item()] for idx in top5_idx[0]]
|
639 |
+
probabilities = [prob.item() for prob in top5_prob[0]]
|
640 |
+
|
641 |
+
sum_probs = sum(probabilities[:3])
|
642 |
+
relative_probs = [f"{(prob/sum_probs * 100):.2f}%" for prob in probabilities[:3]]
|
643 |
+
|
644 |
+
print("\nClassifier Predictions:")
|
645 |
+
for breed, prob in zip(breeds[:5], probabilities[:5]):
|
646 |
+
print(f"{breed}: {prob:.4f}")
|
647 |
+
|
648 |
+
return probabilities[0], breeds[:3], relative_probs
|
649 |
|
650 |
+
except RuntimeError as e:
|
651 |
+
if "out of memory" in str(e) or "CUDA" in str(e):
|
652 |
+
logger.warning("ZeroGPU unavailable, falling back to CPU")
|
653 |
+
device_mgr._current_device = torch.device('cpu')
|
654 |
+
model.to('cpu')
|
655 |
+
return await predict_single_dog(image) # 遞迴調用,使用 CPU
|
656 |
+
raise e
|
657 |
|
658 |
|
|
|
659 |
async def detect_multiple_dogs(image, conf_threshold=0.3, iou_threshold=0.55):
|
660 |
results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
|
661 |
dogs = []
|