Spaces:
Sleeping
Sleeping
File size: 6,693 Bytes
59d6247 b691765 59d6247 f877e18 f1946ce f877e18 f1946ce 59d6247 f877e18 f1946ce 911101b f1946ce 911101b 06d2fa0 8b1d6f5 911101b 8b1d6f5 59d6247 8b1d6f5 911101b 59d6247 8b1d6f5 911101b 59d6247 8b1d6f5 06d2fa0 8b1d6f5 06d2fa0 8b1d6f5 59d6247 06d2fa0 8b1d6f5 06d2fa0 8b1d6f5 06d2fa0 f877e18 06d2fa0 f877e18 f1946ce da1d009 f1946ce f877e18 f1946ce 911101b 8b1d6f5 911101b 8b1d6f5 06d2fa0 8b1d6f5 59d6247 da1d009 8b1d6f5 f877e18 59d6247 8b1d6f5 59d6247 8b1d6f5 59d6247 c052932 59d6247 8b1d6f5 f1946ce da1d009 f1946ce 8313df0 911101b f1946ce 508baaa 06d2fa0 546adda f1946ce 8b1d6f5 911101b da1d009 8b1d6f5 f1946ce 8b1d6f5 da1d009 8b1d6f5 911101b 06d2fa0 8b1d6f5 06d2fa0 911101b 8b1d6f5 373292c | 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | import os
import cv2
import numpy as np
import gradio as gr
import spaces
# ============================================
# 1. بناء/تدريب النموذج لحفظه محلياً
# ============================================
model_path = 'mnist_cnn_model.keras'
def ensure_model_exists():
if not os.path.exists(model_path):
print("⚠️ جاري تدريب النموذج وحفظه لأول مرة...")
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
(x_train, y_train), _ = datasets.mnist.load_data()
x_train = x_train.reshape((60000, 28, 28, 1)).astype('float32') / 255.0
model.fit(x_train, y_train, epochs=3, validation_split=0.1, verbose=1)
model.save(model_path)
print("✅ تم حفظ النموذج بنجاح.")
ensure_model_exists()
# تحميل بيانات الاختبار للأمثلة العشوائية
import tensorflow as tf
(_, _), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
test_images_norm = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255.0
# ============================================
# 2. دالة معالجة الصورة الآمنة
# ============================================
def process_image_for_mnist(image_input):
# التحقق الآمن من الصفر/الغياب بدون تقييم المصفوفة كـ Boolean
if image_input is None:
return None, None
if isinstance(image_input, dict):
image = image_input.get('composite', None)
if image is None:
image = image_input.get('background', None)
if image is None and len(image_input) > 0:
image = list(image_input.values())[0]
else:
image = image_input
if image is None or not isinstance(image, np.ndarray) or image.size == 0:
return None, None
if len(image.shape) == 3 and image.shape[-1] == 4:
image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
if len(image.shape) == 3:
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
else:
gray = image.copy()
resized = cv2.resize(gray, (28, 28), interpolation=cv2.INTER_AREA)
_, binary = cv2.threshold(resized, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
if np.sum(binary == 255) > np.sum(binary == 0):
binary = 255 - binary
normalized = binary.astype('float32') / 255.0
reshaped = normalized.reshape(1, 28, 28, 1)
return normalized, reshaped
loaded_model = None
# ============================================
# 3. دالة التوقع ببيئة ZeroGPU المضمونة
# ============================================
@spaces.GPU
def predict_sketch(image):
global loaded_model
try:
# إصلاح سبب الخطأ: استخدام size أو is None بشكل صريح
if image is None:
return {}, None, "⚠️ يرجى الرسم في المربع أو اختيار مثال أولاً!"
normalized, reshaped = process_image_for_mnist(image)
if normalized is None:
return {}, None, "⚠️ تعذر معالجة الصورة المدخلة."
import tensorflow as tf
gpus = tf.config.list_physical_devices('GPU')
if gpus:
try:
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
except RuntimeError:
pass
if loaded_model is None:
loaded_model = tf.keras.models.load_model(model_path)
preds = loaded_model(reshaped, training=False).numpy()[0]
predicted_class = int(np.argmax(preds))
confidence = float(np.max(preds))
probabilities = {str(i): float(preds[i]) for i in range(10)}
display_img = (normalized * 255).astype(np.uint8)
display_img = cv2.resize(display_img, (140, 140), interpolation=cv2.INTER_NEAREST)
top3_idx = np.argsort(preds)[-3:][::-1]
top3_str = "\n".join([f" {i+1}. الرقم {idx}: {preds[idx]:.2%}" for i, idx in enumerate(top3_idx)])
debug_info = f"""📊 نتائج التوقع :
- الرقم المتوقع: {predicted_class}
- نسبة الثقة: {confidence:.2%}
🔝 أعلى 3 احتمالات:
{top3_str}"""
return probabilities, display_img, debug_info
except Exception as e:
return {}, None, f"❌ خطأ أثناء التوقّع: {str(e)}"
# ============================================
# 4. دالة اختيار مثال عشوائي (تمت إعادتها)
# ============================================
def random_example():
idx = np.random.randint(0, len(test_images))
img = test_images[idx]
img_large = cv2.resize(img, (280, 280), interpolation=cv2.INTER_NEAREST)
img_rgb = np.stack([img_large] * 3, axis=2)
return img_rgb, f"🎲 تم اختيار رقم عشوائي (الرقم الحقيقي: {test_labels[idx]})"
# ============================================
# 5. بناء واجهة Gradio
# ============================================
with gr.Blocks(title="MNIST") as demo:
gr.Markdown("# 🧠 التعرف على الأرقام المكتوبة بخط اليد ")
with gr.Row():
with gr.Column(scale=1):
sketch = gr.Sketchpad(label="✏️ منطقة الرسم")
with gr.Row():
submit_btn = gr.Button("🔮 توقع", variant="primary")
random_btn = gr.Button("🎲 مثال عشوائي", variant="secondary")
info = gr.Textbox(label="📌 معلومات التصحيح", interactive=False, lines=8)
with gr.Column(scale=1):
output = gr.Label(num_top_classes=3, label="📊 احتمالات التوقع")
processed_img = gr.Image(label="🖼️ الصورة بعد المعالجة", image_mode="L")
# ربط الأحداث
submit_btn.click(
fn=predict_sketch,
inputs=sketch,
outputs=[output, processed_img, info]
)
random_btn.click(
fn=random_example,
inputs=[],
outputs=[sketch, info]
)
demo.launch() |