EngReem85 commited on
Commit
a5d68f6
·
verified ·
1 Parent(s): 070be86

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -56
app.py CHANGED
@@ -5,16 +5,11 @@ import cv2
5
  from tensorflow.keras import datasets, layers, models
6
  import os
7
 
8
- # ============================================================
9
- # 1. تحميل أو بناء النموذج (حل احتياطي في حال عدم وجود الملف)
10
- # ============================================================
11
  model_path = 'mnist_cnn_model.keras'
12
-
13
  if os.path.exists(model_path):
14
  model = tf.keras.models.load_model(model_path)
15
- print("✅ تم تحميل النموذج المحفوظ.")
16
  else:
17
- print("⚠️ لم يتم العثور على النموذج، جارٍ البناء والتدريب...")
18
  model = models.Sequential([
19
  layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
20
  layers.MaxPooling2D((2, 2)),
@@ -24,80 +19,49 @@ else:
24
  layers.Dense(64, activation='relu'),
25
  layers.Dense(10, activation='softmax')
26
  ])
27
- model.compile(optimizer='adam',
28
- loss='sparse_categorical_crossentropy',
29
- metrics=['accuracy'])
30
-
31
  (train_images, train_labels), _ = datasets.mnist.load_data()
32
  train_images = train_images.reshape((60000, 28, 28, 1)).astype('float32') / 255
33
  model.fit(train_images, train_labels, epochs=3, validation_split=0.1, verbose=1)
34
  model.save(model_path)
35
- print("✅ تم بناء النموذج وتدريبه وحفظه.")
36
 
37
- # ============================================================
38
- # 2. تحميل بيانات MNIST للاستخدام في الأمثلة العشوائية
39
- # ============================================================
40
  (_, _), (test_images, test_labels) = datasets.mnist.load_data()
41
  test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255
42
 
43
- # ============================================================
44
- # 3. دالة التنبؤ بالصورة المرسومة
45
- # ============================================================
46
  def predict_sketch(image):
47
- """
48
- تستقبل الصورة من Sketchpad، تعالجها، وتعيد الاحتمالات لكل فئة.
49
- """
50
  try:
51
- # الصورة قادمة بصيغة (height, width, 3) من نوع numpy array
52
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
53
  resized = cv2.resize(gray, (28, 28))
54
- # قلب الألوان لأن MNIST تدربت على خلفية سوداء وكتابة بيضاء
55
  inverted = 255 - resized
56
  normalized = inverted.astype('float32') / 255.0
57
  reshaped = normalized.reshape(1, 28, 28, 1)
58
-
59
- prediction = model.predict(reshaped, verbose=0)[0]
60
- # تحويل إلى قاموس لعرضه في Label
61
- return {str(i): float(prediction[i]) for i in range(10)}
62
  except Exception as e:
63
- return {"خطأ": str(e)}
64
 
65
- # ============================================================
66
- # 4. دالة جلب مثال عشوائي من بيانات الاختبار
67
- # ============================================================
68
  def random_example():
69
  idx = np.random.randint(0, len(test_images))
70
  img = test_images[idx].reshape(28, 28)
71
- # تحويل الصورة إلى 3 قنوات (RGB) لأن Sketchpad يتوقع ذلك
72
  img_rgb = np.stack([img] * 3, axis=2)
73
- info_text = f"🖼️ رقم العينة: {idx} | الرقم الحقيقي: {test_labels[idx]}"
74
- return img_rgb, info_text
75
-
76
- # ============================================================
77
- # 5. بناء واجهة Gradio باستخدام Blocks + Sketchpad
78
- # ============================================================
79
- with gr.Blocks(title="MNIST Digit Recognizer") as demo:
80
- gr.Markdown("# 🧠 التعرف على الأرقام المكتوبة بخط اليد")
81
- gr.Markdown("ارسم رقماً (0-9) في المربع، أو اضغط على زر **'مثال عشوائي'** لتجربة النموذج.")
82
 
 
 
 
83
  with gr.Row():
84
- # العمود الأيسر: لوحة الرسم والأزرار
85
- with gr.Column(scale=1):
86
- sketch = gr.Sketchpad(label="✏️ ارسم هنا")
87
  with gr.Row():
