اذهب إلى المحتوى

Ali Haidar Ahmad

الأعضاء
  • المساهمات

    1068
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    43

إجابات الأسئلة

  1. إجابة Ali Haidar Ahmad سؤال في تعطيل معلومات التصحيح debugging في تنسرفلو Tensorflow كانت الإجابة المقبولة   
    يمكنك إلغاؤها كلها من خلال os.environ:
    import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' بحيث:
    نقوم بإسناد القيمة 3 لمنع طباعة المعلومات INFO والتنبيهات WARNING و رسائل الأخطاء ERROR messages  أما 2 لمنع ال INFO و ال WARNING messages بينما 1 لمنع المعلومات INFO messages بينما 0 ستؤدي لتسجيل كل الرسائل.
  2. إجابة Ali Haidar Ahmad سؤال في ما الفرق بين tf.placeholder و tf.Variable في تنسرفلو Tensorflow كانت الإجابة المقبولة   
    كلاهما يستخدم لتخزين حالة المتغيرات ضمن ال graph في تنسرفلو (نستخدمهما لتعريف متغيرات ضمن جلسة تنسرفلو) لكن الفرق بينهما هو أن tf.Variable يحتاج إلى تهيئته بقيم أولية بشكل فوري أي بلحظة تعريفه مثلاً:
    w = tf.Variable([[1.], [2.]]) هنا عرفنا متغير ضمن ال graph نسميها عقدة ضمن الغراف (البيان) واسمينها w، لاحظ أننا قمنا بإعطائه قيم مباشرةً. أما بالنسبة ل tf.placeholder فنعَرف أيضاً من خلاله متغيرات لكن هنا لانحتاج لتهيئة المتغيرات بقيم أولية كما في tf.Variable وهذا مهم جداً جداً. لماذا؟ عند بناء نماذج التعلم (الشبكات العصبية مثلاً) فنحن لدينا نوعين من المتغيرات: بيانات الدخل X التي نجلبها من الDataset + الأوزان التدريبية أي w و b. وكما نعلم فإن الأوزان نحتاج لتهيئتها بقيم ابتدائية (عادةً قيم عشوائية) وهذه المتغيرات نسميها trainable variables أي متغيرات قابلة للتدريب (للتحديث) ونستخدم معها tf.Variable . أما بيانات الدخل X و Y فلايتم تهيئتها بقيم ابتدائية حيث أننا نضطر لتعريفها داخل النموذج (بدون تعيين قيم لها) وننتظر أن يتم إعطاءها قيم عندما يتم تغذية الشبكة بال Dataset. ولهذا السبب نحتاج لتعريفهم ك  placeholder. مثال:
    ##################### Variable ################## weights = tf.Variable(tf.truncated_normal([IMAGE_PIXELS, hidden1_units], stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights') biases = tf.Variable(tf.zeros([hidden1_units]), name='biases') ##################### placeholder ############### images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_PIXELS)) labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size)) #################### تغذية الشبكة بالبيانات #### for step in xrange(FLAGS.max_steps): feed_dict = { images_placeholder: images_feed, labels_placeholder: labels_feed, } _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)  
  3. إجابة Ali Haidar Ahmad سؤال في ما هو Slug في جانغو Django؟ ومتى يستخدم؟ كانت الإجابة المقبولة   
    يأتي مصطلح "slug" من المقالات والصحف وهو الاسم الغير رسمي الذي يُطلق على قصة أو مقالة أثناء عملية الإنتاج. أما في جانغو يتم استخدام حقل slug لتخزين وإنشاء عناوين URL صالحة لصفحات الويب التي تم إنشاؤها ديناميكياً. بشكل عام باستخدام البيانات التي تم الحصول عليها بالفعل. على سبيل المثال ، يستخدم slug عنوان المقالة لإنشاء عنوان URL.
    <title> damn cat </title> <content> Wonderful movie </content> <slug> Wonderful-movie </slug> يمكنك إنشاء slug من خلال SlugField:
    slug = models.SlugField(max_length=90)
    وينصح بإنشاء الرابط الثابت عن طريق تابع، بالنظر إلى العنوان أو جزء آخر من البيانات، بدلاً من تعيينه يدوياً. مثال:
    # الآن لنفرض لدينا النموذج التالي class art(models.Model): title = models.CharField(max_length=59) content = models.TextField(max_length=1900) slug = models.SlugField(max_length=50) #وباسم ذو معنى URL يمكنك الإشارة إلى هذا الكائن بعنوان # :بالشكل URL بحيث يكون عنوان Article.id على سبيل المثال استخدام www.slu.com/art/23 # أو www.slu.com/art/damn cat #20% لذا يجب استبدالها ب URL وبما أن المسافات غير مسموحة في عناوين www.example.com/art/damn%20cat #slugأما باستخدام # - يمكننا استبال الفراغات ب www.example.com/article/damn-cat كما يمكنك استخدام التابع slugify لاستخدام ال slug كعنوان:
    from django.template.defaultfilters import slugify class art(models.Model): title = models.CharField(max_length=90) def slug(self): return slugify(self.title) كما يمكنك استخدام الوسيط unique=True إذا أردت جعله فريداً:
    slug = models.SlugField(max_length=90, unique=True)  
  4. إجابة Ali Haidar Ahmad سؤال في إستخدام دالة الجمع sum وكذلك group-by في pandas كانت الإجابة المقبولة   
    يمكننا القيام بذلك من خلال groupby:
    #################################### التجميع على أساس عمود ################################ df = pd.DataFrame({'Animal': ['Falcon', 'Falcon', 'Parrot', 'Parrot'], 'Max Speed': [380., 370., 24., 26.]}) df """ Animal Max Speed 0 Falcon 380.0 1 Falcon 370.0 2 Parrot 24.0 3 Parrot 26.0 """ # التجميع حسب اسم الحيوان ثم تطبيق المتوسط الحسابي على القيم المجمعة df.groupby(['Animal']).mean() """ Max Speed Animal Falcon 375.0 Parrot 25.0 """ أو المجموع لو أردت:
    df.groupby(['Animal']).sum() """ Max Speed Animal Falcon 750.0 Parrot 50.0 """ التجميع على أساس أكثر من عمود:
    df = pd.DataFrame({'Animal': ['Falcon', 'Falcon', 'Parrot', 'Parrot'], 'behaviour': ['carnivorous', 'carnivorous', 'vegetarian', 'vegetarian'], 'Max Speed': [380., 370., 24., 26.]}) # التجميع حسب اسم الحيوان وسلوكه ثم تطبيق المتوسط الحسابي على القيم المجمعة df.groupby(['Animal',"behaviour"]).mean() """ Max Speed Animal behaviour Falcon carnivorous 375.0 Parrot vegetarian 25.0 """  
  5. إجابة Ali Haidar Ahmad سؤال في الفرق بين 'SAME' و  'VALID' في الطبقة tf.nn.max_pool في تنسرفلو tensorflow؟ كانت الإجابة المقبولة   
    الحشو padding   هو الآلية التي ستتبعها الخوارزمية أثناء عملية ال convolution (الالتفاف) على المصفوفة للتعامل مع حدود المصفوفة. ففي حالة قمت بضبطها على Valid فهذا يعني أن الخوارزمية قد تتجاهل حدود المصفوفة، مثلاً إذا كان حجم الخطوة strides هو2 وأبعاد المصفوفة 3*2 سيتم تجاهل العمود الثالث من المصفوفة ولن يدخل في الخوارزمية (فقدان معلومات). لأن حجم الخطوة هو بكسلين وبالتالي لن تستطيع معالجة هذا العمود لوحده لذا تتجاهله ، وطبعاً تكون أبعاد المصفوفة الناتجة أقل دوماً. أما في حالة وضعته على SAME فستقوم الخوارزمية بإضافة عمود جديد إلى اليمين وستضبط قيمه بأصفار (حشو padding) وبالتالي ستصبح المصفوفة 4*2 وبالتالي سيتم أخذ كل الأعمدة بعين الاعتبار وفي هذه الحالة ستكون أبعاد المصفوفة الناتجة هي نفس أبعاد المصفوفة الأصلية (عندما يكون حجم الخطوة 1 ينتج نفس الأبعاد) أو أقل. المعادلة التالية تحدد الأبعاد الناتجة في حالة استخدام VALID:
    output_shape = math.floor((input_shape - ksize) / strides) + 1 (when input_shape >= ksize) أما في حالة استخدمت same فسوف يقوم بعملية الحشو. والمصفوفة الناتجة في هذه الحالة:
    output_shape = math.floor((input_shape - 1) / strides) + 1 إليك بعض الأمثلة:
    import tensorflow as tf # تعريف تنسر matrix = tf.constant([ [0, 0, 1, 7], [0, 2, 0, 0], [5, 2, 0, 0], [0, 0, 9, 8], ]) #max_pool ضبط حجمها بالشكل الذي تتوقعه دالة reshaped = tf.reshape(matrix, (1, 4, 4, 1)) ########################## SAME ######################### #على المصفوفة max_pool تطبيق a1=tf.nn.max_pool(reshaped, ksize=2, strides=2, padding="SAME") a1 """ <tf.Tensor: shape=(1, 2, 2, 1), dtype=int32, numpy= array([[[[2], [7]], [[5], [9]]]], dtype=int32)> """ a1.shape # TensorShape([1, 2, 2, 1]) ########################## VAILD ######################### matrix = tf.constant([ [0, 0, 1, 7], [0, 2, 0, 0], [5, 2, 0, 0], [0, 0, 9, 8], ]) matrix = tf.constant([ [0, 0, 1, 7], [0, 2, 0, 0], [5, 2, 0, 0], [0, 0, 9, 8], ]) reshaped = tf.reshape(matrix, (1, 4, 4, 1)) #على المصفوفة max_pool تطبيق a2=tf.nn.max_pool(reshaped, ksize=2, strides=2, padding="VALID") a2 """ <tf.Tensor: shape=(1, 2, 2, 1), dtype=int32, numpy= array([[[[2], [7]], [[5], [9]]]], dtype=int32)> """ a2.shape # TensorShape([1, 2, 2, 1]) مثال آخر، هنا ستبقى المصفوفة بنفس الأبعاد عند استخدام SAME:
    ########################## SAME ######################### #على المصفوفة max_pool تطبيق a1=tf.nn.max_pool(reshaped, ksize=2, strides=1, padding="SAME") a1 """ <tf.Tensor: shape=(1, 4, 4, 1), dtype=int32, numpy= array([[[[2], [2], [7], [7]], [[5], [2], [0], [0]], [[5], [9], [9], [8]], [[0], [9], [9], [8]]]], dtype=int32)> """ import tensorflow as tf # تعريف تنسر matrix = tf.constant([ [ 0, 1], [ 2, 0] ]) #max_pool ضبط حجمها بالشكل الذي تتوقعه دالة reshaped = tf.reshape(matrix, (1, 2, 2, 1)) ########################## SAME ######################### import tensorflow as tf # تعريف تنسر matrix = tf.constant([ [ 0, 1], [ 2, 0] ]) #max_pool ضبط حجمها بالشكل الذي تتوقعه دالة reshaped = tf.reshape(matrix, (1, 2, 2, 1)) #على المصفوفة max_pool تطبيق a1=tf.nn.max_pool(reshaped, ksize=2, strides=1, padding="SAME") a1 """ <tf.Tensor: shape=(1, 2, 2, 1), dtype=int32, numpy= array([[[[2], [1]], [[2], [0]]]], dtype=int32)> """  
  6. إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ Could not find a version that satisfies the requirement TensorFlow (from versions: ) No matching distribution found for TensorFlow في تنسرفلو Tensorflow كانت الإجابة المقبولة   
    بدءاً من أكتوبر 2020، تنسرفلو تدعم فقط نسخ بايثون ذات ال  64-bit، ونسخ بايثون بدءاً من  3.5. لذلك إذا كنت تستخدم إصداراً ذو 32-bit يجب أن تبدله إلى إصدار 64 بت أو إذا كانت نسخة بايثون لديك ليست ضمن المجال المذكور، فأيضاً عليك تنزيل نسخة ضمن المجال المذكور.
  7. إجابة Ali Haidar Ahmad سؤال في زيادة حجم البيانات Data Augmentation  في كيراس Keras وتنسرفلو Tensorflow باستخدام ImageDataGenerator كانت الإجابة المقبولة   
    نعم يمكنك القيام بذلك من خلال الكلاس الرائع ImageDataGenerator في تنسرفلو وكيراس. حيث يقوم هذا التابع بتوليد صور جديدة من البيانات الأصلية (يقوم بأخذ صورة ثم يطبق عليها مجموعة من التحويلات مثل زيادة السطوع أو تقليله أو قلب الصورة رأسياً أو أفقياً أو تدويرها أو إزاحة البكسلات . إلخ). وروعته في أنه يقوم بتوليد الصور الجديدة في ال  real-time أي بقوم بإنتاجها أثناء تدريب النموذج. وتضمن لك أن النموذج سيتلقى صوراً مختلفة في كل epoch وأيضاً يجب أن تعلم أنه لايقوم بإضافة الصور الجديدة إلى مجموعة البيانات الأصلية (ومن المنطقي جداً حدوث هذا لأنه قد يؤدي إلى ال OF على الصورة). وميزة أخرى لـ ImageDataGenerator هي أنه يتطلب استخدام ذاكرة أقل. حيث يقوم بإنشاء batches بدلاً من توليد كامل مجموعة البيانات ووضعها كلها في الذاكرة. ويمكن  إنشائه بالشكل التالي:
    dataGen=tf.keras.preprocessing.image.ImageDataGenerator( rotation_range=0, width_shift_range=0.0, height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0, channel_shift_range=0.0, fill_mode="nearest", cval=0.0, horizontal_flip=False, vertical_flip=False, rescale=None, data_format=None, validation_split=0.0 ) هذا الكلاس نحدد له العمليات التي نريد تنفيذها على الصور، فبالنسبة لأول وسيط وهو rotation_range فهو يقوم بتدوير الصورة الأصلية بدرجة معينة نقوم بتحديدها (من 0 إلى 360). لكن عندما يتم تدوير الصورة، ستتحرك بعض وحدات البكسل خارج الصورة وتترك مساحة فارغة يجب ملؤها. يمكنك ملء ذلك بطرق مختلفة مثل القيمة الثابتة "constant" أو أقرب قيم البكسل "nearest" .. إلخ. يتم تحديد هذا في وسيطة fill_mode والقيمة الافتراضية هي "nearest" والتي تقوم ببساطة باستبدال المساحة الفارغة بأقرب قيم للبكسل.
    أيضاً قد لا يكون الكائن دائماً في وسط الصورة. للتغلب على هذه المشكلة ، يمكننا إزاحة وحدات البكسل في الصورة إما أفقياً أو رأسياً، ويتم ذلك عن طريق إضافة قيمة ثابتة معينة لجميع وحدات البكسل، ويمكننا القيام بذلك من خلال الوسيطة height_shift_range للإزاحة الرأسية و width_shift_range للإزاحة الأفقية للصورة. إذا كانت القيمة رقم float، فسيشير ذلك إلى النسبة المئوية لعرض أو ارتفاع الصورة المراد إزاحتها. بخلاف ذلك ، إذا كانت القيمة عدد صحيح، فسيتم إزاحة العرض أو الارتفاع ببساطة بواسطة قيم البكسل العديدة هذه.
    يعد قلب الصور أيضاً تقنية رائعة ويمكننا القيام بذلك من خلال الوسيط horizo1ntal_flip و vertical_flip للقلب على طول المحور الرأسي أو الأفقي. ومع ذلك، يجب أن تكون هذه التقنية وفقاً للكائن الموجود في الصورة. على سبيل المثال ، لن يكون القلب الرأسي للسيارة أمراً منطقياً لأنه في البيانات الحقيقية لن يتم اختبار هكذا حالات. أيضاً brightness_range يغير سطوع الصورة بشكل عشوائي. إنها أيضاً تقنية لزيادة البيانات مفيدة للغاية لأن الكائن الخاص بنا لن يكون في حالة إضاءة مثالية في معظم الأوقات. لذلك، يصبح من الضروري تدريب نموذجنا على الصور تحت ظروف الإضاءة المختلفة. ويقبل قائمة من قيمتين عائمتين float ويختار قيمة إزاحة السطوع من هذا النطاق.  أيضاً تمثل القيمة 0.0 حالة عدم إضافة أي سطوع بينما القيمة 1.0 تمثل أعظم سطوع. أيضاً يمكنك عمل zoom in و zoom out للصورة من خلال الوسيط zoom_range حيث تعطيه قائمة بقيمتين تحددان الحد الأدنى والحد الأعلى لعملية ال zoom. أو إذا قمت بتحديد قيمة عائمة، فسيتم إجراء التكبير / التصغير في النطاق:[1-zoom_range ، 1 + zoom_range].
    أي قيمة أصغر من 1 سيتم تكبير الصورة. في حين أن أي قيمة أكبر من 1 سيتم تصغيرها. أيضاً تسمح لك الوسيطة shear_range بتنفيذ عملية غريبة نوعاً ما فهي تشبه إلى حدما عملية التدوير لكنها تمدد الصورة (تمديد للبكسلات) وأيضاً يجب أن تحدد له درجة لكن هذه الدرجة لاتمثل درجة الدوران وإنما درجة تسمى درجة "القص" أو الميل (ليس لدي فكرة جيدة عنها). أيضاً هناك الوسيطة channel_shift_range التي تسمح لك بتطبيق إزاحة أيضاً لكن على قنوات الصورة. الوسيطة fill_mode كما قلنا من أجل تحديد الآلية التي سيتم فيه تعويض البكسلات التي  انتقلت (تغير مكانها). أما cval فتستخدم مع fill mode في حالة اخترنا التكنيك constant وذلك من أجل تحديد القيمة التي نريد التعويض بها (قيمة float طبعاً). أما الوسيطة rescale فهي تمنحنا القدرة على عملي standaraization للصورة (توحيد قيمها لتكون ضمن المجال 0 ل 1) وهذه العملية ضرورية دوماً. أما الوسيط data_format فهو لتحديد ترتيب أبعاد الصورة أي لتحديد فيما إذا كانت القناة هي أخر  بعد "channels_last" أو أول بعد"channels_first" . أما الوسيط الأخير فيسمح لنا بأخذ جزء من البيانات ك validation data. الآن بعد أن تقوم بتحديد هذه الوسطاء لباني الصف هذا، كل ماعليك فعله هو استخدام التايع  flow_from_directory لقراءة الصور مباشرةً من المجلد وتنفيذ ال augmantaion أثناء تدريب الشبكة العصبية على بيانات التدريب. ويتوقع التابع أن الصور التي تنتمي إلى فئات مختلفة موجودة في مجلدات مختلفة ولكنها داخل نفس المجلد الأصلي. وهذا التابع له الشكل التالي:
    ImageDataGenerator.flow_from_directory( directory, # المسار الخاص بالمجلد target_size=(256, 256), # حجم الصور color_mode="rgb", # النمط "grayscale", "rgb", "rgba". Default: "rgb" classes=None, # الفئات ويمكنك تحديدها أولا أي أنه اختياري ['dogs', 'cats'] مثلاً class_mode="categorical", batch_size=32, # حجم الباتش للبيانات shuffle=True, # خلط البيانات أو لا save_to_dir=None, # إذا اردت الاحتفاظ بالصور التي تم توليدها ضع له مسار مجلد ليحفظها فيهم save_format="png", # الامتداد الذي تريد حفظ الصور فيه في حال أردت حفظها follow_links=False, subset=None, interpolation="nearest", # تحديد الطريقة التي سيتم فيها تصغير الصورة في حالة كانت أكبر من الحجم المحدد أو أصغر منه ) بالنسبة للوسيط subset يجب أن تحدد في هذه الوسيطة إما ("training" أو "validation") وذلك في حالة كنت قد حدد جزءاً من البيانات ك validation في باني الكلاس. أما class_mode فهو يحدد نوع البيانات التي لديك أي binary أي أن لديك فئتين وبالتالي سيكون لدينا  1D binary labels، أو categorical سيكون لدينا 2D one-hot encoded labels أو sparse سيكون  1D integer labels. أو None وبالتالي هنا لن يقوم بتوليد ال labels للصور لن ينتج عن المُنشئ سوى مجموعات من بيانات الصورة ، وهو أمر مفيد للاستخدام مع model.predict ()). الآن دعنا نرى تطبيقاً عملياً:
    from keras.models import Sequential from keras.layers import Dense,Conv2D,Dropout,MaxPooling2D,Flatten from keras.preprocessing.image import ImageDataGenerator import cv2 import numpy as np 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 ######################################### obj = ImageDataGenerator( rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) train_generator = obj.flow_from_directory( '/content/safe/train', target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') # validation data val_datagen = ImageDataGenerator(rescale=1. / 255) validation_generator = val_datagen.flow_from_directory( '/content/safe/val', target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') """ Found 2039 images belonging to 2 classes. Found 384 images belonging to 2 classes. """ print(train_generator.class_indices) # {'ClosedFace': 0, 'OpenFace': 1} # Number of Training and Validation Samples nb_train_samples = 2039 nb_validation_samples = 384 ################################## Bulding Model ###############################3 #Instantiation model = Sequential() #1st Convolutional Layer model.add(Conv2D(32, (3, 3), input_shape=(100,100,3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #2nd Convolutional Layer model.add(Conv2D(32, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #3rd Convolutional Layer model.add(Conv2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #Passing it to a Fully Connected layer model.add(Flatten()) # 1st Fully Connected Layer model.add(Dense(64)) model.add(Activation('relu')) # Add Dropout to prevent overfitting model.add(Dropout(0.5)) #Output Layer model.add(Dense(1)) model.add(Activation('sigmoid')) # compile model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy']) # Fitting epochs = 15 batch_size = 16 model.fit_generator( train_generator, steps_per_epoch=nb_train_samples // batch_size, epochs=15, validation_data=validation_generator, validation_steps=nb_validation_samples // batch_size) #fit أيضاً يمكنك استخدام الدالة أيضاً في حالة كانت بياناتك موجودة  ضمن Dataframe يمكنك استخدام  flow_from_dataframe بنفس الطريقة مع اختلاف بسيط وهو تمرير الداتافريم الخاص بك وتحديد العمود الذي يحوي أسماء الملفات والعمود الذي يحوي ال labels:
    ImageDataGenerator.flow_from_dataframe( dataframe, directory=None, x_col="filename", y_col="class", weight_col=None, target_size=(256, 256), color_mode="rgb", classes=None, class_mode="categorical", batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix="", save_format="png", subset=None, interpolation="nearest", validate_filenames=True, )  
  8. إجابة Ali Haidar Ahmad سؤال في كيف يمكن تطبيق دالة على بيانات في شكل dataframe في pandas كانت الإجابة المقبولة   
    يمكنك استخداك الدالة apply كما أشار أحمد وبطرق عديدة، أولاً في حالة كان التابع الخاص بك يمرر له أكثر من قيمة أو كنت تحتاج لتطبيق تابع يستخدم قيم الأعمدة الأخرى لإنشاء عمود جديد، فيمكنك استخدام lambda مع Apply كالتالي:
    # Import pandas package import pandas as pd # تعريف تابع # هذا التابع نمرر له عددين ويقوم بجمعهما def add(v1, v2): return v1 + v2 # تعريف داتافريم data = { 'c1':[1, 2, 3], 'c2':[4, 5, 6] } df = pd.DataFrame(data) # طباعته print("Original DataFrame:\n", df) # تطبيق التابع السابق على كل سطر من أسطر الداتا، بحيث يقوم بجمع كل قيمتين متقابلتين من أعمدة الداتا ويخزنهما في عمود جديد #lambda قمنا باستخدام الدالة df['add'] = df.apply(lambda row : add(row['c1'],row['c2']), axis = 1) print('\nAfter Applying Function: ') # النتيجة print(df) """ Original DataFrame: c1 c2 0 1 4 1 2 5 2 3 6 After Applying Function: c1 c2 add 0 1 4 5 1 2 5 7 2 3 6 9 """ #sumكما أنه كان بإمكانك استخدام الدالة df['add'] = df.apply(np.sum, axis = 1) كما يمكنك استخدام الدالة np.vectorize وهي سريعة جداً وأسرع بكثير من الدالة السابقة ويمكنك استخدامها بالشكل الذي تريده بدون الحاجة ل lambda:
    # Import pandas package import pandas as pd import numpy as np # تعريف تابع def add(v1,v2): return v1 + v2 # تعريف داتافريم data = { 'c1':[1, 2, 3], 'c2':[4, 5, 6] } df = pd.DataFrame(data) print("Original DataFrame:\n", df) df['add'] = np.vectorize(add)(df['c1'], df['c2']) print('\nAfter Applying Function: ') print(df) """ Original DataFrame: c1 c2 0 1 4 1 2 5 2 3 6 After Applying Function: c1 c2 add 0 1 4 5 1 2 5 7 2 3 6 9 """  
  9. إجابة Ali Haidar Ahmad سؤال في كيف نمنع Tensorflow من تخصيص كامل ذاكرة ال GPU؟ كانت الإجابة المقبولة   
    نعم يمكنك تخصيص نسبة من حجم ال GPU أثناء إنشاء الجلسة tf.session، ليتم استخدامها فقط. ويتم ذلك عن طريق تمرير tf.GPUOptions كجزء من وسيطة config، كالتالي:
    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.25) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) حيث افترضنا أن لديك gpu ب 8 جيجابايت، وخصصنا 2 جيجا فقط منها لتكون متاحة خلال الجلسة.
  10. إجابة Ali Haidar Ahmad سؤال في ما المقصود بال epoch في تنسرفلو Tensorflow و كيراس Keras كانت الإجابة المقبولة   
    ال epoch  هو عملية مرور على كامل بيانات التدريب التي لديك، فمثلاً إذا كان لديك 5000 عينة تدريبية، مقسمة إلى 100 باتش-حزمة- (مفهوم ال Mini-Batches) وبالتالي سيكون لدينا حجم كل باتش batch-size يساوي 50 عينة. هذا يعني أنه عند المرور على كامل البيانات (ال 5000 عينة) سنكون قد قمنا ب 100 iteration أي 100 عملية  forward و backward على البيانات (مرور على البيانات ثم تحديث قيم الأوزان في الشبكة). وهذا هو الفرق، ولهذا السبب نستخدم مفهوم ال epoch  بدلاً من ال iteration فهو أعم، ونحتاجه في حالة التعامل مع ال Mini-Batches.
  11. إجابة Ali Haidar Ahmad سؤال في ما المقصود ب logits وما الفرق بين softmax و softmax_cross_entropy_with_logits كانت الإجابة المقبولة   
    أولاً logits في الرياضيات هي دالة تقوم بتعيين الاحتمالات [0 ، 1] إلى [-inf ، + inf]. ثانياً لاترتبك من الاسم، ال logits في تنسرفلو هي فقط مخرجات الطبقة الأخيرة من نموذجك وتمت تسميتها بهذا الاسم كون مخرجات الطبقة الأخيرة من النموذج لاتكون قيم احتمالية وإنما تكون قيم من [-inf, +inf] أي أن مجموعها لايساوي 1. وعند تمرير هذه ال logits  (مخرجات الطبقة الأخيرة من نموذجك) إلى دالة التنشيط Softmax تصبح قيم هذه ال logits احتمالية أي قيمها بين 0 و 1 ومجموعها كلها يساوي 1. هذا كل شيئ. وفي التوثيق الرسمي لتنسرفلو هذا ماتم شرحه عنها: "هي Tensor غير فارغة "  non-empty Tensor " ويجب أن تكون من أحد الأنماط التالية half, float32, float64." الآن بالنسبة ل tf.nn.softmax فهي دالة ال softmax التي نعرفها جميعاً (وفي حال لن تكن على دراية بها يمكنك الذهاب إللى الرابط في الأسفل) :
    import tensorflow as tf import numpy as np logits = tf.constant(np.array([[.1, .3, .5, .9]])) # الدخل هو قيم غير محدودة print((tf.nn.softmax(logits))) # لاحظ أن الخرج أصبح قيم احتمالية بين 0 و1 # tf.Tensor([[0.16838508 0.205666 0.25120102 0.37474789]], shape=(1, 4), dtype=float64) أما بالنسبة ل tf.nn.softmax_cross_entropy_with_logits فهي تطبق الدالة السابقة على ال logits ثم تطبق  cross_entropy على خرجه، أي:   <<< افترض أن لديك فهم للانتروبيا المتقطعة في نظرية المعلومات>>>
    sm = tf.nn.softmax(x) ce = cross_entropy(sm) # وفي تنسرفلو يتم دمج هاتين العمليتين كالتالي tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None) وتستخدم كدالة تكلفة cost  حيث يقيس الخطأ الاحتمالي في مهام التصنيف المنفصلة أي  التي تكون فيها الفئات متنافية (كل إدخال في فئة واحدة بالضبط). على سبيل المثال ، يتم تصنيف كل صورة على أنها كلب أو قطة وليس كلاهما.  وطبعاً كون الفئات متنافية فهذا لايعني بالضرورة أن تكون احتمالاتها متنافية. وكل مايهمنا هو أن يكون التوزيع الاحتمالي لاحتمالاتها صالحاً (أي مجموع ال label يساوي 1) على سبيل المثال:
    logits = [[4.0, 2.0, 1.0], [0.0, 5.0, 1.0]] labels = [[1.0, 0.0, 0.0], [0.0, 0.8, 0.2]] tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits) # <tf.Tensor: shape=(2,), dtype=float32, numpy=array([0.16984604, 0.82474494], dtype=float32)> ويجب أن تكون كل من label و logits من نفس الأبعاد أي [batch_size, num_classes].
    افرض المثال التالي، لدينا مصفوفتي tensor الأولى هي قيم y_hat ولتكن تساوي y = W*x +b أي الأوزان التدريبية مضروبة بالدخل مجموعة على الانحراف (أي القيم المتوقعة من دون إدخالها في دالة تنشيط أي logits)، وو y_true هي القيم الحقيقية.
    y_hat = ... # Predicted label, e.g. y = tf.matmul(X, W) + b y_true = ... # True label, one-hot encoded وبالتالي يكون مقدار الخطأ الكلي للانتروبيا المتقطعة يساوي إلى :
    y_hat_softmax = tf.nn.softmax(y_hat) total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1])) وهو مايكافئ الدالة التالية في تنسرفلو:
    total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
  12. إجابة Ali Haidar Ahmad سؤال في استبدال قيمة بقيمة أخرى داخل dataframe في بايثون كانت الإجابة المقبولة   
    يتم استخدام الدالة replace ولها الشكل التالي:
    Syntax: DataFrame.replace( old value, new value) مثال:
    import pandas as pd # إنشاء قاموس dic1 = {'c1': ['55', '44', '33', '22'], 'c2': ['1', '2', '3', '4']} dic2 = {'c1': [ 'e','f', 'g', 'h'], 'c2': ['argentena', 'barca', 'MachineLearning', 'ali']} # تحويلها لداتا فريم df1 = pd.DataFrame(dic1, columns=['c1', 'c2']) df2 = pd.DataFrame(dic2, columns=['c1', 'c2']) # عرض البيانات display(df1) display(df2) """ c1 c2 0 55 1 1 44 2 2 33 3 3 22 4 """ """ c1 c2 0 e argentena 1 f barca 2 g MachineLearning 3 h ali """ # استبدال القيمة 3 في العمود الثاني من الفريم الأول بالقيمةالثانية من العمود الثاني في الفريم الثاني # تحديد القيمة القديمة المراد استبدالها old = df1['c2'][2] # حيث حددنا العمود الثاني والفهرس الذي يقابل القيمة 3 # تحديد القيمة الجديدة new = df2['c2'][1] # تنفيذ عملية الاستبدال df1 = df1.replace(old,new) # عرض النتيجة display(df1) """ c1 c2 0 55 1 1 44 2 2 33 barca 3 22 4 """ # كما يمكنك استبدالها بقيمة أنت تريدها مثلا old = df1['c1'][0] df1 = df1.replace(old,'hsoub') display(df1) """ c1 c2 0 hsoub 1 1 44 2 2 33 barca 3 22 4 """ # كما ويمكننا استبدال عمود بآخر df1['c1'] = df1.replace(df1['c1'],df1['c2']) display(df1) """ c1 c2 0 hsoub 1 1 44 2 2 33 barca 3 22 4 """ كما يمكنك تمرير الوسيط  inplace=True في حال أردت أن يتم التعديل على المصفوفة الأصلية بدون إنشاء نسخة.
     
  13. إجابة Ali Haidar Ahmad سؤال في كيفية عمل شرط لا يساوي في queryset filtering في جانغو Django؟ كانت الإجابة المقبولة   
    هناك 3 طرق:الأولى استخدام Q() objects مع  معامل النفي ~:
    from django.db.models import Q r = QuerySet.filter(~Q(a=True), x=5) والثانية استخدام exclude مع filter:
    r = Model.objects.exclude(a=True).filter(x=5) والثالثة هي إنشاء custom lookup لكن أولاً عليك إنشاء lookup بنفسك:
    from django.db.models import Lookup class check(Lookup): #lookup اسم ال lookup_name = 'ne' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return '%s <> %s' % (lhs, rhs), params # ثم نقوم بتسجيله from django.db.models import Field Field.register_lookup(check) #في استعلامك __ne lookup الآن يمكنك استخدام results = Model.objects.exclude(a=True, x__ne=5)  
  14. إجابة Ali Haidar Ahmad سؤال في كيف يمكننا معرفة نسخة تنسرفلو الحالية TensorFlow Version كانت الإجابة المقبولة   
    pip list | grep tensorflow أبسط طريقة من خلال ال IDE  التي تعمل عليها (جوبيتر أو سبايدر أو باي شارم..) أو من محرر الأكواد الذي تتعامل معه:
    import tensorflow as tf print(tf.__version__) أو في النسخ الحديثة من تنسرفلو 2x:
    import tensorflow as tf print(tf.version.VERSION) أما بالنسبة للنسخ الأقدم:
    import tensorflow as tf print(tf.VERSION) أو من خلال CLI:
    # ضع الكود التالي فقط python -c 'import tensorflow as tf; print(tf.__version__)' وإذا كانت هناك نسخ متعددة من Python على النظام ، فاستخدم:
    python<version> -c 'import tensorflow as tf; print(tf.__version__)' أيضاً يمكنك من خلال pip:
    pip show tensorflow أو يمكنك استخدام pip list التي تعرض لك كل ماتم تنزيله باستخدام pip install + grep لفلترة النتائج وعرض تنسرفلو فقط (في حالة كنت تستخدم لينوكس)
    pip list | grep tensorflow في حالة ويندوز فيمكنك قلترة النتائج بالشكل:
    pip list | findstr "tensorflow" أما إذا كنت قد ثبت تنسرفلو على بيئة افتراضية Virtual Environment: قم أولاً بتفعيل البيئة الافتراضية:
    virtualenv <environment name> # Linux <environment name>\Scripts\activate # Windows # الآن pip show tensorflow أو من خلال أناكوندا، إذا كنت تعمل عليها:
    conda list | grep tensorflow conda list | findstr "tensorflow"  
  15. إجابة Ali Haidar Ahmad سؤال في ما الفرق بين null و blank في النماذج في جانغو Django؟ كانت الإجابة المقبولة   
    null = True يعين NULL (مقابل NOT NULL) في العمود في قاعدة البيانات الخاصة بك. سيتم تخزين القيم الفارغة لأنواع حقول Django مثل DateTimeField أو ForeignKey على أنها NULL في قاعدة البيانات. يحدد blank ما إذا كان الحقل مطلوباً في النماذج. وهذا يشمل ال admin والنماذج المخصصة الخاصة بك "custom forms". إذا كانت blank = True، فلن يكون الحقل مطلوباً (أي سيقبل القيم الفارغة blank values)، بينما إذا كان False فلا يمكن أن يكون الحقل فارغاً. يكون الجمع بين الاثنين متكرراً جداً لأنه عادةً إذا كنت ستسمح لأحد الحقول بأن يكون فارغاً في النموذج الخاص بك، فستحتاج أيضاً إلى أن تجعل قاعدة البيانات الخاصة بك تسمح بقيم NULL لهذا الحقل. الاستثناء هو CharFields و TextFields، والتي لا يتم حفظها في Django على أنها NULL. يتم تخزين القيم الفارغة في قاعدة البيانات كسلسلة فارغة (""). أمثلة:
    #يعطي خطأ IntegrityError if blank models.DateTimeField(blank=True) #مسموحة NULL قيم models.DateTimeField(null=True) # ولكن يجب تعبئتها في نموذج من الواضح أن هذين الخيارين ليس لهما معنى منطقي للاستخدام (على الرغم من أنه قد يكون هناك حالة استخدام لـ null = True ، blank = False إذا كنت تريد أن يكون الحقل مطلوباً دائماً في النماذج، وهو اختياري عند التعامل مع كائن من خلال شيء مثل ال shell):
    models.CharField(blank=True) #"" سيتم تخزين القيم الفارغة ك #مسموحة NULL قيم models.CharField(null=True) #NULL ولكن لن يتم تعيينها على أنها لا يتم حفظ أنواع CHAR و TEXT كـ NULL بواسطة Django ، لذا فإن null = True غير ضروري. ومع ذلك ، يمكنك تعيين أحد هذه الحقول يدوياً إلى None لفرض تعيينه على أنه NULL. إذا كنت تحتاج لذلك لسبب ما.
  16. إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ TensorFlow not found using pip في تنسرفلو Tensorflow كانت الإجابة المقبولة   
    أنت بحاجة إلى إصدار 64 بت من Python وفي حالتك تستخدم إصدار 32 بت. اعتباراً من الآن ، يدعم Tensorflow إصدارات 64 بت من Python 3.5.x و 3.8.x على Windows. لحل مشكلتك:
    في حال كنت تستخدم Windows (8, 8.1, 10) قم بتثبيتها كالتالي:
    python3 -m pip install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.12.0-py3-none-any.whl بالنسبة ل mac ولينوكس قم بتبديل python3 إلى python حسب التكوين الخاص بك، وقم بتغيير py3 إلى py2 في عنوان url إذا كنت تستخدم Python 2.x.
  17. إجابة Ali Haidar Ahmad سؤال في ظهور الرسالة Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2 في تنسرفلو Tensorflow كانت الإجابة المقبولة   
    الأمر كله يتعلق بال CPU، أولاُ يجب أن تعلم أن لكل معالج مجموعة تعليمات منخفضة المستوى Low-Level هذه التعليمات نسميها ISA، مجموعة التعليمات هذه هي قائمة بجميع الأوامر المتاحة بمختلف أشكالها التي يمكن لمعالج ما تنفيذها، وتتضمن هذه التعليمات: تعليمات حسابية ومنطقية مثل الجمع المنطقي والضرب المنطقي والنفي المنطقي ووووو..  طريقة تعريف هذه التعليمات وتحقيقها يلعب دوراً كبيراً جداً في سرعة المعالج وأدائه. هناك مجموعات تعليمات أساسية تدعمها كل المعالجات الحديثة وهناك توسعات كثيرة لها   "Instruction Set Extensions" مثل  SSE2, SSE4, AVX 2,AVX ..إلخ هذه التوسعات أو الإضافات أو الامتدادات تعطي الحاسب سرعة  وأداء إضافي كبيرة.
    إن هذه الرسالة التي تظهر لك مفادها أن معالجك يدعم مجموعة تعليمات AVX لكن تنسرفلو لاتستفيد منها، هذه التعليمات تنفذ عمليات تسمى  fused multiply-accumulate (FMA) وفائدتها في أنها تسرع من تنفيذ عمليات الجبر الخطي وضرب المصفوفات والجداء النقطي "dot-product"  وعمليات الالتفاف على المصفوفات "convolution"، وكما نعرف جميعنا فإن هذه العمليات هي 90% من العمليات الداخلية التي تنفذ في التعلم الآلي. وبالتالي فإن تسريع حسابها يزيد سرعة الأداء بشكل كبير جداً بنسبة تصل ل 300٪.  حسناً لماذا لاتستفيد منها وتستخدمها؟ السبب هو أن التوزيع الافتراضي لـ tensorflow تم إنشاؤه بدون امتدادات وحدة المعالجة المركزية ، مثل SSE4.1 و SSE4.2 و AVX و AVX2 و FMA وما إلى ذلك ، حيث أن التصميمات الافتراضية  تهدف إلى أن تكون متوافقة مع أكبر عدد ممكن من وحدات المعالجة المركزية. سبب آخر هو أنه حتى مع هذه الإضافات ، تعد وحدة المعالجة المركزية أبطأ بكثير من وحدة معالجة الرسومات GPU ، ومن المتوقع أن يتم تنفيذ تدريب التعلم الآلي على نطاق متوسط وكبير على وحدة معالجة الرسومات GPU.  إذاً ما الحل؟  إذا كان لديك GPU ، فلا يجب أن تهتم بدعم AVX ، وبالتالي يمكنك ببساطة تجاهل هذا التحذير عن طريق (منعه من الظهور):
    import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' أو إذا أردت استخدام تعليمات AVX فهناك تحديثات خاصة لتنسرفلو لكي تدعم هذه التعليمات بأنواعها المختلفة  SSE4.1 و SSE4.2 و AVX و AVX2 و FMA إلخ.، وهي موجودة على gitHub في الرابط التالي: https://reposhub.com/python/deep-learning/lakshayg-tensorflow-build.html 
    بعد أن تقوم بتحميل النسخة التي تريدها فقط ادخل لل cmd:
    pip install --ignore-installed --upgrade /path/to/binary.whl --user حيث تمرر له المسار الذي يتواجد فيه الملف الذي تم تنزيلها، أو يمكنك تحميلها مباشرة من gitHub:
    pip install --ignore-installed --upgrade "Download URL" --user حيث فقط تمرر له رابط النسخة التي نريدها (هناك عشرين نسخة أو أكثر وكل منها لنظام مختلف وتوسعات مختلفة).
    هذا كل شيئ..
  18. إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ ValueError: Input 0 of layer sequential_6 is incompatible with the layer في كيراس Keras كانت الإجابة المقبولة   
    input_shape يمثل شكل البيانات التي ستدخل إلى طبقة معينة من نموذجك وبالتالي يجب أن تكون متوافقة مع حجم بياناتك، حيث أن كل طبقة من طبقات النموذج ستتلقى دخلأ بأبعاد معينة، لكننا لانحتاج لتحديد ذلك سوى لأول طبقة (لأن الطبقات التالية يتم استنتاج الأبعاد فيها لأنها تنتج من اختزال أبعاد الدخل على حجم الخلايا في الطبقة). وبما أن أول طبقة هي Dense فهي تتوقع منك مصفوفة (أو بمعنى أدق tensor) ثنائية الأبعاد تمثل حجم الباتش وعدد الفيتشرز features:
    model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(10000,))) model.add(keras.layers.LayerNormalization()) input_shape=(10000,) تعني أن الدخل سيكون لديه 10 آلاف features (ال axis=0 لانحدده وبالتالي سيتم قبول أي قيمة لحجم الباتش).
  19. إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ ValueError: Data cardinality is ambiguous في كيراس Keras كانت الإجابة المقبولة   
    يظهر هذا الخطأ عندما تكون بيانات التدريب والاختبار غير متوافقة، أقصد بذلك عندما تكون الأبعاد غير متوافقة، أي بمعنى أوضح إذا كانت::
    # في حالة كانت بياناتك هي بيانات تصنيف ثنائي # x أبعاد الدخل shape : (samples,features) #سمها كما شئت y أو label أو ال target فيجب أن تكون أبعاد بيانات الهدف Shape: (samples,) # أي مثلاً X_Shape:(1000,521) --> يجب أن يكون --> y_shape:(1000,) #label أي بمعنى آخر يجب أن يكون لكل عينة من بياناتك قيمة تمثل الهدف أو # في حالة كانت بياناتك بيانات تصنيف متعدد X_Shape : (samples,features) y_shape: (samples,عدد الفئات) # أي في مثالك فإن أبعاد الدخل هي X_Shape : 7982, 10000) # ولدينا 46 فئة وبالتالي أبعاد الهدف تكون (7982, 46) وهنا يخبرك كيراس أن عدد ال samples في بياناتك هو 7982 بينما ال label هو 8982 لذا يظهر خطأ. الحل:
    x_val = x_train[:1000] partial_x_train = x_train[1000:] # هنا y_val = one_hot_train_labels[:1000] partial_y_train = one_hot_train_labels[1000:] # الآن: partial_x_train.shape # (7982, 10000) partial_y_train.shape # (7982, 46) ... ... . . #fit تدريب النموذج من خلال الدالة history = model.fit(tf.convert_to_tensor(partial_x_train, np.float32), partial_y_train, epochs=6, batch_size=512, validation_data=(x_val, y_val),max_queue_size=10) حيث أنك قمت باقتطاع جزء من بيانات التدريب لديك لتكون بيانات validation لكنك نسيت أن تقوم باقتطاع بيانات الهدف أيضاً.
  20. إجابة Ali Haidar Ahmad سؤال في الدالة fit في كيراس Keras كانت الإجابة المقبولة   
    تقوم هذه الدالة يتدريب نموذجك (تدريب الأوزان على المشكلة المعطاة)، ولها الشكل التالي:
    Model.fit( x=None, y=None, batch_size=None, epochs=1, verbose="auto", callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, validation_batch_size=None, validation_freq=1, max_queue_size=10, workers=1, use_multiprocessing=False, ) 1. أول وسيط يشير إلى بيانات الدخل، ويجب أن يكون مصفوفة نمباي (أو نوع آخر يشابهها)، أو قائمة من المصفوفات "list of arrays" (في حالة كان نموذجك متعدد الدخل multiple inputs). أو يمكن أن تكون مصفوفة تنسر "TensorFlow tensor" أو قائمة من التنسر "list of tensors" (في حالة كان نموذجك متعدد الدخل multiple inputs). أو قاموس يربط اسم بمصفوفة أو تنسر في حال كان لمصفوفات الدخل أسماء. أو tf.data مجموعة بيانات مكونة من خلال تنسرفلو، بحيث تكون من الشكل (inputs, targets) أو (inputs, targets, sample_weights).أو مولد generator أو تسلسل keras.utils.Sequence بحيث يعيد (inputs, targets) أو (inputs, targets, sample_weights).
    2. ثاني وسيطة هي بيانات الهدف أو ال Target أو ال label، وبشكل مشابه لبيانات الدخل x يجب أن تكون Numpy array(s) أو TensorFlow tensor(s)، ويجب أن تكوم متسقة مع x، أي بمعنى إذا كانت x تحوي 400 عينة فهذا يعني أنه يجب أن يكون لدينا 400 target، و لايجب أن يكون x نمباي و y تنسر أو العكس. وفي حالة كانت بيانات الإدخال x من النوع dataset, generator, أو keras.utils.Sequence فلا تقم بتمرير قيم ال y لأنهم يحصلون علبها بشكل تلقائي من خلال x.
    3. الوسيط الثالث هو ال batch_size وهو يمثل حجم دفعة البيانات، وهو عدد صحيح يشير إلى عدد العيانات التي سيتم تطبيق خوارزمية الانتشار الأمامي والخلفي عليها في المرة الواحدة. أي مثلاً لو كان لديل 100 عينة وكان حجم الباتش 10 هذا يعني أن هسيكون لديك 10 باتشات وكل باتش يحوي 10 عينات وبالتالي سيتم تطبيق خوارزمية الانتشار الأمامي ثم الخلفي (تحديث الأوزان) على أول باتش ثم ينتقل للباتش الثاني وهكذا.. أيضاً في حالة كانت بيانات الإدخال x من النوع dataset, generator, أو keras.utils.Sequence فلاتقم بتحديد هذا الوسيط لأنهم في الأساس يقومون بتوليد باتشات. وأيضاً في حالة لم تقوم بتعيين قيمة للباتش "None" فسأخذ القيمة الافتراضية 32. 
    4. الوسيط الرابع epochs عدد الحقب التي تريدها لتدريب النموذج، كل حقبة تقابل مرور على كامل مجموعة البيانات. 5. الوسيط الخامس هو ال verbose لعرض تفاصيل عملية التدريب في حال ضبطه على 0 لن يظهر لك تفاصيل عملية التدريب "أي الوضع الصامت"، أما في حالة ضبطه على 1 فهذا يعني أنك تريد أن تظهر لك تفاصيل التديب (الكل يريد هذا طبعاً).  6. الوسيط السادس callbacks قائمة من keras.callbacks.Callback وهي قائمة الاسترجاعات المطلوب تقديمها أثناء التدريب. 7. الوسيط السابع validation_split هو عدد حقيقي بين 0 و ال 1، يحدد نسبة يتم اقتطاعها من بيانات التدريب ليتم استخدامها كعينات تطوير Validaton set، وهذه الخاصية غير مدعومة في حالة كانت بيانات الإدخال x من النوع dataset, generator, أو keras.utils.Sequence. 8. الوسيط الثامن validation_data هو البيانات التي تريد استخدامها كعينات تطوير Validaton set أي لن يستخدمها في عملية التدريب وإنما سيختبر عليها دقة النموذج بعد كل حقبة (تماماً كما في الوسيط السابق)، ويجب أن تكون tuble من الشكل (x_val, y_val) كما يجب أن تكون من نمط البيانات tensors أو مصفوفات نمباي، أو tf.data.Dataset أو generator أو keras.utils.Sequence تعيد (inputs, targets) أو (inputs, targets, sample_weights). 9. الوسيط التاسع shuffle يأخذ قيمة بوليانية لتحديد فيما إذا كنت تريد القيام بعملية خلط للبيانات قبل كل حقبة أو يأخذ str في حالة كنت تريد الخلط قبل كل باتش ونمرر له في هذه الحالة "batch". وفي حالة كانت بياناتك هي مولدات أو tf.data.Dataset سيتم تجاهل هذا الوسيط. ملاحظة: "batch" هي خيار خاص للتعامل مع قيود بيانات HDF5، يخلط في أجزاء chunks بحجم الدُفعة batch-sized chunks. ويكون له تأثير عندما تكون None= steps_per_epoch .  أما الوسيط العاشر 10. فهو ال class_weight وهي عبارة عن قاموس (اختياري) يربط فهارس الفئة (أعداد صحيحة) بوزن (قيمة float) لتوزين دالة التكلفة (خلال فترة التدريب فقط) ويكون استخدامه مفيداً لإخبار النموذج "بإيلاء المزيد من الاهتمام" لفئات الأقلية في حال كانت البيانات غير متوازنة (مثلاً عدد صور القطط 1000 وعدد صور الكلب 4000). 11. الوسيط sample_weight هو مصفوفة أوزان (اختياري) لعينات التدريب وتستخدم أيضاً لتوزين دالة التكلفة.ويمكنك إما تمرير مصفوفة Numpy مسطحة (1D) بنفس طول عينات الإدخال (ربط 1: 1 بين الأوزان والعينات). أو في حالة البيانات الزمنية ، يمكنك تمرير مصفوفة ثنائية الأبعاد ذات شكل (عينات ، طول التسلسل) ، لتطبيق وزن مختلف لكل خطوة زمنية لكل عينة. وهذه الخاصية غير مدعومة في حالة كانت بيانات الإدخال x من النوع dataset, generator, أو keras.utils.Sequence.. 
    الوسيط 12.  هو initial_epoch عدد صحيح. الحقبة التي تبدأ فيها التدريب (مفيدة لاستئناف دورة تدريبية سابقة). 13. steps_per_epoch  عدد صحيح أو None إجمالي عدد الخطوات (مجموعات العينات) قبل الإعلان عن انتهاء حقبة واحدة وبدء المرحلة التالية. عند التدريب باستخدام موترات الإدخال مثل TensorFlow data tensors ، فإن القيمة الافتراضيةNone تساوي عدد العينات في مجموعة البيانات الخاصة بك مقسوماً على حجم الباتش، أو 1 إذا تعذر تحديد ذلك. إذا كانت x عبارة عن tf.data ، وكانت "steps_per_epoch=" None ، فسيتم تشغيل الحقبة حتى يتم استنفاد مجموعة بيانات الإدخال. وهذه الوسيطة غير مدعومة عندما تكون مدخلاتك هي مصفوفات. 14. validation_steps: تعمل فقط إذا تم توفير validation_data  وكانت عبارة عن tf.data. وهي إجمالي عدد الخطوات (باتش من العينات batches of samples) المطلوب سحبها قبل التوقف عند إجراء ال validation في نهاية كل حقبة. إذا كانت "validation_steps" هي None ، فسيتم تشغيل ال validation حتى يتم استنفاد مجموعة بيانات validation_data. أما إذا تم تحديد "Validation_steps" فسيتم استخدام جزء فقط من مجموعة البيانات ، وسيبدأ التقييم من بداية مجموعة البيانات في كل حقبة. وهذا يعني استخدام نفس عينات التحقق في كل مرة. 15. validation_batch_size: عدد العينات لكل دفعة validation. إذا لم يتم تحديدها ، فسيتم تعيينها افتراضياً إلى batch_size. لا تحدد validation_batch_size إذا كانت بياناتك في شكل  dataset, generator, أو keras.utils.Sequence..  (لأنها تولد باتشات). 16. validation_freq: تعمل فقط إذا تم توفير validation_data وهي عبارة عن عدد صحيح أو collections.abc.Container (مثل list ، tuple ، إلخ). إذا كان عدداً صحيحاً ، فإنه يحدد عدد حقب التدريب التي سيتم تشغيلها قبل إجراء عملية تحقق جديدة، على سبيل المثال validation_freq = 2 يتم تشغيل ال validation  كل حقبتين. إذا كانت Container ، فإنها تحدد الحفب التي سيتم فيها تشغيل ال  validation  ، على سبيل المثال Validation_freq = [1 ، 2 ، 10] أي تشغيل ال validation   في نهاية الحقبة الأولى والثانية والعاشرة.  17. max_queue_size: عدد صحيح ، و يستخدم للمولد generator أو keras.utils.Sequence فقط. ويمثل الحجم الأقصى لرتل المولد. إذا لم يتم تحديدها ، فسيتم تعيين max_queue_size افتراضياً على 10.  18. use_multiprocessing: قيمة بوليانية لتحديد فيما إذا كنت تريد استخدام المعالجة المتعددة أم لا وهو مدعوم فقط في حالة generator أو keras.utils.Sequence.
    الآن سأعطيك مثال لاستخدامه في تدريب نموذج:
    from keras.datasets import reuters import keras import tensorflow as tf (train_data, train_labels), (test_data, test_labels) = reuters.load_data( num_words=10000) import numpy as np def vectorize_sequences(sequences, dimension=10000): results = np.zeros((len(sequences), dimension)) for i, sequence in enumerate(sequences): results[i, sequence] = 1. return results x_train = vectorize_sequences(train_data) x_test = vectorize_sequences(test_data) from keras.utils.np_utils import to_categorical one_hot_train_labels = to_categorical(train_labels) one_hot_test_labels = to_categorical(test_labels) x_val = x_train[:1000] partial_x_train = x_train[1000:] y_val = one_hot_train_labels[:1000] partial_y_train = one_hot_train_labels[1000:] from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(10000,))) model.add(keras.layers.LayerNormalization()) model.add(layers.Dense(64, activation='relu')) model.add(keras.layers.LayerNormalization()) model.add(layers.Dense(46, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['CategoricalAccuracy']) #fit تدريب النموذج من خلال الدالة history = model.fit(tf.convert_to_tensor(partial_x_train, np.float32), partial_y_train, epochs=6, batch_size=512, validation_data=(x_val, y_val)) """ Epoch 1/6 16/16 [==============================] - 2s 75ms/step - loss: 1.7822 - categorical_accuracy: 0.6134 - val_loss: 1.1558 - val_categorical_accuracy: 0.7510 ... ... Epoch 6/6 16/16 [==============================] - 1s 56ms/step - loss: 0.1659 - categorical_accuracy: 0.9535 - val_loss: 0.9125 - val_categorical_accuracy: 0.8080 """ كما وترد هذه الدالة كائن History يحوي قيم ال loss وال accuracy لنموذجك في كل حقبة "epoch".  حيث يمكننا الوصول إليهم من خلال الواصفة history من هذا الكائن أي كالتالي History.history:
    history.history """ {'categorical_accuracy': [0.6207717657089233, 0.8475319743156433, 0.9155600070953369, 0.9433726072311401, 0.9516412019729614, 0.9551491141319275], 'loss': [1.70294189453125, 0.7281545996665955, 0.43800199031829834, 0.2743467688560486, 0.2031983882188797, 0.1586201786994934], 'val_categorical_accuracy': [0.753000020980835, 0.7839999794960022, 0.7940000295639038, 0.796999990940094, 0.7900000214576721, 0.7860000133514404], 'val_loss': [1.115304946899414, 0.9754453897476196, 0.9541780948638916, 0.9103594422340393, 0.9673216342926025, 0.9509721994400024]} """  
  21. إجابة Ali Haidar Ahmad سؤال في كيف تعمل الدالة histogram في numpy وما هي فائدتها؟ كانت الإجابة المقبولة   
    bin هو مجال يمثل عرض bar (شريط) واحد من الهستوغرام على طول المحور الأفقي X. كما يمكن أن نسميه بالفاصل الزمني. يقوم هذا التابع بحساب عدد مرات ظهور عناصر من مصفوفة الدخل ضمن مجال معين "bar"، ستفهم أكثر من خلال المثال التالي، لكن سأعطيك مثال من خلال دالة تكافئ هذه الدالة لأن هذه الدالة لاتقوم بالرسم:
    import matplotlib.pyplot as plt plt.hist([1, 2, 2], bins=[0, 1, 2, 3]) plt.show() # bins=[0, 1, 2, 3] تعني أنه سيتم تقسيم المحور الأفقي إلى أريع مجالات تبعاً لهذه القيم # [1, 2, 2] هي الثائمة التي نريد حساب هستوغرامها # وبالتالي هذا التابع يحسب لنا عدد مرات ظهور عناصر من بيانات الدخل ضمن مجال معين # لاحظ أنه ضمن المجال من 0 إلى 1 لايوجد أي عناصر في بيانات الدخل ولهذا لم يظهر لنا البار # ضمن المجال من 1 ل 2 يوجد قيمة وحيدة وهي 1 # لاحظ أن 2 لاتحتسب ضمن المجال وإنما الأصغر تماماً من 2 # الآن ضمن المجال من 2 ل 3 يوجد قيمتين في بيانات الدخل وهما 2 و 2 لذا كانت قمة البار تقابل القيمة 2 على المحور الأفقي
    مثال آخر:
    plt.hist([0,0,1, 2, 2,5,5,5], bins=[0, 1, 2, 3,4,5]) plt.show() # لاحظ أنه ضمن المجال من 3 ل4 لاتوجد أي قيمة في بيانات الدخل لذا كان طول البار يساوي 0 ضمن هذا المجال # كما نلاحظ أن طول البار يساوي 3 ضمن المجال من 4 ل 5 لوجود 3 قيم في بيانات الدخل ضمن هذا المجال # لاحظ أيضاً أنه بالرغم من أن 5 ليست أصغر تماماً لكنها احتسبت ضمن المجال وهذه حالة خاصة لأنها آخر مجال
    لاحظ هنا عند إضافة مجال آخر ستحتسب القيمة 5 ضمن المجال الجديد:
    # هنا سنعبث بالمجالات plt.hist([0,0,1, 2, 2,5,5,5], bins=[0, 1, 2,2.5,5,6]) plt.show() # أو مجال من 0 ل1 والثاني من 1 ل2والثالث من 2 ل 2.5 ويوجد ضمنه قيمتين وهكذا
    دالة np.histogram تعمل بشكل مكافئ تماماً، لكنها لاتقوم بالرسم.
    # أمثلة np.histogram([1, 2, 1], bins=[0, 1, 2, 3]) #(array([0, 2, 1]), array([0, 1, 2, 3])) np.histogram(np.arange(4), bins=np.arange(5), density=True) #(array([0.25, 0.25, 0.25, 0.25]), array([0, 1, 2, 3, 4])) np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3]) #(array([1, 4, 1]), array([0, 1, 2, 3])) ونستخدمها في الأمور الإحصائية أو في مهام معالجة الصور حيث أن حساب هستوغرام صورة يخبرنا بالعديد من المعلومات عن الصورة.
  22. إجابة Ali Haidar Ahmad سؤال في  ما الفرق بين تمرير دالة التنشيط كوسيط أو استخدامها كطبقة Activation في كيراس Keras كانت الإجابة المقبولة   
    أولاً هذه الطبقة تمكننا من إضافة دالة التنشيط التي نريدها إلى نموذجنا تماماً كما في الشكل الذي أضفته، أما بالنسبة للفرق بين الطريقتين فلايوجد فرق من حيث المبدأ لكن الفرق يكون من حيث الاستخدام والهدف، فعندما تريد مثلاً تطبيق ال Bachnormlaization أو ال Layer Normlaization على قيم z فهنا أنت بحاجة لفصل التنشيط عن قيم ال z التي تنتجها الخلايا، لاحظ المثال التالي:
    model = models.Sequential() model.add(layers.Dense(64,input_shape=(10000,))) model.add(keras.layers.LayerNormalization()) model.add(layers.Activation("relu")) model.add(layers.Dense(64)) model.add(keras.layers.LayerNormalization()) model.add(layers.Activation("relu")) model.add(layers.Dense(46, activation='softmax')) وهنا أيضاً:
    AlexNet.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='same')) AlexNet.add(BatchNormalization()) # هنا AlexNet.add(Activation('relu')) AlexNet.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))
  23. إجابة Ali Haidar Ahmad سؤال في ظهور الخطأ <TypeError: The added layer must be an instance of class Layer. Found: <keras.layers.core.Dropout object at 0x000001622999A5F8 في كيراس Keras كانت الإجابة المقبولة   
    السبب في قيامك بالخلط مابين Keras API و tensorflow.keras، فهما منفصلتين، فالأولى هي إطار العمل كيراس أما الثانية فهي كيراس نفسها لكن بعد أن تم دمجها كموديول في تنسرفلو عملية الدمج هذه قد تنتج أخطاءاً تتعلق بالتوافق في بعض الأحيان عندما تقوم باستخدامهما في نموذجك معاً، حيث قمت هنا بتهيئة معمارية sequential من tensorflow.keras وإضافة طبقات لها من  Keras API لذا استخدم إما   Keras API أو tensorflow.keras. وبالتالي يكون :
    from tensorflow.keras.layers import Conv2D,MaxPooling2D from tensorflow.keras.datasets import mnist from tensorflow.keras.models import Sequential import tensorflow.keras from tensorflow.keras.layers import Dense, Dropout, Flatten model = Sequential() model.add(Conv2D(30,(3,3),padding="valid",kernel_initializer="glorot_uniform", activation="tanh", input_shape=(28, 28, 1) )) model.add(Conv2D(30,(3,3), activation="tanh")) model.add(MaxPooling2D((2,2)) model.add(Dropout(0.4)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dropout(0.4)) model.add(Dense(10, activation='softmax'))  
  24. إجابة Ali Haidar Ahmad سؤال في تطبيق تقنية Layer Normalization في كيراس Keras كانت الإجابة المقبولة   
    إذا لم تكن على دراية بهذا المفهوم فيجب أولاً أن تقوم بقراءة الإجابة عن هذا السؤال، فهو مرتبط به تماماً، حيث أن ال Layer Normalization هي تعديل على ال batch normalization:
    في batch normalization كنا نقوم بحساب المتوسط mean وال variance اعتماداً على حجم ال batch أما هنا فنقوم بحسابه اعتماداً على عدد الخلايا في الطبقة أي أن هذه المعملات الإحصائية يتم حسابها بشكل مستقل عن الباتش. وهذا هو الفرق بينهما. وسبب ظهورها هو أن ال batch normalization لاينفع مع مع شبكات RNNs (وهذا هو السبب الرئيسي). حيث أنه في هذا النوع من الشبكات يكون لدينا بيانات متسلسلة "sequential data" فالجمل تكون بأطوال مختلفة وبالتالي الاعتماد على الاحصائيات التي نحصل عليها بالنسبة لحجم الباتش يكون أمراً غير دقيق بالمرة. لذا أتت هذه الفكرة وهي حساب هذه المعاملات الإحصائية بالنبسة لكل عينة من البيانات أي عملياً (لكل جملة في حالة ال sequential data). في كيراس له الشكل التالي:
    tf.keras.layers.LayerNormalization( axis=-1, epsilon=0.001, center=True, scale=True, beta_initializer="zeros", gamma_initializer="ones", beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None, ) هذه الوسطاء هي نفسها في ال batch normlaization (يمكنك العودة إلى الرابط الذي قدمته في الأعلى). وفي المثال التالي أبين لك كيف يمكنك استخدامه مع الشبكة العصبية (بشكل مشابه لل batch norm):
    model = tf.keras.models.Sequential([ tf.keras.layers.Reshape((28,28,1), input_shape=(28,28)), tf.keras.layers.Conv2D(filters=16, kernel_size=(3,3),data_format="channels_last"), # LayerNorm Layer لإضافة طبة tf.keras.layers.LayerNormalization(axis=3 , center=True , scale=True), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax') ]) حيث قمنا بتطبيق Layernormalization بعد طبقة Conv2D واستخدام مقياس وعامل إزاحة.
    مثال آخر لاستخدامه مع نموذج لتحليل مراجعات الأفلام IMDB:
    from keras.datasets import reuters import keras (train_data, train_labels), (test_data, test_labels) = reuters.load_data( num_words=10000) import numpy as np def vectorize_sequences(sequences, dimension=10000): results = np.zeros((len(sequences), dimension)) for i, sequence in enumerate(sequences): results[i, sequence] = 1. return results x_train = vectorize_sequences(train_data) x_test = vectorize_sequences(test_data) from keras.utils.np_utils import to_categorical one_hot_train_labels = to_categorical(train_labels) one_hot_test_labels = to_categorical(test_labels) x_val = x_train[:1000] partial_x_train = x_train[1000:] y_val = one_hot_train_labels[:1000] partial_y_train = one_hot_train_labels[1000:] from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(10000,))) model.add(keras.layers.LayerNormalization()) model.add(layers.Dense(64, activation='relu')) model.add(keras.layers.LayerNormalization()) model.add(layers.Dense(46, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['CategoricalAccuracy']) history = model.fit(partial_x_train, partial_y_train, epochs=6, batch_size=512, validation_data=(x_val, y_val)) ########################## أو يمكنك تطبيقها قبل استخدام دالة التنشيط ######################### model = models.Sequential() model.add(layers.Dense(64,input_shape=(10000,))) model.add(keras.layers.LayerNormalization()) model.add(layers.Activation("relu")) model.add(layers.Dense(64)) model.add(keras.layers.LayerNormalization()) model.add(layers.Activation("relu")) model.add(layers.Dense(46, activation='softmax'))  
  25. إجابة Ali Haidar Ahmad سؤال في تحويل مصفوفة Numpy من نوع int32 إلى float32 بدون نسخها كانت الإجابة المقبولة   
    الطريقتين السابقتين تعتمدان على إنشاء مايسمى view لكن ماهو هذا ال view وكيف ينتج.. دعنا نفهم ذلك؟ ال view أو المشهد هو عرض جديد للمصفوفة مع نفس البيانات. أو بمعنى أوضح فكما يقول اسمها، إنها ببساطة طريقة أخرى لعرض بيانات المصفوفة. من الناحية الفنية ، هذا يعني أنه تتم مشاركة بيانات كلا الكائنين. هذا العرض الجديد للمصفوفة ينتج في حالتين الأولى عند قيامك بتطبيق مفهوم ال slicing (مثلاً عرض جزء من المصفوفة أو كاملها)، أو تغيير نمط البيانات (أو كليهما). وفيما يلي توضيح أكبر. وله الشكل التالي في بايثون:
    ndarray.view([dtype][, type]) # الوسيط الأول هو نمط البيانات الذي تريده # الوسيط الثاني نوع العرض الذي سيتم إرجاعه أمثلة، أولاُ سنعطي مثال لكيفية إنتاج مشهد للمصفوفة من خلال مفهوم التشريح أو slicing:
    # Slice views أخذ شرائح من المصفوفة أو أقسام محددة منها # المصفوفة الناتجة تكون عبارة عن مشهد من المصفوفة الأصلية بحيث تتم مشاركة البيانات import numpy as np arr = np.arange(8) arr # array([0, 1, 2, 3, 4, 5, 6, 7]) # الآن سنطبق مفهوم الشرائح ve = arr[1:2] ve # array([1]) # سنعدل قيمة في المصفوفة الأصلية لنرى فيما إذا كان حقاً قد تم تشارك البيانات arr[1] = 2 # لاحظ كيف تغيرت هي أيضاً ve # array([2]) # مثال آخر ve1 = arr[1::3] ve1 # array([1, 4, 10]) arr[7] = 10 ve1 #array([1, 4, 7]) الآن الطريقة الأخرى لإنتاج مشهد وهي تغيير نمط البيانات (حل مشكلتك):
    # Dtype views import numpy as np arr = np.arange(8, dtype='int32') arr # array([0, 1, 2, 3, 4, 5, 6, 7], dtype=int32) v = arr.view('float32') v """ array([0.e+00, 1.e-45, 3.e-45, 4.e-45, 6.e-45, 7.e-45, 8.e-45, 1.e-44], dtype=float32) """ # حسناً هنا صحيح أنهما تشاركا البيانات لكن حصل تشويه وهذ منطقي جداً لاختلاف حجم البايت بين النمطين (أنت تحاول تغيير النمط في نفس المكان) للقيم لذا يمكننا أن نعود بعد ذلك لفكرة التشريح # نقوم بإسناد قيم المصفوفة الأصلية ذات النمط الصحيح إلى المشهد ذو القيم الحقيقية v[:]=arr v[:] # array([0., 1., 2., 3., 4., 5., 6., 7.], dtype=float32) #وبالتالي هنا نكون حصلنا على مانريده # الآن لو نظرنا لقيم المصفوفة الأصلية arr """ array([ 0, 1065353216, 1073741824, 1077936128, 1082130432, 1084227584, 1086324736, 1088421888], dtype=int32) """ # ولو قمنا بتعديل أي قيمة فيها arr[2]=0 v # array([0., 1., 0., 3., 4., 5., 6., 7.], dtype=float32) # نلاحظ أن التعديل أنتقل إلى المصفوفة هذا يعني أنهما يتشاركان البيانات ########################################################################### #false مع تحديد النسخ على Astype بالنسبة لاستخدام #view فلا أظنها ترجع # كما أنني لم ارى ذلك في التوثيق # انظر للمثال التالي import numpy as np arr = np.arange(8, dtype='int32') arr # array([0, 1, 2, 3, 4, 5, 6, 7], dtype=int32) vv = arr.astype(np.float32, copy=False) vv # array([0., 1., 2., 3., 4., 5., 6., 7.], dtype=float32) arr[0]=5 arr # array([5, 1, 2, 3, 4, 5, 6, 7], dtype=int32) vv # array([0., 1., 2., 3., 4., 5., 6., 7.], dtype=float32) # لاحظ أنه لم يحدث أي تغيير لذا لاأظنها حلاً لمشكلتك  
×
×
  • أضف...