-
المساهمات
1068 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
43
إجابات الأسئلة
-
إجابة Ali Haidar Ahmad سؤال في حفظ الرسم plot في ملف بدلاً من عرضه باستخدام Matplotlib كانت الإجابة المقبولة
توفر مكتبة matplotlib الأداة savefig لتخزين الرسم البياني الناتج:
savefig(fname, dpi=None, format=None,bbox_inches=None) حيث أن الوسيط الأول يمثل المسار الذي تود فيه حفظ الملف الناتج، وال dpi أو dots per inch (وهي وحدة قياس تحدد عدد النقاط الفردية التي يمكن وضعها في مربع 1 × 1 بوصة) وزيادتها تؤدي لزيادة حجم الصورة. أما الوسيط الثالث فهو لتحديد الصيغة التي سيتم فيها حفظ الشكل البياني أي 'png', 'pdf', 'svg' ...إلخ. أما الوسيط الأخير ففي حال ضبطه على tight سيتم إزالة المسافة البيضاء الغير مرغوب فيها التي تكون حول الرسم البياني. هنا سأقوم بإنشاء رسم بياني وحفظه:
import matplotlib.pyplot as plt fig, ax = plt.subplots( nrows=1, ncols=1 ) #figure إنشاء ax.plot([0,1,2], [10,20,3]) fig.savefig('to.png') # حفظه plt.close(fig) # figure إغلاق ال وبالنسبة للمثال الخاص بك:
import pylab as pt pt.figure(1, figsize=(6, 6)) nationalism = 'European','Asian', 'Indian' ratio = [15, 35, 55] ax = pt.axes([0.1, 0.1, 0.8, 0.8]) pt.pie(ratio, explode=(0, 0.05, 0), labels=nationalism, shadow=True) pt.savefig('al.png') # حفظه كما يجب أن تتجنب استخدام التعليمة imshow لعرض الشكل قبل حفظه وإلا فستكون الصورة التي سيتم تخزينها صورة فارغة.
-
إجابة Ali Haidar Ahmad سؤال في دمج الصور في OpenCV كانت الإجابة المقبولة
يمكنك ذلك من خلال جمع الصورتين مع إعطاء وزن لكل صورة (لتحديد الشفافية) مع إضافة تصحيح غاما (اختياري) وتوفر مكتبة OpenCV التابع addWeighted لإتمام المهمة:
img = cv2.addWeighted(source1, alpha, source2, beta, gamma) حيث أن الوسيط الأول يمثل الصورة الأولى والوسيط الثاني alpha يمثل وزنها (مقدار الشفافية) والوسيط الثالث هو الصورة الثانية والرابع وزنها beta، حيث سيتم ضرب كل بكسل بالصورة الأولى ب alpha وكل بكسل في الثانية بقيمة beta، أما غاما فهي قيمة ستضاف للناتج (هنا هي لضبط شدة السطوع brightness أو التباين contrast في ألوان الصورة بغاية زيادة جودتها). المعادلة التالية تعبر عن العملية حيث تعتمد قيمة كل بكسل من بكسلات الخرج التي ستمثل الصورة الممزوجة على المعادلة التالية:
G(x)= alpha*f0(x)+(1 – alpha)*f1(x) + gamma # أو بشكل أبسط Image= alpha * image1 + beta * image2 + y +gamma نلاحظ أنه من خلال تغيير قيمة ألفا، والتي ستتراوح من 0 إلى 1، يمكننا بسهولة التحويل من صورة إلى أخرى، وتتراوح قيمة هذه الأوزان من 0 إلى 1، ومن ثم يمكننا الحصول على العرض المطلوب للصور حسب حاجتنا. وبالنسبة لغاما يمكنك ضبطها على 0 لكي تتجاهل تأثيرها.
والمثال التالي سيوضح ذلك، حيث سنقوم بدمج الصورتين التاليتين:
والكود اللازم:
import cv2 as cv # نقوم بقراءة الصور img1 = cv.imread(r'C:\Users\Windows.10\Desktop\Safedrive\closedeye1.jpg',1) img2 = cv.imread(r'C:\Users\Windows.10\Desktop\Safedrive\car.jpg',1) # عرض أبعاد الصورة الثانية img2.shape # (194, 259, 3) # أبعاد الصورة الأولى img1.shape # (186, 271, 3) #resize يجب أن تكون أبعاد الصور متاطابقة لذا نوحد حجمهما من خلال التابع img2 = cv.resize(img2,(190,250)) img1 = cv.resize(img1,(190,250)) # أو كان بالإمكان جعل حجم الصورة الثانية مطابقة للأولى كالتالي # img2 = cv2.resize(img2,(img1.shape[1],img1.shape[0])) # لكن الطريقة الأولى أفضل في حال كانت الصورتين بأبعاد مختلفة وللتحكم بذلك بشكل أدق # اللآن سنقوم بدمج الصورتين img = cv.addWeighted(img1,0.6,img2,0.4,0) cv.imshow('image',img) cv.waitKey(0) cv.destroyAllWindows() cv2.destroyAllWindows() الخرج:
-
إجابة Ali Haidar Ahmad سؤال في قراءة وتشغيل الفيديو باستخدام مكتبة OpenCV كانت الإجابة المقبولة
لقراءة الفيديو يمكنك استخدام الكود التالي:
import numpy as np import cv2 as cv #نحدد مسار الفيديو الذي نريد التقاطه captured = cv.VideoCapture(r'C:\Users\Windows.10\Downloads\Video\videoplayback_6.mp4') while(True): # التقاط الفيديو إطار تلو الآخر ret, frame = captured.read() # هنا يمكنك القيام بالعمليات التي تريدها على إطارات الفيديو # على سبيل المثال تريد عرض الفيديو بالصيغة الرمادية: gray_frame = cv.cvtColor(frame, cv2.COLOR_BGR2GRAY) # سيتم تحويل كل إطار ملون إلى إطار رمادي # عرض الإطار cv2.imshow('frame',gray_frame) #من لوحة المفاتيح a الانتظار 25 ميلي ثانية قبل قراءة الإطار التالي وفي هذه الأثناء إذا ضغطت على الزر # سيتم الخروج من الفيديو if cv2.waitKey(25) == ord('a'): break # عند الانتهاء من الفيديو يتم تدمير النافذة cv2.destroyAllWindows() حيث أن التابع VideoCapture هو التابع الذي يمكننا من التقاط الفيديو وهنا كوننا نقوم بقراءة فيديو من القرص يجب أن نقوم بتمرير مسار الصورة، أما لو كنا نريد التقاط الفيديو من كاميرا فيجب أن نمرر له رقم يمثل ترتيب الكاميرا وبالتالي إذا كنت تستخدم كاميرا وحيدة فنمرر له 0 أي الكاميرا الأولى والوحيدة:
cv.VideoCapture(0) أما إذا كان لديك عدد أكبر -5 كاميرات مثلاً- وأردت التقاط الفيديو من الكاميرا الثالثة، نمرر له الرقم 2 وهكذا..
وكما نعلم فإن الفيديو هو عبارة عن إطارات (صور) يتم عرضها بسرعة عالية جداً وبالتالي سنستخدم حلقة while لقراءة هذه الاطارات الواحد تلو الآخر حيث نقوم ضمن الحلقة while بقراءة الصورة من خلال التابع read الذي يعيد قيميتين الأولى هي ret وهي قيمة منطقية (True|False) بحيث إذا قرأ إطار يكون True وإذا لم يقرأ إطار يكون False (أي انتهى أو هناك خطأ ما). والآن بعد قراءة الإطار يمكنك القيام بأي نوع تريده من العمليات على سبيل المثال قمنا بتحويل الإطار إلى الصيغة الرمادية من خلال التابع cvtColor ثم بعدها قمنا بعرض الإطار ثم قمنا باستخدام التابع waitKey للانتظار مدة زمنية محددة -25 ميلي ثانية- قبل الدخول في تكرار جديد للحلقة while وقراءة إطار جديد. أيضاً خلال هذه المدة -25 ميلي ثانية- إذا ضغطنا على الزر "a" من لوحة المفاتيح سيتم إيقاف الفيديو (إغلاق النافذة) وإنهاءه.
^-^هذا كل شيء ^-^
-
إجابة Ali Haidar Ahmad سؤال في توليد عدد عشوائي random في لغة سي شارب #C كانت الإجابة المقبولة
نعم هناك الكلاس Random يمكنك استخدامه لتوليد أعداد صحيحية عشوائية. نقوم أولاً بتعريف غرض (object) من هذا الكلاس:
Random rand = new Random(); ثم بعدها يمكنك استخدام الدالة next عن طريق استدعائها من خلال هذا الغرض لتوليد أعداد عشوائية كالتالي:
int number = rand.Next(min, max); حيث تكون الأعداد المولَدة ضمن المجال [min,max] مثال:
int number1 = rnd.Next(9, 99); // تولد رقم عشوائي بين ال 9 وال 99 int number2 = rnd.Next(9); // تولد رقم عشوائي بين ال0 وال 9 -
إجابة Ali Haidar Ahmad سؤال في اختبار في تحليل البيانات Data Analysis python كانت الإجابة المقبولة
أولاً عليك قراءة البيانات في بايثون ويفضل تحويلها إلى ملف CSV ثم قراءتها ك Dataframe ليسهل التعامل معها (لامشكلة المهم أن تقوم بقراءتها بالشكل المناسب)، ثم بعد ذلك يمكنك استخدام مكتبة sklearn لتنفيذ الطلبات المتبقية حيث توفر لك مكتبة sklearn ماتحتاجه لتقسيم البيانات (الطلب 2 ) وبناء نموذج LinearR وإليك الروابط التالية التي تشرحهما:
وبالنسبة للطلب الأخير (تقييم أداء النموذج) فهنا يوجد كل الطرق مع شرحها، ويمكنك استخدام واحدة منها:
-
إجابة Ali Haidar Ahmad سؤال في كيفية تحويل قائمة list إلى tf.data.Dataset في تنسرفلو Tensorflow كانت الإجابة المقبولة
يمكنك استخدام الدالة tf.data.Dataset.from_generator لتحويل أي iterable في بايثون (أي قوائم أو قواميس أو tubles أو set) إلى Dataset ولها الشكل التالي:
from_generator( generator, output_types=None, output_shapes=None ) #كما ذكرنا iter الوسيط الأول هو أي كائن # output_shapes: None أبعاد المخرجات وفي حالتك كونها أحجام مختلفة نضع # output_types: نمط الإخراج لتطبيقها على مثالك كالتالي:
import tensorflow as tf li = [[1,11], [1,2,3]] #from_generator استخدام الدالة #none كون الأحجام مختلفة نضع المخرجات dataset = tf.data.Dataset.from_generator(lambda: li, tf.int32, output_shapes=[None]) # وسنستعرضها الآن iterator = dataset.make_one_shot_iterator() next_element = iterator.get_next() with tf.Session() as sess: print(sess.run(next_element)) # '[1,11]' print(sess.run(next_element)) # '[1,2,3]' كما يمكنك استخدام الدالة from_tensor_slices كالتالي:
dataset = tf.data.Dataset.from_tensor_slices(tf.ragged.constant(li)) # عرضها for s in dataset: print(s) """ <tf.RaggedTensor [[1, 11]]> <tf.RaggedTensor [[1, 2, 3]]> """ -
إجابة Ali Haidar Ahmad سؤال في الطبقة Conv2D في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
الطبقة Conv2D هي الطبقة التي يمكننا من خلالها بناء شبكة CNN في كيراس وتنسرفلو.. وسأشرح كيف نستخدمها.. أولاً الشكل العام لها:
tf.keras.layers.Conv2D( filters, kernel_size, strides=(1, 1), padding="valid", data_format=None, activation=None, use_bias=True, kernel_initializer="glorot_uniform", bias_initializer="zeros", kernel_regularizer=None, bias_regularizer=None, input_shape, **kwargs ) الوسيط الأول filters يمثل عدد المرشحات التي تريد أن يتم تطبيقها على مجموعة بياناتك (الصور). حيث يتم تطبيق كل فلتر على كل صورة لاستخراج السمات المميزة فيها (حواف زوايا نقاط..إلخ) عن طريق تنفيذ عملية "التفاف" convolution عليها. وعدد هذه الفلاتر سيمثل عدد القنوات التي سيتم إخراجها من هذه الطبقة (ستفهم أكثر في المثال بعد قليل).
الوسيط الثاني kernel_size يمثل حجم النواة (حجم المرشحات التي سيتم تطبيقها) حيث نمرر tuble يحوي قيمتين تمثلان طول وعرض المرشح، على سبيل المثال إذا قمنا بتمرير (3,3) فهذا يعني أن المرشحات التي سيتم تطبيقها ستكون أبعادها 3*3. كما يمكننا أن نمرر قيمة واحدة بدلاً من ال tuble، على سبيل المثال يمكن أن نمرر 5 وبالتالي سيفهم تلقائياً أن حجم المرشح الذي تريده هو 5*5. كما يجب أن نعلم أن أبعاد هذا المرشح يجب أن تكون أعداداً فردية لأن الأرقام الزوجية تعطي أداء ضعيف لأنك ستعاني مما يسمى بال aliasing error وهي عبارة عن تشوهات غير مرغوبة.
الوسيط الثالث هو strides أي عدد الخطوات، فكما نعلم إن عملية ال convolution هي عملية مرور مرشح على الصورة بدءاً من أعلى اليسار وصولاً لأسفل اليمين من الصورة. والوسيط strides يقوم بتحيد عدد الخطوات (عدد البكسلات).
الوسيط الرابع padding لتحيد فيما إذا كنت تريد تنفيذ عملية حشو للصورة أو لا (حشو جوانب الصورة بأصفار). ويأخذ قيمتان same لتنفيذ عملية الحشو و valid لعدم تنفيذها. ويكون الحشو في يمين ويسار أو أسفل وأعلى الصورة حسبما تحتاجه الصورة وذلك للحفاظ على نفس الأبعاد للصورة.
الوسيط الخامس data_format لتحديد شكل أبعاد الصور في بياناتك فمثلاً إذا كان عدد القنوات اللونية للصور في مجموعة بياناتك يتم تمثيلها في البعد الأخير (أي الثالث) فهنا نضع channels_last (وهي الحالة الافتراضية حيث أن أغلب الصور يتم تمثيل القنوات اللونية فيها كآخر بعد (batch_size, height, width, channels) ). أو channels_first في حال كان عدد القنوات اللونية ممثل في أول بعد (batch_size, channels, height, width).
الوسيط السادس activation هو دالة التنشيط التي سيتم استخدامها (افتراضياُ لن يتم استخدام أي دالة تنشيط) حيث يتم تطبيقها على مخرجات الطبقة. أما الوسيط السابع use_bias ويأخذ إما True أو False لتحديد فيما إذا كنت تريد إضافة وزن يمثل ال bias بحيث يتم جمعه على ناتج تطبيق الفلتر. أما الوسيط الثامن فهو kernel_initializer وهو لتحديد نوع التهيئة التي سيتم فيها تهيئة الفلاتر (افتراضياً يكون "glorot_uniform") والوسيط التاسع bias_initializer وافتراضياً يكون التهيئة بأصفار"zeros". وأخيراً input_shape لتحديد حجم الصور التي سيتم تقديمها للطبقة حيث نحدد لها طول وعرض وعدد القنوات اللونية للصورة وهو يضيف تلقائياُ البعد الرابع الذي يمثل حجم الباتش أي: batch_shape + (channels, rows, cols) أو batch_shape + (rows, cols, channels) حسب موضع القناة اللونية.
خرج هذه الطبقة هو:
batch_shape + (filters, new_rows, new_cols) في حالة كانت القناة اللونية في البداية. أو batch_shape + (new_rows, new_cols, filters) في حالة كانت القناة اللونية في النهاية.
ال new_rows و ال new_cols يتم حسابهم من المعادلة:
new_col=(col-2*p+f)/strides + 1 new_row=(row-2*p+f)/strides + 1 {{{{{{{{{وعدد الخطوات هو 1 p=0 في حالة كان بدون حشو يكون }}}}}}}}}} new_col=(col-f) + 1 new_row=(row-f + 1 الأمثلة التالية ستوضح الأمر أكثر:
# سنقوم بإنشاء 4 صور طولها 28 وعرضها 28 وملونة أي لها 3 قنوات لونية # سنقوم بتوليد هذه الصور بقيم عشوائية import tensorflow as tf x = tf.random.normal((4, 28, 28, 3)) #Conv2D الآن سنطبق عليها ال # سنستخدم مرشحين بحجم 3*3 #p=0 لن نستخدم حشو أي # وعدد الخطوات هو (1, 1) y = tf.keras.layers.Conv2D(2, 3,padding="valid",strides=(1, 1), activation='relu', input_shape=(28, 28, 3))(x) # الآن لنعرض أبعاد الخرج print(y.shape) (4, 26, 26, 2) # لاحظ أن الخرج ينتج من المعدلات السابقة كالتالي # new_col=new_row=28-3+1=26 # وعدد الفلاتر يصبح عدد القنوات في حالة كان ال padding=same:
y = tf.keras.layers.Conv2D(2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x) print(y.shape) # (4, 28, 28, 2) # لاحظ أن الخرج لم يتغير حيث أنه يقوم هنا بعملية حشو بأصفار بحيث تحافظ الصورة على أبعادها مثال عملي، حيث سأقوم باستخدامها مع مجموعة البيانات التالية لتصنيف صور القطط والكلاب (يمكنك الحصول على مجموعة البيانات من هنا https://www.kaggle.com/c/dogs-vs-cats/data):
from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Activation, Dropout, Flatten, Dense from keras import backend as K # نحدد مسارات البيانات train_data_dir = 'data/train' validation_data_dir = 'data/validation' nb_train_samples = 2000 # عدد عينات التدريب nb_validation_samples = 800 # التحقق epochs = 50 batch_size = 16 # عدد الباتشات # أبعاد الصور img_width, img_height = 150, 150 # نحدد طبقة الادخال input_shape = (img_width, img_height, 3) #DataAugmentation الآن سنقوم بعملية # إن لم يكن لديك معرفة بها فلقد تركت لك رابط في الأسفل train_datagen = ImageDataGenerator( rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') validation_generator = test_datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') # نبدأ ببناء النموذج model = Sequential() # نعرف أول طبقة التفاف model.add(Conv2D(32, (3, 3),activation='relu', input_shape=input_shape)) #وذلك لتقليل أبعاد الصورة Conv2Dبعد كل طبقة MaxPooling2D غالباً مانستخدم طبقة تسمى # إن لم يكن لديك معرفة بها فلقد تركت لك رابطاً في الأسفل لتوضيها model.add(MaxPooling2D(pool_size=(2, 2))) # ثاني طبقة التفاف model.add(Conv2D(32, (3, 3),activation='relu', )) model.add(MaxPooling2D(pool_size=(2, 2))) # ثالث طبقة model.add(Conv2D(64, (3, 3),activation='relu', )) model.add(MaxPooling2D(pool_size=(2, 2))) # نقوم بتسطيح المخرجات model.add(Flatten()) # fully-connected نبني الكلاسيفير الآن وهنا سنستخدم الطبقات المتصلة بالكامل model.add(Dense(64)) model.add(Activation('relu')) model.add(Dropout(0.5)) #لمنع الأوفرفيت model.add(Dense(1)) # طبقة الخرج model.add(Activation('sigmoid')) # تجميع النموذج model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc']) # تدريب النموذج model.fit_generator( train_generator, steps_per_epoch=nb_train_samples // batch_size, epochs=epochs, validation_data=validation_generator, validation_steps=nb_validation_samples // batch_size)
-
إجابة Ali Haidar Ahmad سؤال في استخدام نموذج VGG16 لتصنيف الصور في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
يمكنك استخدام هذا النموذج من خلال الموديول application.vgg16 في كيراس وتنسرفلو:
tf.keras.applications.vgg16.VGG16 وبالتالي لإنشاء النموذج نقوم بمايلي:
# نقوم أولاً بإنشاء المودل from tensorflow.keras.applications.vgg16 import VGG16 # استيراده model = VGG16() # تعريف كائن يمثل المودل print(model.summary()) # يمكنك استعراض شكل النموذج بالشكل التالي # كما يمكنك عرض رسم بياني يمثل النموذج from keras.utils.vis_utils import plot_model plot_model(model, to_file='vgg.png') الآن لتكن لدينا صورة ما ونريد تصنيفها من خلال هذا النموذج، فأول خطوة يجب القيام بها هي تحميل الصورة، ويمكننا القيام بذلك من خلال الدالة load image:
# نقوم بتحميل الصورة from tensorflow.keras.preprocessing.image import load_img image = load_img('/car.jpg', target_size=(224, 224)) # تعديل حجم الصورة بشكل يتناسب مع الحجم الذي تتطلبه الشبكة الصورة التي استخدمناها هي صورة سيارة:
الآن يجب أن نقوم بتحويل الصورة إلى شكلها الرياضي (مصفوفة بكسلات) من خلال الدالة img_to_array:
# تحويل المصفوفة إلى مصفوفة from tensorflow.keras.preprocessing.image import img_to_array image = img_to_array(image) # أبعاد الصورة image.shape # (224, 224, 3) الآن الصورة ستكون ب 3 أبعاد (طول وعرض وقنوات لونية)، لكن النموذج vgg16 (وأي نموذج آخر يتعامل مع الصور) يتوقع منك أن تمرر الصور في batches (حزم أو مجموعة من الصور دفعة واحدة). لذا يجب أن نقوم بتوسيع أبعاد الصورة (جعلها رباعية الأبعاد) بحيث أن البعد الجديد سوف يمثل عدد العينات(عدد الصور):
# نقوم بتوسيع أبعاد الصورة image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2])) # عرض حجمها الآن image.shape # (1, 224, 224, 3) # البعد الجديد يمثل عدد الصور وهنا لدينا صورة واحدة فقط الآن علينا القيام ببعض عمليات المعالجة على الصورة، بشكل يتطابق مع العمليات التي تمت على الصور أثناء تدريب النموذج، وحسب الورقة البحثية بهذا النموذج:
فإن مانحتاجه هو عملية واحدة فقط وهي طرح متوسط قيم ال RGB من كل بكسل، والخبر الجميل أنك لن تضطر للقيام بذلك بشكل يدوي وإنما هناك دالة preprocess_input تقوم بمايلزم:
# القيام بمعالجة الصورة بشكل يتطابق مع عمليات الممعالجة التي تمت على الصور التي تم تدريب النموذج عليها from keras.applications.vgg16 import preprocess_input image = preprocess_input(image) الآن الصورة (أو مجموعة الصور) جاهزة لأن يتم إنشاء توقعات لها من خلال النموذج:
# إيجاد التوقعات yhat = model.predict(image) yhat.shape # (1, 1000) كما نعلم فإن هذا النموذج تم تدريبه على مجموعة بيانات ImageNet التي تحوي ألف فئة مختلفة وبالتالي الخرج سيكون 1000 قيمة احتمالية تمثل احتمال انتماء هذه الصورة لكل فئة. لذا نحتاج لطريقة نستطيع فيها أخذ أكبر احتمال وهذا مايقدمه لنا decode_predictions:
from keras.applications.vgg16 import decode_predictions # تحويل الاحتمالات إلى تسميات فئة label = decode_predictions(yhat) label """ [[('n04037443', 'racer', 0.562338), # لاحظ أن أقوى احتمال هو أن الصورة تمثل صورة متسابق باحتمالية قدرها 56 بالمئة ('n04285008', 'sports_car', 0.28281146), # ثاني أكبر احتمال هو أنها صورة سيارة سباق باحتمالية قدرها 28 بالمئة ('n03100240', 'convertible', 0.08739577), ('n02974003', 'car_wheel', 0.037510887), ('n03930630', 'pickup', 0.010782746)]] """ الآن إذا كنت تريد استخلاص أكبر احتمال (التوقع الأساسي):
# استرداد النتيجة الأكثر احتمالا ، على سبيل المثال أعلى احتمال label = label[0][0] # طباعة التصنيف print('%s (%.2f%%)' % (label[1], label[2]*100)) # racer (56.23%) هذا كل شيئ...
-
إجابة Ali Haidar Ahmad سؤال في الفرق بين المعلمات الغير قابلة للتدريب "non-trainable" و القابلة للتدريب "trainable" في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
المعلمات غير القابلة للتدريب " non-trainable parameter " هي عدد الأوزان التي لن يتم تحديثها أثناء التدريب باستخدام خوارزمية ال Gradient descent الانتشار العكسي backpropagation.
وهناك نوعان رئيسيان للأوزان / المعلمات غير القابلة للتدريب:
أوزان wights نريد جعلها ثابتة لاتتغير قيمتها خلال عملية التدريب. هذا يعني أن keras لن تقوم بتحديث هذه الأوزان من خلال خواررزمية GD أثناء التدريب على الإطلاق (على سبيل المثال عندما نقوم باستخدام نماذج نقل التعلم مثل VGG أو Inception أو Res .. إلخ) فإننا نقوم بعملية تجميد لهذه الأوزان المدربة (فتغييرها من خلال خواررزمية GD يلغي فكرة نقل التعلم كلها فنحن نريد هذه الأوزان المدربة لذا نحتاج إلى تجميدها freez لكي لاتتغير). أو مثلاً عندما نستخدم شبكات تلاففية CNN فكما نعلم فإن هذه الشبكات تعتمد على تطبيق مرشحات لكشف سمات الصورة مثل الحواف من خلال مرشح سوبل مثلاُ الذي يعتمد على مشتقات الدرجة الأولى. وكما نعلم فإن قيم المرشح ستتغير من خلال عملية الانتشار الخلفي. لكن لو قمنا بتثبيت قيمها (قمنا بتثبيت قيم مرشح سوبل -قيم المرشحات تعتبر أوزان-) فقد يؤدي ذلك إلى أداء أفضل.
النوع الثاني ليس أوزان وإنما معلمات كتلك التي نستفيد منها للقيام بعمليات أشبه بالعمليات الإحصائية عندما نستخدم فكرة ال BatchNormalization في نماذجنا. وبالرغم من أنه قد يتم تحديث بعضها خلال التدريب إلى أنه لايتم تعديلهم من خلال ال backpropagation. لاحظ عندما نستخدم ال BatchNormalization:
model.add(BatchNormalization()) model.summary() """_________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_1 (Dense) (None, 10) 1010 _________________________________________________________________ batch_normalization_1 (Batch (None, 10) 40 ================================================================= Total params: 1,050 # العدد الكلي للمعلمات والأوزان Trainable params: 1,030 # قابلة للتدريب Non-trainable params: 20 # معلمات غير قابلة للتدريب _________________________________________________________________ """ ويمكنك مثلاً جعل أوزان طبقة ما ثابتة باستخدام الواصفة trainable حيث نقوم بضبطها على False:
model.get_layer(layerName).trainable = False كما يمكن التحكم بها من خلال الوسيط trainable لكن فقط أثناء بناء النموذج. مثال:
model.add(Dense(32, trainable=False,..)) # هنا جعلنا كل الخلايا غير قابلة للتدريب في هذه الطبقة
أما ال trainable parameter فهي الأوزان وال bias التي يتم تحديث قيمهم خلال عملية التدريب من خلال خوارزمية ال GD أي أنها الأوزان الموجودة داخل الشبكة والتي يتم تعديلها للحصول على ما نريد (حل مشكلة معينة).حيث يتم تعديل قيمهم من خلال خوارزمية الانتشار العكسي بحيث يتم تقليل قيمة ال loss إلى أقل مايمكن. وبشكل افتراضي ، يمكن تدريب جميع الأوزان في نموذج keras مالم تحدد عكس ذلك (مالم تقوم بتجميد بعضها -الحالة الأولى في الأعلى-).
هذا كل شيئ.
-
إجابة Ali Haidar Ahmad سؤال في الدالة compile في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
الدالة compile هي الدالة المسؤولة عن تكوين النموذج بعد أن تكون قد قمت بتحديد هيكليته (طبقاته وبارمتراته). حيث تقوم بترجمة هذه الهيكلية وتحديد المعلومات الأخرى اللازمة لتكوين النموذج وتجهيزه لبدء عملية التدريب. ولها الشكل التالي:
Model.compile( optimizer="rmsprop", loss=None, metrics=None, weighted_metrics=None, steps_per_execution=None, **kwargs ) حيث أن الوسيط الأول هو المحسَن المستخدم (وفي الرابط في الأسفل هناك شرح لأشهر نوعين من المحسنات وهما Rmsprop و Adam). أما الوسيط الثاني فهو دالة التكلفة المراد تطبيقها (غالباً نستخدم Binary_cross_Entropy مع مسائل التصنيف الثنائي و Categorical Crossentropy مع مسائل التصنيف المتعدد أو Spare Categorical Crossentropy) وأيضاً تجدهما في الروابط وكذلك يمكنك القيام بتعريف دالة التكلفة الخاصة بك واستخدامها كما تم شرح ذلك في الرابط في الأسفل. أما الوسيط الثالث فهو معيار قياس أداء النموذج خلال التدريب وغالباً نستخدم المعيار Accuracy عندما تكون البيانات متوازنة أو F1-Score عندما تكون البيانات غير متوازنة. أما الوسيط الخامس فهو لتوزين الفئات حيث نمرر لها قائمة المقاييس التي سيتم تقييمها ووزنها حسب وزن العينة sample_weight أو وزن الفئة class_weight أثناء التدريب والاختبار. أما الوسيط الأخير steps_per_execution فهذا يتعلق بسرعة التنفيذ و الافتراضي هو 1. ويمث عدد الدُفعات batches التي سيتم تنفيذها أثناء كل استدعاء tf.function. والفائدة منه تكمن في أن تشغيل دفعات متعددة داخل استدعاء tf.function واحد إلى تحسين الأداء بشكل كبير في حال كنت تستخدم وحدات TPU(على كولاب مثلاً). وما يلي هو مثال بسيط لها:
model.compile(optimizer=tf.keras.optimizer.Adam(learning_rate=1e-3), # هنا مررنا المحسن loss=tf.keras.losses.BinaryCrossentropy(), # دالة التكلفة metrics=[tf.keras.metrics.BinaryAccuracy(), # ومقياسين للأداء tf.keras.metrics.FalseNegatives()]) كما يمكنك أن تجد مثال عنها في كل رابط من الروابط المذكورة في الأسفل مع نماذج بسيطة وواضحة.
-
إجابة Ali Haidar Ahmad سؤال في ما الفرق بين الذواكر UMA والذواكر NUMA كانت الإجابة المقبولة
يتم تصنيف الآلات التي تستخدم الذاكرة المشتركة إلى ( Uniform Memory Access) UMA و(Non Uniform Memory Access) NUMA وذلك بالاعتماد على زمن الوصول للذاكرة "memory access time" حيث أن UMA يكون فيها الوصول للذاكرة متساوٍ، أما NUMA يكون الوصول غير متساوي. هنا إليك ملخص عن كل منهم:
تعرف باسم اكثر شهرة وهو SMP المعالجات المتعددة المتناظرة "Symmetric Multiprocessor" (متناظرة=أي المعالجات المتكافئة في العمل،كل معالج هو رئيس وند للآخر) + المعالجات متماثلة (أي نفس الصلاحيات ونفس العمل) Identical Processor + متساوية في السماحية بالوصول للذاكرة ووقت الوصول للذاكرة access time + تحقق مبدأ ترابط الكاش cache coherency، حيث تسمى أحيانا بcc_uma.
يكون لدينا ذاكرة واحدة مشتركة مع كل المعالجات موجودة في نفس المكان (كتلة واحدة) + هي عبارة عن SMP واحدة + يوجد لدينا متحكم واحد في الذاكرة ( single memory controller ) + يمكننا إضافة عدد محدود من المعالجات. + كل المعالجات لها نفس زمن الوصول latency إلى الذاكرة + يوجد نوع واحد منها هو cc_uma.
يتم تحقيقها عادة بشكل فيزيائي عن طريق ربط جهازي SMP أو أكثر + كل جهاز SMP يمكنه أن يصل مباشرة إلى ذاكرة جهاز SMP آخر حيث أن المعالجات تتصل ببعضها عن طريق ناقل bus الموجود ضمن الحاسب نفسه + الوصول للذاكرة عبر الناقل أبطأ من الوصول المباشر للذاكرة ضمن نفس الSMP + ليس كل المعالجات لها وصول متساوٍ إلى كل الذواكر + كل معالج له ذاكرته المحلية الخاصة والتي تكون مشتركة مع كل المعالجات الأخرى، أي أن الذاكرة موزعة في أكثر من موقع (كتل) + كل معالج له زمن وصول محدد إلى ذاكرة المعالجات الأخرى ويختلف ذلك بحسب مكانه + يمكننا إضافة العدد الذي نريده من المعالجات + هي عبارة عن مجموعة من الSMP + يوجد لدينا عدة متحكمات في الذاكرة ( multiple memort controller) + يوجد نوعين منها هما :numa ,cc_numa.
-
إجابة Ali Haidar Ahmad سؤال في نسخ الأوزان من طبقة إلى طبقة أخرى من خلال الدالة set_weights في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
يمكننا استخدام الدالة set_weights التي لها الشكل التالي:
Model.set_weights(weights) حيث نمرر لهذه الدالة الأوزان (مصفوفة نمباي) المراد استخدامها كأوزان للطبقة المستدعية (عمليى نسخ).
كما نعلم فإن أوزان الطبقة تعبر عن حالة الطبقة(سلوكها والتدريب الذي تلقته). إن هذه الدالة تقوم بنسخ الأوزان من طبقة لأخرى. حيث يجب تمرير قيم الوزن بالترتيب الذي تم إنشاؤه بواسطة الطبقة. على سبيل المثال ، تُرجع الطبقة Dense قائمة من قيمتين: مصفوفة النواة (مصفوفة الأوزان) ومتجه التحيز (قيم الانحراف bias). هذه القيم يمكن استخدامها لتعيين أوزان طبقة Dense أخرى:
import tensorflow as tf #وتهيئة قيم أوزانها Dense إنشاء طبقة # تهيئة الانحراف بقيمة 0 والأوزان بقيمة 1 layer1 = tf.keras.layers.Dense(1,kernel_initializer=tf.constant_initializer(1.)) out1 = layer1(tf.convert_to_tensor([[1., 2., 3.]])) # طباعة الأوزان (يتضمن ذلك قيمة الانحراف) layer1.get_weights() """ [array([[1.], [1.], [1.]], dtype=float32), array([0.], dtype=float32)] """ # تعريف طبقة أخرى layer2 = tf.keras.layers.Dense(1,kernel_initializer=tf.constant_initializer(2.)) out2 = layer_b(tf.convert_to_tensor([[10., 20., 30.]])) layer2.get_weights() """ [array([[2.], [2.], [2.]], dtype=float32), array([0.], dtype=float32)] """ # نسخ أوزان الطبقة الأولى للثانية layer_2.set_weights(layer_1.get_weights()) # عرض أوزانها الآن للتأكد layer_2.get_weights() """ [array([[1.], [1.], [1.]], dtype=float32), array([0.], dtype=float32)] """ -
إجابة Ali Haidar Ahmad سؤال في استبدال طبقة الدخل input layer في كيراس keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
نعم ممكن. عندما نقوم بحفظ النموذج من خلال:
model.save('my_model.h5') يتم حفظ معماريته (هيكليته) مما يسمح لنا بإنشاء النموذج. ويتم حفظ أوزان النموذج المدربة و ال loss وال optimizer (وحالته أيضاً) مما يمكننا من استكمال التدريب لاحقاً. وبالتالي عند تحميل النموذج:
load_model('my_model.h5') يمكننا الحصول على معماريته وأوزانه من خلال:
model.summary() # ملخص بطبقات النموذج وأوزانه model.get_weights() # (قيم الأوزان) أوزان النموذج ثم يمكنك القيام بحذف طبقة الدخل من خلال الدالة pop حيث نمرر لها رقم الطبقة المراد حذفها ثم إضافة الطبقة الجديدة التي تريدها:
model.layers.pop(0) # حذف الطبقة الأولى # تعريف طبقة الدخل الجديدة وتعديل النموذج Input = Input(batch_shape=(0,300,300,3)) # مثلاً # الخرج الجديد newOutputs = model(Input) newModel = Model(Input, newOutputs) # عرض هيكلية النموذج بعد التعديل newModel.summary() أو كحل ثاني وجدته لك لكنني غير مقتنع تماماً به (سيتجاهل حالة الأوبتيمايزر ودالة التكلفة لذا إن كانت غايتك هي تدريب النموذج من حيث توقف فلن ينجح الأمر. لذا فهذا الحل يصلح معك فقط إن أردت استخدام الأوزان السابقة): يمكنك استخراج تكوين النموذج السابق (هيكليته) ثم تعديله بالشكل الذي تريده في نموذج جديد ثم نسخ الأوزان إليه. مثلاً:
# استخراج تكوين النموذج config = model.get_config() # نسخ التكوين input_layer_name = config['layers'][0]['name'] config['layers'][0] = { 'name': 'new_input', 'class_name': 'InputLayer', 'config': { 'batch_input_shape': (None, 300, 300), 'dtype': 'float32', 'sparse': False, 'name': 'new_input' }, 'inbound_nodes': [] } config['layers'][1]['inbound_nodes'] = [[['new_input', 0, 0, {}]]] config['input_layers'] = [['new_input', 0, 0]] # النموذج الجديد model = model.__class__.from_config(model_config, custom_objects={}) # نسخ الأوزان weights = [layer.get_weights() for layer in model.layers[1:]] for layer, weight in zip(new_model.layers[1:], weights): layer.set_weights(weight) -
إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ TypeError: __array__() takes 1 positional argument but 2 were given في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
هذا الخطأ يظهر أحياناً بسبب وجود مشاكل في نسخة Pillow 8.3.0 الجديدة (صحيح أنك لاتستخدم import PIL بشكل صريح لكن الدالة ()tf.keras.preprocessing.image.load_img تستخدم PIL ضمنياً). لذا قم بتخفيض نسخة PIL إلى 8.2.0 وسينجح الأمر:
!pip install pillow==8.2.0 وبشكل عام لمعرفة الإصدار الحالي من PIL:
import PIL print(PIL.__version__) -
إجابة Ali Haidar Ahmad سؤال في متابعة أداء النموذج أثناء عملية التدريب من خلال ال Tensorboard في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
tensorboard_callback هي أداة تسمح لك بمراقبة أداء النموذج من خلال رسم بياني يوضح حالة التدريب. ويمكنك استخدامها مع نموذجك أو أي نموذج آخر بنفس الطريقة كالتالي:
%load_ext tensorboard # tensorboard نقوم بتحميل الإضافة # الآن سنعرف نموذج import tensorflow as tf import datetime mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 def create_model(): return tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax') ]) model = create_model() # ترجمة النموذج model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # مسار المجلد الذي سيتم فيه حفظ المعلومات التي سيقوم التنسربورد بتحليلها وعرضها log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # تعريف الكولباكس tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) # نقوم بتمرير الكولباكس إلى دالة التدريب model.fit(x=x_train, y=y_train, epochs=2, validation_data=(x_test, y_test), callbacks=[tensorboard_callback]) الآن لعرض الرسم البياني نقوم بتنفيذ الأمر التالي ضمن ال nootebook:
# لعرض الغراف %tensorboard --logdir logs/fit # حيث نضع مسار المجلد السابق أو من خلال ال commandline استخدم نفس الأمر السابق لكن من دون استخدام المعامل % أي:
tensorboard --logdir logs/fit وبهذه الطريقة يمكنك عرض معلومات الدقة والتكلفة loss ضمن نموذجك خلال عملية تدريب نموذجك.
-
إجابة Ali Haidar Ahmad سؤال في كيفية حساب ال Precision و Recall و F1 score في تنسرفلو Tensorflow كانت الإجابة المقبولة
في تنسرفلو يمكنك حسابهم بالشكل التالي اعتماداً على الصيغة العامة لهم:
بعد حساب القيم المتوقعة y_pred نقوم بحساب ال TP و TN و FP و FN ونستخدم الدالة count_nonzero للقيام بذلك:
TP = tf.count_nonzero(y_pred * y_true) TN = tf.count_nonzero((y_pred - 1) * (y_true - 1)) FP = tf.count_nonzero(y_pred * (y_true - 1)) FN = tf.count_nonzero((y_pred - 1) * y_true) ثم نقوم بتطبيق القوانين السابقة مباشرةً:
precision = TP / (TP + FP) recall = TP / (TP + FN) f1 = 2 * precision * recall / (precision + recall) عموماً إذا لم تكن تستخدم graph فيمكنك أيضاً استخدام التوابع الجاهزة في sklearn لذا سأترك لك روابط لهم:
في الرابط هنا تجد شرح لل TP و ال TN إلخ..
-
إجابة Ali Haidar Ahmad سؤال في تنفيذ كود معين عندما يبدأ جانغو Django لأول مرة فقط كانت الإجابة المقبولة
كما ذكر سامح.. من أجل Django 1.7+ يجب عليك استخدام الخطاف. ولكن إذا كنت تريد أن يتم استدعاء دالتك فقط عند تشغيل الخادم (وليس عند إجراء migrations ، migrate ، shell ، إلخ.. ) ، وتريد تجنب استثناءات AppRegistryNotReady عليك القيام بما يلي:
# الملف: myapp / apps.py import sys from django.apps import AppConfig class AppC(AppConfig): name = 'App' def ready(self): if 'runserver' not in sys.argv: return True # يجب عليك استيراد الوحدات الخاصة بك هنا # لتجنب استثناء AppRegistryNotReady from .models import MyModel # كود بدء التشغيل أيضاً يمكنك استخدام <project> /wsgi.py للقيام بذلك ، وسيتم تشغيله مرة واحدة فقط ، عند بدء تشغيل الخادم ، ولكن ليس عند تشغيل أوامر أو استيراد وحدة معينة:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") # كود بدء التشغيل هنا .. .. from django.core.wsgi import get_wsgi_application application = get_wsgi_application() -
إجابة Ali Haidar Ahmad سؤال في كيفية تحويل ملفات النموذج .meta و .data و. index إلى ملف Graph.pb واحد في تنسرفلو Tensorflow كانت الإجابة المقبولة
يمكنك القيام بعملية التحويل من خلال الكود التالي:
import tensorflow as tf with tf.Session() as mysess: # تحميل الغراف saver = tf.train.import_meta_graph('model.ckpt-22480.meta') # meta نمرر مسار تواجد ملف # تحويل الأوزان saver.restore(mysess,tf.train.latest_checkpoint('path/of/your/.meta/file')) # تجميد الغراف output_nodes = ['output:0'] # نحدد أسماء عقد الإخراج frozen_graph_def = tf.graph_util.convert_variables_to_constants( mysess,mysess.graph_def, output_nodes) # حفظه with open('graph.pb', 'wb') as file: file.write(frozen_graph_def.SerializeToString()) وفي حال لم تكن تعرف أسماء عقد الخرج، يمكنك استخدام الكود التالي لاستخلاصها:
output_nodes = [n.name for n in tf.get_default_graph().as_graph_def().node] -
إجابة Ali Haidar Ahmad سؤال في تعريَف callback من خلال الأداة LambdaCallback في كيراس Keras وتنسرفلو Tensorflow كانت الإجابة المقبولة
يمكنك استخدام الكلاس LambdaCallback التي تسمح لك بتعريفَ callback خاص بك وبالطريقة التي تريدها. باني هذا الكلاس يأخذ الوسطاء التالية التي تسمح لك بالتحكم في توقيت تنفيذ ال callback:
tf.keras.callbacks.LambdaCallback( on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None, on_train_begin=None, on_train_end=None, **kwargs ) on_epoch_begin أي الاستدعاء يتم في بداية كل epoch. و on_epoch_end أي في نهايته. on_batch_begin أي في بداية الباتش... وهكذا بالنسبة لللبقية.
بالنسبة ل on_epoch_begin و on_epoch_end فهما يتوقعان منك أن تتستخدم معهما وسيطين موضعيين هما ال epoch, logs. بالنسبة ل on_batch_begin و on_batch_end يتوقعان وسيطين أيضاً هما batch, logs. وأخيراً on_train_begin و on_train_end يتوقعان فقط وسيط واحد وهو logs. الآن لجعل الأمور أوضح سنأخذ المثال التالي:
# بناء نموذج # compile ترجمته من خلال الدالة # fit الآن عندما نريد تعريف الكولباك يجب أن يتم ذلك قبل تنفيذ الدالة # تعريف الكولباك الذي طلبته mycallback= LambdaCallback(on_epoch_end=lambda epoch, logs:model.save_weights(myfile.hdf5) if logs["val_accuracy"]>0.7 else None) #لكن لاتنسى أن تقوم بتمرير الكولباك الذي عرفناه للدالة أي fit الآن تقوم بتدريب النموذج من خلال الدالة model.fit(..., callbacks=[mycallback]) وبالتالي سيتم حفظ أوزان النموذج كلما كانت قيمة ال val_acc أكبر من 70 في المئة.
مثال آخر حيث سنقوم بتعريف كولباك يقوم بطباعة رقم الحزمة في بداية كل باتش:
callback1 = LambdaCallback( on_batch_begin=lambda batch,logs: print(batch)) تعريف كول باك آخر يقوم بحفظ ال loss في نهاية كل epoch في ملف JSON (الملف سيكون عبارة عن كائن json في كل سطر):
import json json_log = open('loss_log.json', mode='wt', buffering=1) #json إنشاء ملف callback2 = LambdaCallback( on_epoch_end=lambda epoch, logs: json_log.write( json.dumps({'epoch': epoch, 'loss': logs['loss']}) + '\n'), on_train_end=lambda logs: json_log.close() ) الآن نقوم بتمريرهم للدالة fit عندما نريد بدأ التدريب:
model.fit(..., callbacks=[callback1, callback2]) -
إجابة Ali Haidar Ahmad سؤال في استخدام نماذج نقل التعلم مع الصور الرمادية في كيراس Keras و تنسرفلو Tensorflow كانت الإجابة المقبولة
بالنسبة لاقتراحك فلا اعتقد أنه خيار جيد وسيجعل أوزان نقل التعلم أقل فائدة، والسبب في ذلك يعود إلى جوهر فكرة ال CNN وهي تطبيق filterbank على الصور في كل طبقة بحيث في أول طبقة يتم استخلاص سمات الصورة ( مثل الحواف من خلال تطبيق مرشحات الدرجة الأولى (سوبل) أو الثانية (غاوص) ومرشحات كشف الزوايا مثل هاريس و كاني .. إلخ) ثم في الطبقة التالية يتم تطبيق filterbank مرة أخرى على ناتج المرحلة السابقة، وهكذا.. أي يتم استخراج سمات عالية المستوى كلما تعمقت، مشتقة من سمات المستوى الأدنى التي استخرجتها الطبقات السابقة. وبالتالي إذا قمت بإسقاط الطبقة الأولى سيتم تخريب هذا التسلسل.
الحل يكون من خلال جعل صورك بتنسيق RGB حتى ولو أنها رمادية وسينجح ذلك تماماً، ويتم ذلك من خلال استخدام طريقة ما بحيث تقوم بنسخ القيم أي تكرار مصفوفة الصور 3 مرات على بُعد جديد. وهنا حل مقترح للقيام بذلك من خلال استخدام التابع np.newaxis من المكتبة نمباي:
# أبعاد الصور الرمادية print(grayscale_batch.shape) # (40, 100, 100) rgb_batch = np.repeat(grayscale_batch[..., np.newaxis], 3, -1) # أبعاد الصور بعد تكرار المصفوفة print(rgb_batch.shape) # (40, 100, 100, 3) يمكنك أيضاً استخدام الوسيط color_mode في الدالة image_dataset_from_directory وذلك عن طريق ضبطها على "RGB" حيث سيقوم بتحويلها تلقائياً اعتماداً على الفكرة السابقة. ولمزيد من التفاصيل عنه وعن ال Imagegenerator فهذا الرابط يشرح كل شيء:
-
إجابة Ali Haidar Ahmad سؤال في Webpack : تحويل الصور إلى webp باستخدام image-webpack-loader كانت الإجابة المقبولة
هناك حل أفضل من استخدام image-webpack-loader وهو استخدام imagemin و imagemin-webp:
تحقق من أنه تم تثبيت magemin & imagemin-webp. قم بإنشاء ملف webpack.config.prod.js لإنشاء سكريبت لتحويل الصور. قبل يناء سكريبت webpack.
تكون المصفوفة ['src/images/*.{jpg,png}'] هي ال input ويكون ال destination هو الخرج: const imagemin = require( "imagemin" ) const webp = require( "imagemin-webp" ) imagemin( ['src/images/*.{jpg,png}'], { destination: 'src/images', plugins: [ webp( { quality: 60 } ) ] } ) يتم الإخراج من خلال src لتجنب تحميل الأشياء غير المستخدمة في مجلد dist والسماح لمكوِّن إضافي لـ ejs بطلب ملفات .webp مباشرة بواسطة أمر "require".
وأخيراً قم بإنشاء prescript في package.json تكون مخصصة لل production.
"scripts": { "preprod": "node webpack.config.prod.js", "prod": "npm webpack" }
-
إجابة Ali Haidar Ahmad سؤال في التحويل من التنسيق NHWC إلى NCHW في تنسرفلو Tensorflow كانت الإجابة المقبولة
أولاً لنشرح الرموز: N هو عدد الصور ضمن الحزمة (batch). H هو ارتفاع كل صورة. W: عرضها. C عدد القنوات اللونية للصورة.
للتحويل من (N, H, W, C) NHWC ل (N, C, H, W) NCHW:
يجب عليك التبديل بين الأبعاد وهنا سنستخدم الدالة tf.transpose مع استخدام الوسيطة perm للقيام بعملية التبديل:
perm[0] = 0 أي أن البعد الأول من الخرج (البعد الأول للصورة الجديدة) سيكون نفسه في الصورة القديمة.
perm[1] = 3 أي أن البعد الأول من الخرج سيكون نفسه البعد الرابع من الصورة القديمة. ونفس الأمر لبقية الأبعاد:
perm[2] = 1 perm[3] = 2 الآن مثال لتوضيخ الفكرة حيث قمنا بتعريف حزمة من الصور ثم حولنا تنسيقها:
import tensorflow as tf nhwc = tf.placeholder(tf.float32, [None, 50, 150, 3]) # حزمة الإدخال nchw = tf.transpose(nhwc, perm =[0, 3, 1, 2]) print(nchw.get_shape()) # the shape of out is [None, 3, 50, 150] الخرج الآن للتحويل العكسي أي من NCHW ل NHWC نستخدم نفس الفكرة السابقة. مثال:
nchw = tf.placeholder(tf.float32, [None, 3, 50, 150]) nhwc = tf.transpose(images_nchw, [0, 2, 3, 1]) print(nhwc.get_shape()) # the shape of out is [None, 50, 150, 3]
-
إجابة Ali Haidar Ahmad سؤال في ما الفرق بين model.predict و model.evaluate في كيراس Keras و تنسرفلو Tensorflow كانت الإجابة المقبولة
الدالة evaluate تقوم بتوقع (predict) قيم على أساس دخل (input) يمرر لها وتقوم بحساب الدقة و التكلفة (loss) على أساس المعطيات (دالة التكلفة ومعيار الكفاءة metric) الممررة للدالة compile أي نقوم لتمريرالقيم الحقيقية والمتوقعة ويحسب لك الدقة والتكلفة. ولمزيد من التفاصيل يمكنك الانتقال إلى السؤال التالي:
أما بالنسبة للدالة predict فهي تقوم فقط بتوقع القيم على أساس الدخل الممرر لها، وذلك مفيد بالطبع لأنك قد تحتاج هذا القيم، مثلاً تريد استخدام معيار آخر غير معرَف ضمن إطار العمل مثل F1-Score أو تريد التعبير عن النتائج كقيم احتمالية.. إلخ. مثال:
from sklearn.datasets import make_blobs from sklearn.preprocessing import MinMaxScaler as mimx from keras.models import Sequential from keras.layers import Dense # توليد بيانات تصنيف ثنائية الأبعاد data, labels = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1) # تقييس البيانات s = mimx() s.fit(data) data = scalar.transform(data) # توليد بيانات أخرى للاختبار test, _ = make_blobs(n_samples=3, centers=2, n_features=2, random_state=1) test = s.transform(test) # تعريف النموذج model = Sequential() model.add(Dense(8, input_dim=2, activation='relu')) model.add(Dense(8, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='rmsprop') model.fit(data, labels, epochs=461) # prediction prdictedValues = model.predict_classes(test) # عرض القيم المتوقعة لعينات البيانات for i in range(len(Xnew)): print("X=%s, Predicted=%s" % (test[i], prdictedValues[i])) """ X=[0.87935790 0.1206421], Predicted=[0] X=[0.22155783 0.7724488], Predicted=[1] X=[0.70015480 0.96791697], Predicted=[0] """
-
إجابة Ali Haidar Ahmad سؤال في كيفية تعيين معدل تعلم تكيفي ل GradientDescentOptimizer في تنسرفلو Tensorflow كانت الإجابة المقبولة
عموماً لايوجد طريقة مباشرة للقيام بذلك لأن GradientDescentOptimizer يقبل معدل تعلم ثابت (غير متغير) لكن للقيام بذلك نستفيد من فكرة أن وسيطة ال learning_rate في باني ال GradientDescentOptimizer يمكن أن يكون موتر (Tensor)، وبالتالي يمكننا استخدام معدل تعلم مختلف في كل خطوة، على سبيل المثال:
import tensorflow as tf lr = tf.placeholder(tf.float32, shape=[]) # ... # ... train_step = tf.train.GradientDescentOptimizer(name="myOptimizer" learning_rate=learning_rate).minimize(m) mysess = tf.Session() # تمرير قيم مختلفة لمعدل التعلم في كل خطوة تدريب mysess.run(train_step, feed_dict={lr: 0.1}) mysess.run(train_step, feed_dict={lr: 0.01}) mysess.run(train_step, feed_dict={lr: 0.001}) -
إجابة Ali Haidar Ahmad سؤال في ما الفرق بين Session.run و Tensor.eval في تنسرفلو Tensorflow كانت الإجابة المقبولة
eval تقوم بتقييم ال Tensorالذي قام باستدعائها (دالة نستدعيها من خلال الموتر أي: ()tensor.eval). وسيؤدي استدعاء هذه الطريقة إلى تنفيذ جميع العمليات السابقة التي تنتج المدخلات اللازمة للعملية التي تنتج هذا الموتر "التنسر". وطبعاً قبل استدعاء Tensor.eval، يجب أن يكون قد تم تشغيل البيان الخاص به في جلسة Session، ويجب أن تكون الجلسة الافتراضية متاحة ، أو يجب تحديد الجلسة بشكل صريح.
Session.run تقوم أيضاً بتقييم التنسر (run هي دالة نمرر لها الموتر أي: (tensor)Session.run).
نستنتج أنه عندما يكون لدينا موتر ما وليكن t فإن استدعاء t.eval يكافئ استدعاء tf.get_default_session().run(t) مثال:
import tensorflow as tf t = tf.constant(5.0) mysess = tf.Session() with mysess.as_default(): assert sess is tf.get_default_session() assert t.eval() == mysess.run(t) # لن يعطي خطأ لأنهما متساويتان لكن Session.run نستطيع من خلالها الحصول على قيم أكثر من موتر دفعة واحدة، مثال:
t1 = tf.constant(5.0) t2 = tf.constant(4.0) t3 = tf.constant(6.0) mul1 = tf.mul(t1, t2) mul2 = tf.mul(t1,t3 ) with sess.as_default(): # تقييم الموترين دفعة واحدة sess.run([mul1, mul2]) mul1.eval() # تقييم الموتر الأول mul2.eval() # الثاني