EngReem85 commited on
Commit
f877e18
·
verified ·
1 Parent(s): da1d009

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -66
app.py CHANGED
@@ -1,51 +1,39 @@
1
  import os
2
-
3
- # ⚠️ إجبار TensorFlow على عدم حجز الـ GPU بالكامل أثناء الـ Startup لمنع تصادم ZeroGPU
4
- os.environ["TF_FORCE_GPU_ALLOW_GROWTH"] = "true"
5
- os.environ["CUDA_VISIBLE_DEVICES"] = "0"
6
-
7
  import cv2
8
  import numpy as np
9
- import tensorflow as tf
10
  import gradio as gr
11
- import spaces # مكتبة ZeroGPU
12
- from tensorflow.keras import datasets, layers, models
13
 
14
  # ============================================
15
- # 1. تحميل أو بناء النموذج
16
  # ============================================
17
  model_path = 'mnist_cnn_model.keras'
18
 
19
- if os.path.exists(model_path):
20
- model = tf.keras.models.load_model(model_path)
21
- print("✅ تم تحميل النموذج المحفوظ.")
22
- else:
23
- print("⚠️ بناء وتدريب النموذج...")
24
- model = models.Sequential([
25
- layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
26
- layers.MaxPooling2D((2, 2)),
27
- layers.Conv2D(64, (3, 3), activation='relu'),
28
- layers.MaxPooling2D((2, 2)),
29
- layers.Flatten(),
30
- layers.Dense(128, activation='relu'),
31
- layers.Dropout(0.5),
32
- layers.Dense(10, activation='softmax')
33
- ])
34
- model.compile(
35
- optimizer='adam',
36
- loss='sparse_categorical_crossentropy',
37
- metrics=['accuracy']
38
- )
39
-
40
- (x_train, y_train), _ = datasets.mnist.load_data()
41
- x_train = x_train.reshape((60000, 28, 28, 1)).astype('float32') / 255.0
42
- model.fit(x_train, y_train, epochs=5, validation_split=0.1, verbose=1)
43
- model.save(model_path)
44
- print("✅ تم حفظ النموذج.")
45
-
46
- # تحميل بيانات الاختبار للأمثلة
47
- (_, _), (test_images, test_labels) = datasets.mnist.load_data()
48
- test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255.0
49
 
50
  # ============================================
51
  # 2. دالة معالجة الصورة
@@ -55,9 +43,7 @@ def process_image_for_mnist(image_input):
55
  return None, None
56
 
57
  if isinstance(image_input, dict):
58
- image = image_input.get('composite', None)
59
- if image is None:
60
- image = image_input.get('background', None)
61
  if image is None and len(image_input) > 0:
62
  image = list(image_input.values())[0]
63
  else:
@@ -85,11 +71,15 @@ def process_image_for_mnist(image_input):
85
 
86
  return normalized, reshaped
87
 
 
 
 
88
  # ============================================
89
- # 3. دالة التوقع المحمية بـ ZeroGPU
90
  # ============================================
91
  @spaces.GPU
92
  def predict_sketch(image):
 
93
  try:
94
  if image is None:
95
  return {}, None, "⚠️ يرجى الرسم في المربع أولاً!"
@@ -99,8 +89,23 @@ def predict_sketch(image):
99
  if normalized is None:
100
  return {}, None, "⚠️ تعذر معالجة الصورة المدخلة."
101
 