88
- submit_btn = gr.Button("🔮 توقع", variant="primary")
89
- random_btn = gr.Button("🎲 مثال عشوائي", variant="secondary")
90
- info = gr.Textbox(label="📌 معلومات", interactive=False, value="ارسم أو اختر مثالاً عشوائياً.")
91
-
92
- # العمود الأيمن: عرض النتائج
93
- with gr.Column(scale=1):
94
- output = gr.Label(num_top_classes=3, label="📊 أعلى 3 احتمالات")
95
-
96
- # ربط الأزرار بالدوال
97
  submit_btn.click(fn=predict_sketch, inputs=sketch, outputs=output)
98
  random_btn.click(fn=random_example, inputs=[], outputs=[sketch, info])
99
 
100
- # ============================================================
101
- # 6. 🔥 هذا هو المتغير الذي سيستخدمه Hugging Face Spaces
102
- demo.launch()
103
- # ============================================================
 
5
  from tensorflow.keras import datasets, layers, models
6
  import os
7
 
8
+ # ========== 1. تحميل النموذج ==========
 
 
9
  model_path = 'mnist_cnn_model.keras'
 
10
  if os.path.exists(model_path):
11
  model = tf.keras.models.load_model(model_path)
 
12
  else:
 
13
  model = models.Sequential([
14
  layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
15
  layers.MaxPooling2D((2, 2)),
 
19
  layers.Dense(64, activation='relu'),
20
  layers.Dense(10, activation='softmax')
21
  ])
22
+ model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
 
 
 
23
  (train_images, train_labels), _ = datasets.mnist.load_data()
24
  train_images = train_images.reshape((60000, 28, 28, 1)).astype('float32') / 255
25
  model.fit(train_images, train_labels, epochs=3, validation_split=0.1, verbose=1)
26
  model.save(model_path)
 
27
 
28
+ # ========== 2. بيانات MNIST ==========
 
 
29
  (_, _), (test_images, test_labels) = datasets.mnist.load_data()
30
  test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255
31
 
32
+ # ========== 3. دوال التنبؤ والعشوائي ==========
 
 
33
  def predict_sketch(image):
 
 
 
34
  try:
 
35
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
36
  resized = cv2.resize(gray, (28, 28))
 
37
  inverted = 255 - resized
38
  normalized = inverted.astype('float32') / 255.0
39
  reshaped = normalized.reshape(1, 28, 28, 1)
40
+ pred = model.predict(reshaped, verbose=0)[0]
41
+ return {str(i): float(pred[i]) for i in range(10)}
 
 
42
  except Exception as e:
43
+ return {"error": str(e)}
44
 
 
 
 
45
  def random_example():
46
  idx = np.random.randint(0, len(test_images))
47
  img = test_images[idx].reshape(28, 28)
 
48
  img_rgb = np.stack([img] * 3, axis=2)
49
+ return img_rgb, f"الرقم الحقيقي: {test_labels[idx]}"
 
 
 
 
 
 
 
 
50
 
51
+ # ========== 4. الواجهة (بدون launch) ==========
52
+ with gr.Blocks(title="MNIST Recognizer") as demo:
53
+ gr.Markdown("# 🧠 التعرف على الأرقام")
54
  with gr.Row():
55
+ with gr.Column():
56
+ sketch = gr.Sketchpad(label="ارسم هنا")
 
57
  with gr.Row():
58
+ submit_btn = gr.Button("توقع", variant="primary")
59
+ random_btn = gr.Button("عشوائي", variant="secondary")
60
+ info = gr.Textbox(label="معلومات")
61
+ with gr.Column():
62
+ output = gr.Label(num_top_classes=3, label="الاحتمالات")
 
 
 
 
63
  submit_btn.click(fn=predict_sketch, inputs=sketch, outputs=output)
64
  random_btn.click(fn=random_example, inputs=[], outputs=[sketch, info])
65
 
66
+ # ========== 5. ❌ ممنوع استخدام launch() هنا ==========
67
+ # Spaces يتولى التشغيل عبر المتغير 'demo'