import torch import torch.nn as nn import os from typing import Tuple, Optional, Any import warnings def safe_load_model(model_path: str, device: torch.device, model_instance: nn.Module) -> Tuple[Optional[nn.Module], bool]: """ تحميل آمن للنموذج مع معالجة الأخطاء Args: model_path: مسار ملف النموذج device: الجهاز (CPU/GPU) model_instance: instance من النموذج Returns: tuple: (النموذج المحمل، نجح التحميل أم لا) """ try: # التحقق من وجود الملف if not os.path.exists(model_path): print(f"❌ ملف النموذج غير موجود: {model_path}") print("💡 تأكد من وضع ملف best_model.pth في نفس مجلد التطبيق") return None, False print(f"📂 جاري تحميل النموذج من: {model_path}") # تحميل النموذج checkpoint = torch.load(model_path, map_location=device) # التحقق من نوع checkpoint if isinstance(checkpoint, dict): # إذا كان النموذج محفوظ كـ state_dict if 'model_state_dict' in checkpoint: model_instance.load_state_dict(checkpoint['model_state_dict']) print("✅ تم تحميل state_dict من checkpoint") elif 'state_dict' in checkpoint: model_instance.load_state_dict(checkpoint['state_dict']) print("✅ تم تحميل state_dict") else: # محاولة تحميل dict مباشرة model_instance.load_state_dict(checkpoint) print("✅ تم تحميل النموذج كـ state_dict") else: # إذا كان النموذج محفوظ كـ full model model_instance = checkpoint print("✅ تم تحميل النموذج الكامل") # نقل إلى الجهاز المناسب model_instance = model_instance.to(device) model_instance.eval() # وضع التقييم print(f"✅ تم تحميل النموذج بنجاح على {device}") return model_instance, True except FileNotFoundError: print(f"❌ ملف النموذج غير موجود: {model_path}") return None, False except RuntimeError as e: print(f"❌ خطأ في تحميل النموذج: {e}") print("💡 تأكد من أن بنية النموذج متطابقة مع النموذج المحفوظ") return None, False except Exception as e: print(f"❌ خطأ غير متوقع في تحميل النموذج: {e}") return None, False def validate_model_architecture(model: nn.Module, expected_input_size: int = 193) -> bool: """ التحقق من صحة بنية النموذج Args: model: النموذج المحمل expected_input_size: حجم الإدخال المتوقع Returns: bool: صحيح إذا كانت البنية صحيحة """ try: # إنشاء tensor تجريبي dummy_input = torch.randn(1, expected_input_size) # تجربة forward pass with torch.no_grad(): output = model(dummy_input) print(f"✅ بنية النموذج صحيحة - الإدخال: {expected_input_size}, الإخراج: {output.shape}") return True except Exception as e: print(f"❌ بنية النموذج غير صحيحة: {e}") return False def create_dummy_model(num_classes: int = 8) -> nn.Module: """ إنشاء نموذج وهمي للاختبار عند عدم وجود النموذج الأصلي Args: num_classes: عدد الفئات Returns: نموذج وهمي """ print("⚠️ إنشاء نموذج وهمي للاختبار...") class DummyEmotionNet(nn.Module): def __init__(self, num_classes=8): super(DummyEmotionNet, self).__init__() self.fc = nn.Linear(193, num_classes) # 193 هو حجم الميزات المستخرجة def forward(self, x): return self.fc(x) model = DummyEmotionNet(num_classes) print("✅ تم إنشاء النموذج الوهمي") return model def check_model_file(model_path: str = 'best_model.pth'): """ فحص ملف النموذج وإعطاء معلومات عنه Args: model_path: مسار ملف النموذج """ print(f"🔍 فحص ملف النموذج: {model_path}") if not os.path.exists(model_path): print("❌ ملف النموذج غير موجود!") print("💡 تأكد من:") print(" 1. وضع ملف best_model.pth في نفس مجلد التطبيق") print(" 2. أن اسم الملف صحيح") print(" 3. أن الملف غير تالف") return False # معلومات الملف file_size = os.path.getsize(model_path) print(f"📊 حجم الملف: {file_size / (1024*1024):.2f} MB") # محاولة قراءة الملف try: checkpoint = torch.load(model_path, map_location='cpu') print("✅ يمكن قراءة الملف") if isinstance(checkpoint, dict): print("📋 محتويات الملف:") for key in checkpoint.keys(): print(f" - {key}") return True except Exception as e: print(f"❌ خطأ في قراءة الملف: {e}") return False if __name__ == "__main__": # اختبار النظام print("🧪 اختبار نظام تحميل النموذج...") check_model_file()