102
- # إجراء التوقع باستخدام الـ GPU المخصص ديناميكياً
103
- preds = model(reshaped, training=False).numpy()[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  predicted_class = int(np.argmax(preds))
105
  confidence = float(np.max(preds))
106
 
@@ -112,7 +117,7 @@ def predict_sketch(image):
112
  top3_idx = np.argsort(preds)[-3:][::-1]
113
  top3_str = "\n".join([f" {i+1}. الرقم {idx}: {preds[idx]:.2%}" for i, idx in enumerate(top3_idx)])
114
 
115
- debug_info = f"""📊 نتائج التوقع (ZeroGPU):
116
  - الرقم المتوقع: {predicted_class}
117
  - نسبة الثقة: {confidence:.2%}
118
 
@@ -125,17 +130,7 @@ def predict_sketch(image):
125
  return {}, None, f"❌ خطأ أثناء التوقّع: {str(e)}"
126
 
127
  # ============================================
128
- # 4. دالة اختيار مثال عشوائي
129
- # ============================================
130
- def random_example():
131
- idx = np.random.randint(0, len(test_images))
132
- img = test_images[idx].reshape(28, 28)
133
- img_large = cv2.resize(img, (280, 280), interpolation=cv2.INTER_NEAREST)
134
- img_rgb = np.stack([img_large] * 3, axis=2)
135
- return img_rgb, f"🎲 تم اختيار رقم عشوائي (الرقم الحقيقي: {test_labels[idx]})"
136
-
137
- # ============================================
138
- # 5. بناء واجهة Gradio
139
  # ============================================
140
  with gr.Blocks(title="MNIST Recognizer on ZeroGPU") as demo:
141
  gr.Markdown("# 🧠 التعرف على الأرقام المكتوبة بخط اليد (ZeroGPU)")
@@ -143,9 +138,7 @@ with gr.Blocks(title="MNIST Recognizer on ZeroGPU") as demo:
143
  with gr.Row():
144
  with gr.Column(scale=1):
145
  sketch = gr.Sketchpad(label="✏️ منطقة الرسم")
146
- with gr.Row():
147
- submit_btn = gr.Button("🔮 توقع", variant="primary")
148
- random_btn = gr.Button("🎲 مثال عشوائي", variant="secondary")
149
  info = gr.Textbox(label="📌 معلومات التصحيح", interactive=False, lines=8)
150
 
151
  with gr.Column(scale=1):
@@ -157,11 +150,5 @@ with gr.Blocks(title="MNIST Recognizer on ZeroGPU") as demo:
157
  inputs=sketch,
158
  outputs=[output, processed_img, info]
159
  )
160
-
161
- random_btn.click(
162
- fn=random_example,
163
- inputs=[],
164
- outputs=[sketch, info]
165
- )
166
 
167
  demo.launch()
 
1
  import os
 
 
 
 
 
2
  import cv2
3
  import numpy as np
 
4
  import gradio as gr
5
+ import spaces
 
6
 
7
  # ============================================
8
+ # 1. بناء/تدريب النموذج لحفظه محلياً
9
  # ============================================
10
  model_path = 'mnist_cnn_model.keras'
11
 
12
+ def ensure_model_exists():
13
+ if not os.path.exists(model_path):
14
+ print("⚠️ جاري تدريب النموذج وحفظه لأول مرة...")
15
+ import tensorflow as tf
16
+ from tensorflow.keras import datasets, layers, models
17
+
18
+ model = models.Sequential([
19
+ layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
20
+ layers.MaxPooling2D((2, 2)),
21
+ layers.Conv2D(64, (3, 3), activation='relu'),
22
+ layers.MaxPooling2D((2, 2)),
23
+ layers.Flatten(),
24
+ layers.Dense(128, activation='relu'),
25
+ layers.Dropout(0.5),
26
+ layers.Dense(10, activation='softmax')
27
+ ])
28
+ model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
29
+
30
+ (x_train, y_train), _ = datasets.mnist.load_data()
31
+ x_train = x_train.reshape((60000, 28, 28, 1)).astype('float32') / 255.0
32
+ model.fit(x_train, y_train, epochs=3, validation_split=0.1, verbose=1)
33
+ model.save(model_path)
34
+ print("✅ تم حفظ النموذج بنجاح.")
35
+
36
+ ensure_model_exists()
 
 
 
 
 
37
 
38
  # ============================================
39
  # 2. دالة معالجة الصورة
 
43
  return None, None
44
 
45
  if isinstance(image_input, dict):
46
+ image = image_input.get('composite', None) or image_input.get('background', None)
 
 
47
  if image is None and len(image_input) > 0:
48
  image = list(image_input.values())[0]
49
  else:
 
71
 
72
  return normalized, reshaped
73
 
74
+ # Variable لحفظ النموذج داخل الـ GPU Worker
75
+ loaded_model = None
76
+
77
  # ============================================
78
+ # 3. دالة التوقع ببيئة ZeroGPU المضمونة
79
  # ============================================
80
  @spaces.GPU
81
  def predict_sketch(image):
82
+ global loaded_model
83
  try:
84
  if image is None:
85
  return {}, None, "⚠️ يرجى الرسم في المربع أولاً!"
 
89
  if normalized is None:
90
  return {}, None, "⚠️ تعذر معالجة الصورة المدخلة."
91
 
92
+ # تحميل TensorFlow وتكوين الـ GPU ديناميكياً داخل بيئة ZeroGPU فقط
93
+ import tensorflow as tf
94
+
95
+ # تهيئة نمو الذاكرة لتفادي انهيار CUDA memory allocation
96
+ gpus = tf.config.list_physical_devices('GPU')
97
+ if gpus:
98
+ try:
99
+ for gpu in gpus:
100
+ tf.config.experimental.set_memory_growth(gpu, True)
101
+ except RuntimeError:
102
+ pass
103
+
104
+ if loaded_model is None:
105
+ loaded_model = tf.keras.models.load_model(model_path)
106
+
107
+ # التوقع
108
+ preds = loaded_model(reshaped, training=False).numpy()[0]
109
  predicted_class = int(np.argmax(preds))
110
  confidence = float(np.max(preds))
111
 
 
117
  top3_idx = np.argsort(preds)[-3:][::-1]
118
  top3_str = "\n".join([f" {i+1}. الرقم {idx}: {preds[idx]:.2%}" for i, idx in enumerate(top3_idx)])
119
 
120
+ debug_info = f"""📊 نتائج التوقع (ZeroGPU Active):
121
  - الرقم المتوقع: {predicted_class}
122
  - نسبة الثقة: {confidence:.2%}
123
 
 
130
  return {}, None, f"❌ خطأ أثناء التوقّع: {str(e)}"
131
 
132
  # ============================================
133
+ # 4. بناء واجهة Gradio
 
 
 
 
 
 
 
 
 
 
134
  # ============================================
135
  with gr.Blocks(title="MNIST Recognizer on ZeroGPU") as demo:
136
  gr.Markdown("# 🧠 التعرف على الأرقام المكتوبة بخط اليد (ZeroGPU)")
 
138
  with gr.Row():
139
  with gr.Column(scale=1):
140
  sketch = gr.Sketchpad(label="✏️ منطقة الرسم")
141
+ submit_btn = gr.Button("🔮 توقع", variant="primary")
 
 
142
  info = gr.Textbox(label="📌 معلومات التصحيح", interactive=False, lines=8)
143
 
144
  with gr.Column(scale=1):
 
150
  inputs=sketch,
151
  outputs=[output, processed_img, info]
152
  )
 
 
 
 
 
 
153
 
154
  demo.launch()