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

Ali Haidar Ahmad

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

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

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

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

    43

كل منشورات العضو Ali Haidar Ahmad

  1. يمكنك الوصول إلى أي جزء من أجزاء المصفوفة اعتماداً على مفهوم ال slicing في نمباي: import numpy as np arr = [[1, 2, 3], [7, 0, 7], [0, 8, 2]] arr = np.array(arr) print(arr) print('0th row: ') print(arr[0, :]) print('2nd column: ') print(arr[:, 2]) # يمكن أيضًا تحديد عدة أعمدة أو صفوف print('0th and 1st row:') print(arr[:,[0,1]]) """ [[1 2 3] [7 0 7] [0 8 2]] 0th row: [1 2 3] 2nd column: [3 7 2] 0th and 1st row: [[1 2] [7 0] [0 8]] """ يمكنك أيضاً استخدام مفهوم ال Ellipsis: # numpy_Array_name[…,column] للاعمدة # numpy_Array_name[row,…] للاسطر import numpy as np arr = [[1, 2, 4], [5, 6, 8], [7, 2, 2]] a = np.array(arr) print(a) print('0th column: ') print(a[..., 0]) print('1st row: ') print(a[1, ...]) """ [[1 2 4] [5 6 8] [7 2 2]] 0th column: [1 5 7] 1st row: [5 6 8] """ المزيد من الأمثلة: #i:j:k #i فهرس البداية #j فهرس التوقف #k الخطوة x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) x[1:7:2] #array([1, 3, 5]) x[-2:10] #array([8, 9]) x[-3:3:-1] #array([7, 6, 5, 4]) x[5:] #array([5, 6, 7, 8, 9]) x = np.array([[[1],[2],[3]], [[4],[5],[6]]]) x.shape #(2, 3, 1) x[1:2] """array([[[4], [5], [6]]]) """ x[...,0] """ array([[1, 2, 3], [4, 5, 6]]) """
  2. الإجابة التالية حسب توثيق باندا. عندما نضع low_memory=False فهذا يعني أن باندا ستقرأ الأعمدة بأكملها أولاً، ثم يتم تحديد الأنواع المناسبة لكل عمود. على سبيل المثال، سيتم الاحتفاظ بالعمود ككائنات (سلاسل) حسب الحاجة للحفاظ على المعلومات. (وهذا سيئ للذاكرة). إذا كان low_memory = True (الافتراضي)، فإن الباندا تقوم بمعالجة الملف داخلياً ضمن "chunks" (طريقة منهجية للتقسيم إلى أجزاء بحيث يسهل تجميعها لاحقأ)، ثم لاحقاً يقوم بدمجها معاً. مما يؤدي إلى استخدام أقل للذاكرة أثناء عملية ال parsing (التحويل من نمط بيانات إلى نمط آخر)، بعد ذلك، قد تكون بعض الأعمدة مثلاً "chunks of integers and strings" أي مزيج من السلاسل والأعداد الصحيحة، وهنا قد تحدث مشكلة مثلاً عنصر لم يستطع باندا تحويله من نمط إلى آخر وبالتلي قد ينتج عمود كل قيمه أعداد صحيحة ماعدا عنصر واحد لم يستطع باندا تحويله إلى عدد صحيح، لذا في حال حدوث ذلك ولو لمرة واحدة، فستظهر رسالة تحذرك من ذلك لأن هذا قد يسبب مشاكل لاحقاً ولذلك فمن الآمن أكثر أن نحدد نوع البيانات لكل عمود من خلال الوسيطة dtype وبالتالي سيفهم باندا مباشرة عند قراءة العمود نوع بيانات كل عمود وبالتالي تجنب حدوث أي مشاكل وهذا ماعليك القيام به دائماً دائماً: # هنا نحدد ال dtype df = pd.read_csv(csv_file,sep=';', encoding = 'ISO-8859-1',names=['c1','c2'], dtype={'c1':str,'c2':int}) أو نضع low_memory=False لنضمن أنه لن تكون هناك أنواع مختلطة (أي لتضمن عدم وجود عمود به قيم من أنماط مختلفة) أي أيضاً سيتم حل الأمر، لكن هذا الأمر سيكون على حساب الكفاءة كما أشرنا. df = pd.read_csv('data.csv', low_memory=False) وفي حال أردت فلترة التحذير: import warnings warnings.filterwarnings('ignore', message="^Columns.*")
  3. نستخدم verbose لمراقبة عملية تدريب النموذج خلال مرحلة ال Validation بحيث: إذا وضعنا لها القيمة 0 فهذا يعني أن عملية التدريب ستكون صامتة كما نسميها أو مخفية عنك أو بعنى آخر لن ترى أي شيء خلال عملية التدريب، وإذا وضعنا لها القيمة 1 فهذا يعني أنك ستكون قادر على مراقبة عملية التدريب ورؤية النتائج بعد كل epoch وسيظهر لك شريط يمثل عملية التقدم خلال كل epoch أثناء التدريب، وفي حال وضعت 2 لن فسيكون الأمر مشابهاً للحالة السابقة لكن بدون شريط التقدم، انظر للأمثلة التالية التي توضح الأمر جيداً. ############################################ verbose=1 ############################################################## from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() # يمكنك تمريره إلى طبقتك بالشكل التالي # أو tf.keras.activations.relu() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1)) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ----------------------------------------------------------------------------------------- Epoch 1/7 404/404 [==============================] - 3s 1ms/step - loss: 321.6080 - mae: 14.8919 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 20.1112 - mae: 3.1887 Epoch 3/7 404/404 [==============================] - 1s 1ms/step - loss: 20.4705 - mae: 2.8889 Epoch 4/7 404/404 [==============================] - 1s 1ms/step - loss: 17.5232 - mae: 2.5841 ETA: 0s - loss: 13.2 Epoch 5/7 404/404 [==============================] - 0s 1ms/step - loss: 14.8107 - mae: 2.4500 Epoch 6/7 404/404 [==============================] - 1s 1ms/step - loss: 18.6534 - mae: 2.6635 Epoch 7/7 404/404 [==============================] - 0s 1ms/step - loss: 13.8696 - mae: 2.2664 ############################################ verbose=2 ############################################################## Epoch 1/7 404/404 - 1s - loss: 146.2869 - mae: 8.8513 Epoch 2/7 404/404 - 0s - loss: 26.0904 - mae: 3.3522 Epoch 3/7 404/404 - 0s - loss: 19.3153 - mae: 2.8920 Epoch 4/7 404/404 - 0s - loss: 15.3334 - mae: 2.7163 Epoch 5/7 404/404 - 0s - loss: 13.5590 - mae: 2.5430 Epoch 6/7 404/404 - 0s - loss: 13.1906 - mae: 2.4175 Epoch 7/7 404/404 - 0s - loss: 12.6008 - mae: 2.3849 ############################################ verbose=0 ############################################################## لن يظهر أي شيء
  4. هذا أمر مهم في بعض الحالات عندما نستخدم الطبقات التلاففية، يمكنك القيام بذلك في كيراس من خلال model.layers[index].output حيث أنها تقوم بإعطاء خرج أي طبقة من خلال تمرير رقم الطبقة أي ال index الخاص بها. ومن خلالها يمكنك الحصول على طلبك وهو خرج كل طبقة كالتالي: from keras import backend as K #placeholder إدخال ال in = model.input # مخرجات كل الطبقات outputs = [layer.output for layer in model.layers] # تابع التقييم functor = K.function([in , K.learning_phase()], outputs ) # الاختبار test = np.random.random(input_shape)[np.newaxis,...] layer_outs = functor([test, 1.]) print layer_outs ولمحاكاة عملية التسرب (أقصد التنعيم وتحديداً ال Dropout هنا)، استخدم learning_phase كـ 1. في layer_outs وإلا استخدم 0. حيث أننا نحتاجها في حال احتوى النموذج على طبقة Dropout أو batchnorm كما تعلم.
  5. في نمباي يمكنك القيام بذلك من خلال التابع split كالتالي: import numpy as np a = np.array([[1,2,3,4], [5,6,7,8]]) a1 = np.split(a,2,axis=1) التابع split يقوم بقسّم مصفوفة إلى مصفوفات فرعية متعددة. وله الشكل التالي: numpy.split(ary, indices_or_sections, axis=0) # ary: المصفوفة المراد تقسيمها إلى مصفوفات فرعية # indices_or_sections: التقسيمات. ويقبل عدد صحيح أو مصفوفة ببعد واحد # axis: تمثل المحورالذي نريد التقسيم على أساسه وافتراضياً يساوي 0 بالنسبة للوسيط الثاني الخاص بالتقسيمات، فإذا كانت التقسيمات عدداً صحيحاً N ، فسيتم تقسيم المصفوفة إلى مصفوفات N متساوية على طول المحور.
  6. من أجل تسجيل غرض من الصف البعيد في مسجل RMI باسم ما، نستطيع استخدام الطريقة bind والطريقة rebind ولكن الفرق الأساسي بينهما هو أن rebind تستخدم حتى لوكان الاسم موجود مسبقاً (تكتب فوقه)، لكن عندها سيتم إتلاف عملية ال binding السابقة واستبدالها بالجديدة (أي تحذف القديمة وتضع الجديدة) بينما bind لايمكنها القيام بذلك حيث تقوم برمي استثناء في حال كان الاسم موجود بالفعل AlreadyBoundException ومن حيث الاستخدام فالطريقتين السابقتين متشابهتين، كلاهما تأخذان متحولين ( اسم ما للغرض ، الغرض البعيد). نقوم أولا بإنشاء مسجل RMI من خلال استدعاء الطريقة الستاتيكية creatRegistry الموجودة ضمن الصف LocateRegistry، ونحجز له بورت هنا مثلاً (1999): Registry r = LocateRegistry.createRegistry(1999); ثم نأخذ غرض وليكن rb من الصف البعيد ( RemoteObject مثلاً) ونقوم بتسجيله في مسجل RMI بالاسم ("object1") عبر استدعاء إحدى الطريقتين: r.bind("object1", rb); r.rebind("object1", rb);
  7. واجهة تنسرفلو تم تحديثها من set_random_seed() إلى set_seed(): import tensorflow as tf tf.random.set_seed()
  8. ReLU (Rectified Linear Unit) هو تابع تنشيط خطي على القسم الموجب وخطي على القسم السالب، لكن تركيبهما هو مابعطيه الصفة اللاخطية، له الشكل الرياضي البسيط التالي: max(0,x) بحيث من أجل دخل x>0 سيكون خرجه هو x نفسها (أي لاتغيير أي كأننا لم نستخدم تابع تنشيط أي None ) ومن أجل دخل أصغر من الصفر يكون الخرج 0، هذا يعني أنه يسلك سلوك None من أجل الجزء الموجب وكما نعلم فإن أسعار المنازل هي دوماً موجبة وبالتالي استخدام relu سيكون مكافئاً ل None ولكن أفضل لأنه في حالة توقع النموذج قيمة سالبة للنموذج سوف يقصرها على 0 أي إذا توقع -5 سوف يجعلها 0 بسبب تابع ال relu ولهذا السبب كان استخدامه يعطي نتيجة أفضل، لكن هذا لايعني أن استخدامه صحيح وخصوصاً إذا كانت القيم السالبة ضمن مجال التوقع، وأيضاً استخدامه قد يضلل نموذجك قليلاً في الوصول للقيم الصغرى الشاملة لذا أنا أفضل عدم استخدامه. الشكل البياني للتابع: كما نلاحظ فإن قيم المشتق تساوي الصفر أيضاً من أجل القيم السالبة (ليس أمراً جيداً لأنه يسبب بطء لكنه مهمل هنا)، بينما من أجل القيم الموجبة يكون حالة مثالية للتدريب حيث أن قيمة المشتق تكون كبيرة وثابتة (القيمة تساوي 1 كما نلاحظ في الرسم). وهذا يجعل عملية التدريب أسرع (التقارب من القيم الصغرى الشاملة). أحد سلبيات هذا التابع أنه يقوم بتحويل جميع القيم السالبة إلى صفر، اي أنه في حالة القيم السالبة سينظر إليها التابع بشكل واحد وهو الصفر, مما قد يتسبب بخسارة معلومات هامة أثناء تدريب الشبكة. في كيراس أو تنسرفلو له الشكل التالي: tf.keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0) بحيث أن x هي tensor أو متغير ما. أما alpha فيتحكم في ميل القيم الأقل من العتبة. أما max_value فهي التي تحدد عتبة التشبع (أكبر قيمة سترجعها الدالة). أما الوسيط الأخير فهو العتبة أي إعطاء القيمة الحدية لوظيفة التنشيط التي تحتها القيم التي سيتم تثبيطها أو ضبطها على الصفر. وافتراضياً تكون 0. ولاستخدامه في تدريب نموذجك يمكنك استخدامه مع جميع الطبقات في الشبكة عدا طبقة الخرج. وشخصياً أنصحك باستخدامه في جميع طبقات شبكتك (عدا طبقة الخرج طبعاً) لأنه سيجعل نموذجك يتقارب من القيم الصغرى بشكل أسرع كما ذكرت. إليك المثال التالي الذي سأقوم فيه باستخدام هذا التابع في تدريب نموذجي، أول مثال لمهمة توقع: from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() # يمكنك تمريره إلى طبقتك بالشكل التالي # أو tf.keras.activations.relu() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1)) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ------------------------------------------------- Epoch 1/7 404/404 [==============================] - 1s 967us/step - loss: 338.1444 - mae: 15.1877 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 21.6941 - mae: 3.1332 Epoch 3/7 404/404 [==============================] - 0s 1ms/step - loss: 17.6999 - mae: 2.8479 Epoch 4/7 404/404 [==============================] - 0s 947us/step - loss: 13.1258 - mae: 2.4018 Epoch 5/7 404/404 [==============================] - 0s 970us/step - loss: 15.7603 - mae: 2.6360 Epoch 6/7 404/404 [==============================] - 0s 1ms/step - loss: 12.1877 - mae: 2.3640 Epoch 7/7 404/404 [==============================] - 0s 965us/step - loss: 9.7259 - mae: 2.2152 و لاستخدامه مع مهام التصنيف، يكون أيضاً بنفس الطريقة.
  9. يعتبر هذا التابع تابع لوجيستي "logistic function" وهو تابع غير خطي، الشكل الرياضي له: g=sigmoid(x) = 1 / (1 + exp(-x)). والشكل البياني لهذا التابع هو كالتالي: نلاحظ من الخط البياني للتابع أن قيمه تتراوح بين 0 و 1، حيث: عندما z=-∞ تكون قيمة التابع g=0 وعندما z=0 يكون g=0.5 وعندما z=+∞ يكون g=1. ومن الرسم البياني نلاحظ أنه يمكن استخدامه في تدريب النماذج (أقصد أنه يعطي قيماً مختلفة عن الصفر أي هناك تغيرات في ميل المماس)، وكما نلاحظ من الرسم (المنحني الأزرق) فإن المشتق تكون قيمه فعالة للتدريب عندما تكون قيم z قريبة من الصفر ولكن من أجل قيم كبيرة جداً أو صغيرة جداً فلن تكون فعالة في التدريب لأن المماس يكون شبه مستقيم وبالتالي قيمة المشتقة تكون صغيرة جداً، مما يؤدي الى بطء شديد في عملية التدريب وبالتالي مكلف من الناحية الحسابية. إن الاستخدام الشائع والأهم والأفضل لهذا التابع هو استخدامه كمصنف في آخر طبقة من نموذج عندما تكون المهمة مهمة تصنيف ثنائي حيث أن خرجه يكون قيمة احتمالية بين 0 و 1 وبالتالي خيار ممتاز لمهام التصنيف الثنائي. وفي كيراس وتنسرفلو له الشكل التالي: tf.keras.activations.sigmoid(x) مثال: a = tf.constant([-20, -1.0, 0.0, 1.0, 20], dtype = tf.float32) b = tf.keras.activations.sigmoid(a) b.numpy() # الخرج array([2.0611537e-09, 2.6894143e-01, 5.0000000e-01, 7.3105860e-01, 1.0000000e+00], dtype=float32) لاستخدامه في نماذجك، يمكنك استخدامه في أي طبقة، لكن كما ذكرت يفضل استخدامه فقط في آخر طبقة عندما تكون المهمة مهمة تصنيف ثنائي كما في المثال التالي: from keras.datasets import imdb from keras import preprocessing max_features = 10000 maxlen = 20 (x_train, y_train), (x_test, y_test) = imdb.load_data( num_words=max_features) x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen) # هنا حددنا طول الكلمات ب 20 x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen) # بناء نموذجك from keras.models import Sequential from keras.layers import Flatten, Dense model = Sequential() model.add(Embedding(10000, 8, input_length=maxlen)) model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) # آخر طبقة model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc']) model.summary() # تدريبه history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
  10. يجب أن يتم تمرير الموتر "Tensor" إلى الطبقة عند استدعائها، وليس كوسيطة. أو ببمعنى آخر الأٌقواس () مفقودة لذلك يجب أن تعدله كالتالي: # إنشاء طبقة layer = Flatten() #tensor استدعاءها على z = layer(z) # أو بشكل أبسط z = Flatten()(z) انظر لهذا المثال أيضاً سينتج نفس الخطأ والحل بنفس الطريقة: def create(input_shape = (100, 100, 3)): input_img = Input(shape=input_shape) model = efnB0_model (input_img) model = GlobalMaxPooling2D(model) # سيعطي نفس الخطأ model = Dropout(0.2)(model) backbone = model ... ... return model
  11. يجب عليك تخزين numpy.ndarray بتنسيق JSON أو أي تركيب من ال nested-list: import json import numpy as np class NumpyEncoder(json.JSONEncoder): # مشفر جيسون خاص للنوع نمباي def default(self, obj): if isinstance(obj, np.integer): return int(obj) elif isinstance(obj, np.floating): return float(obj) elif isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) dumped = json.dumps(data, cls=NumpyEncoder) with open(path, 'w') as f: json.dump(dumped, f) حيث أن JSON هو "Javascript Object Notation" وبالتالي يمكنه فقط تمثيل التركيبات الأساسية من لغة جافا سكريبت: كائنات (مماثلة لل dict ببايثون) ، ومصفوفات (مماثلة لقوائم بيثون) ، وأرقام ، وبيانات بوليانية، وسلاسل ، و nulls. أما المصفوفات Numpy ليست أياً من هذه الأشياء، وبالتالي لا يمكن تحويلها إلى تسلسل "serialised" في JSON. لذلك نلجأ للطريقة السابقة
  12. المشكلة في التعليمات البرمجية الخاصة بك هي أنك تريد تطبيق العملية على كل صف. الطريقة التي كتبتها بها تأخذ عمودي "bar" و "foo" بالكامل ، وتحولها إلى سلاسل وتعطيك سلسلة واحدة . لذا يمكنك حل المشكلة بالشكل التالي: from pandas import * import numpy df = DataFrame({'foo':['a','b','c'], 'bar':[1, 2, 3]}) df.apply(lambda x:'%s is %s' % (x['bar'],x['foo']),axis=1) ومن خلال نمباي يمكنك القيام بذلك باستخدام الكلاس numpy.chararray حيث نقوم بتحويل الأعمدة إلى تسلسل على هيئة chararrays، ثم نقوم بدمجهم معاً كالتالي: from pandas import * import numpy d = DataFrame({'foo':['a','b','c'], 'bar':[1, 2, 3]}) def join(d): a = numpy.char.array(d['bar'].values) b = numpy.char.array(d['foo'].values) bar=(a + b' is ' + b).astype(str) return DataFrame({'bar':bar}) join(d) """ bar 0 1 is a 1 2 is b 2 3 is c """
  13. هذه تصنيفات تتبع لتصنيف فلين الكلاسيكي Flynn's Classical Taxonomy وهو تصنيف يميز بين الحواسيب متعددة المعالجات ويتم التصنيف على أساس بعدين مستقلين: الأول: مجرى التعليمات Instruction Stream والثاني Data Strem مجرى البيانات، حيق أن كل بعد من هذه الأبعاد يمكنه فقط أن يأخذ إحدى الحالتين : (مفرد) single أو Multiple (متعدد). إذاً لدينا بعدين وحالتين وبالتالي يكون لدينا 2*2=4 وبالتالي نحصل على الأصناف الأربعة التالية: 1.SISD: Single Instruction strem Single Data stream 2.SIMD: Single Instruction strem Multiple Data stream 3.MISD: Multiple Instruction strem Single Data stream 4.MIMD: Multiple Instruction strem Multiple Data stream 1.تعليمة مفردة،بيانات مفردة: تمثل حالة حاسب تسلسلي(وليس تفرعي أبداً).بحيث تعليمة مفردة تعني أن مجرى واحد للتعليمات يتم استخدامه من قبل المعالج في كل نبضة ساعة. وبيانات مفردة تعني أن مجرى واحد للبيانات يتم استخدامه كدخل للمعالج في كل نبضة ساعة. وهذا النمط يمثل الحواسيب الأقدم. 2. تعليمة مفردة، بيانات متعددة: عبارة عن حاسب تفرعي (التفرعية هنا من وجهة نظر البيانات)، وفي هذا النمط يظهر تعدد المعالجات. بحيث تعليمة مفردة تعني أن كل وحدات المعالجة تنفذ نفس التعليمة في كل نبضة ساعة. وبيانات متعددة تعني أن كل وحدة معالجة تستطيع التعامل مع عنصر بيانات مختلف (لها ممر خاص بها) مثال: في عملية جمع عناصر مصفوفة يمكن أن يتم تقسيم المصفوفة إلى عدة أقسام 4 أقسام مثلاً وكل معالج يأخذ قسم وينفذ عليه عملية الجمع+، ثم في النهاية تجمع نواتج الأقسام الأربعة. 3. تعليمات متعددة، بيانات مفردة: تمثل حالة حاسب تفرعي أيضاً (التفرعية هنا من وجهة نظر التعليمات )، وبصراحة لايوجد الكثير من الأمثلة لهذا النمط لكن ينطبق على الحالات التي يكون فيها من الممكن تطبيق أكثر من عملية (جمع وضرب مثلاً) بنفس الوقت على نفس البيانات لكن أشهر أمثلتها هو خوارزميات التشفير المتعددة التي تحاول فك شيفرة رسالة مشفرة مثلاً إذا كان لدينا رسالة نود تشفيرها ولدينا مرحلتين الأولى جعل الأحرف كبيرة والثانية إضافة 35 حسب جدول الآسكي، هنا نلاحظ أنه لدينا نوعين من التشفير (نوعين من التعليمات) والبيانات نفسها (الرسالة) إذاً MISD فهنا الرسالة تتألف من عدة أحرف --> كل حرف يمر أولاً على p1 ويشفر، ثم هو نفسه يمر على p2 ويشفر (لكن بعد فاصل زمني قصير لكي يتم التشفير بشكل صحيح). وطبعاً تعليمات متعددة تعني أن كل حاسب يعمل على البيانات بشكل مستقل عن الوحدات الأخرى عبر مجاري تعليمات مستقلة "Separate instruction streams". وبيانات مفردة تعني أن مجرى بيانات وحيد يستخدم لتغذية كل وحدات المعالجة. 4. تعليمات متعددة، بيانات متعددة: حاسب تفرعي (التفرعية هنا من جانب التعليمات والبيانات). بحيث كل معالج ينفذ تعليماته الخاصة على مجرى تعليمات مختلف. وكل معالج يعمل على مجرى بيانات مختلف. والتنفيذ هنا يكون متزامن أو غير متزامن، وحالياً الأجهزة الشائعة من الحاسبات تستخدم هذا النمط.
  14. هذا خطأ شائع يقع فيه المبتدئين، وهو استخدام توابع التنشيط في آخر طبقة من طبقات نماذج التوقع، يجب أن تتذكر دوماً أن مسائل التوقع Regression تكون فيها قيم الخرج قيم مستمرة أي قيم غير محدودة بمجال معين أي ليست كما في ال classifications حيث يكون فيها الخرج قيم متقطعة أي قيم معينة. لذلك لايجب استخدام أحد توابع التنشيط معها ولاسيما توابع التنشيط اللوجستية مثل التابع السيني sigmoid أو حتى tanh. لأن هذين التابعين خرجهما يكون بين ال 0 وال 1 (بالنسبة للسيني) و من 1 لل -1 (بالنسبة لل tanh). وبالتالي إذا استخدمت أحدهما في آخر طبقة سيكون خرج نموذجك قيماً محصورة بمجال محدد وهذا خاطئ لأنه في أي مهمة توقع ولتكن مهمة توقع أسعار المنازل مثلاً، يجب أن يكون الخرج قيماً تنتمي إلى مجال غير محدود (قيم مستمرة) أما إذا استخدمت التابع السيني مثلاً سيكون خرج النموذج من أجل أي عينة قيمة محصورة بالمجال من 0 ل 1 والقيمة الحقيقية قد تكون 100 أو 50 أو 77 أو أو.. وبالتالي سيكون مقدار الخطأ في التوقع كبير جداً. لذا يجب ضبط تابع التنشيط في آخر طبقة على None دوماً. حسناً أنت تتساءل لماذا تابع ال relu يعطيك نتائج جيدة، وهذا صحيح فبالفعل قد يعطيك نتائج جيدة وفي بعض الأحيان قد يعطيك نتائج أفضل من عدم استخدام تابع تنشيط أي None كالمثال التالي، حيث سنستخدم relu والخطأ المطلق mae=2.2152: from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation='relu')) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ------------------------------------------------- Epoch 1/7 404/404 [==============================] - 1s 967us/step - loss: 338.1444 - mae: 15.1877 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 21.6941 - mae: 3.1332 Epoch 3/7 404/404 [==============================] - 0s 1ms/step - loss: 17.6999 - mae: 2.8479 Epoch 4/7 404/404 [==============================] - 0s 947us/step - loss: 13.1258 - mae: 2.4018 Epoch 5/7 404/404 [==============================] - 0s 970us/step - loss: 15.7603 - mae: 2.6360 Epoch 6/7 404/404 [==============================] - 0s 1ms/step - loss: 12.1877 - mae: 2.3640 Epoch 7/7 404/404 [==============================] - 0s 965us/step - loss: 9.7259 - mae: 2.2152 أما بدونه mae: 2.3221: from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation=None)) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ----------------------------------------------- Epoch 1/7 404/404 [==============================] - 1s 1ms/step - loss: 280.0789 - mae: 13.5154 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 19.4468 - mae: 3.0621 Epoch 3/7 404/404 [==============================] - 0s 1ms/step - loss: 17.4921 - mae: 2.9243 Epoch 4/7 404/404 [==============================] - 0s 1ms/step - loss: 14.3356 - mae: 2.6068 Epoch 5/7 404/404 [==============================] - 0s 1ms/step - loss: 12.1125 - mae: 2.4581 Epoch 6/7 404/404 [==============================] - 0s 952us/step - loss: 16.5646 - mae: 2.5852 Epoch 7/7 404/404 [==============================] - 0s 1ms/step - loss: 12.4237 - mae: 2.3221 حسناً كما تلاحظ فإن النتيجة أفضل مع relu، والسبب في أن التابع relu هو تابع خطي خرجه من الشكل: max(x, 0) بحيث من أجل دخل x>0 سيكون خرجه هو x نفسها (أي لاتغيير أي كأننا لم نستخدم تابع تنشيط أي None ) ومن أجل دخل أصغر من الصفر يكون الخرج 0، هذا يعني أنه يسلك سلوك None من أجل الجزء الموجب وكما نعلم فإن أسعار المنازل هي دوماً موجبة وبالتالي استخدام relu سيكون مكافئاً ل None ولكن أفضل لأنه في حالة توقع النموذج قيمة سالبة للنموذج سوف يقصرها على 0 أي إذا توقع -5 سوف يجعلها 0 بسبب تابع ال relu ولهذا السبب كان استخدامه يعطي نتيجة أفضل، لكن هذا لايعني أن استخدامه صحيح وخصوصاً إذا كانت القيم السالبة ضمن مجال التوقع، وأيضاً استخدامه قد يضلل نموذجك قليلاً في الوصول للقيم الصغرى الشاملة لذا أنا أفضل عدم استخدامه.
  15. أنت تحاول الوصول إلى ال history من دون أن تقوم بتخزينها، لذا قم بتخزين ال history حيث أن التابع model.fit يعيد History object وهذا الكائن لديه العضو history من النمط dict لذا: ########################## في جزء التدريب###################### # بدلاً من model1.fit(data, label, validation_split=0.2, epochs=13) model2.fit(data, label, validation_split=0.2, epochs=13) model3.fit(data, label, validation_split=0.2, epochs=13) # اكتب history1=model1.fit(data, label, validation_split=0.2, epochs=13) history2=model2.fit(data, label, validation_split=0.2, epochs=13) history3=model3.fit(data, label, validation_split=0.2, epochs=13) ######################### في جزء الرسم ######################### plt.plot(history1.history['val_loss'], 'r', history2.history['val_loss'], 'b', history3.history['val_loss'], 'g')
  16. قد تواجهك نفس المشكلة على Windows10 . لذلك أيضاً إذا واجه شخص ما هذه المشكلة في Windows، فيمكن حله من خلال زيادة حجم ال pagefile (جزء محجوز من ال hard disk يستخدم كامتداد لذاكرة الوصول العشوائي (RAM))، حيث أن المشكلة تتعلق بالذاكرة الزائدة "overcommitment". لذا اتبع الخطوات التالية: 1.اضغط زر إبدأ 2.اكتب SystemPropertiesAdvanced 3.اختر Run as administrator 4. Performance --> اختر Settings --> Advanced --> Change 5.قم بإلغاء تحديد "Automatically managing paging file size for all drives" 6.حدد Custom size --> املأ الحجم المناسب 7.اضغط Set --> OK --> exit من "Virtual Memory" و "Performance Options" و "System Properties Dialog" 8.أعد تشغيل النظام الخاص بك أيضاً هناك حل آخر هو التبديل من إصدار 32 بت إلى إصدار 64 بت من Python. حيث أنه يمكن لبرنامج 32 بت ، مثل وحدة المعالجة المركزية 32 بت ، معالجة 4 جيجابايت كحد أقصى من ذاكرة الوصول العشوائي (2 ^ 32). لذلك إذا كان لديك أكثر من 4 غيغابايت من ذاكرة الوصول العشوائي، فلا يمكن لإصدار 32 بت الاستفادة منها. مع إصدار 64 بت من Python (الإصدار المسمى x86-64 في صفحة التحميل) ، تختفي المشكلة.
  17. نعم يمكنك ذلك عن طريق تغيير عدد الوسائط التي يقبلها الباني أو عن طريق تغيير نوع بيانات الوسطاء . لاحظ المثال التالي: حيث قمنا بعمل overload للباني Ali. حيث في الاستداعء الأول للباني قمنا باستدعاء الباني ذو الوسيطة الوحيدة (وستتم التهيئة ب 1.1) أما في الاستدعاء الثاني فسيتم تنفيذ الباني ذو الوسيطتين وستتم التهيئة ب 2.5. class Ali { float x; public Ali(float y) { x=y; } public Ali(float y, float m) { System.out.println("Hi"); if(y>m) { x=y; } else { x=m; } } } public class Main { public static void main (String args[]) { Ali t1 = new Ali(1.1); Ali t2 = new Ali(3, 2.5); System.out.println(t1.x); System.out.println(t2.x); } } حيث أننا هنا قمنا بتغيير عدد الوسطاء، ويمكنك أيضاً أن تقوم بتغيير نوع البيانات: class Ali { int x=0; public Ali(int y) { x=y; } float z=0.0; public Ali(float y) { z=y; } } public class Main { public static void main (String args[]) { Ali t1 = new Ali(1.1); // سيؤدي إلى استدعاء الباني الثاني Ali t2 = new Ali(3); // سيؤدي إلى استدعاء الباني الأول } }
  18. هذه الطبقة كما يشير اسمها هي طبقة تسطيح (أو تسوية أو إعادة تشكيل) المدخلات. نستخدمها عادة مع النماذج عندما نستخدم طبقات RNN و CNN. ولفهمها جيداً سأشرحها مع المثالين التاليين، الأول مع مهمة تحليل مشاعر imdb أي مع مهمة NLP وسنستخدم طبقات RNN وسنتحتاج إلى الطبقة flatten: from keras.datasets import imdb from keras import preprocessing max_features = 10000 maxlen = 20 (x_train, y_train), (x_test, y_test) = imdb.load_data( num_words=max_features) x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen) x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen) # بناء النموذج from keras.models import Sequential from keras.layers import Flatten, Dense model = Sequential() model.add(Embedding(10000, 8, input_length=maxlen)) # هنا سنتحتاج لإضافة طبقة تسطيح model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc']) model.summary() history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2) حسناً هنا قمنا بتسطيح الخرج الناتج من طبقة التضمين Embedding أي قمنا بتسطيح (تحويل) ال 3D tensor التي أنتجتها طبقة التضمين إلى 2Dtensor بالشكل التالي (samples,maxlen * 8)( أي عدد العينات أو الباتشز لايتأثر كما أشرنا في التعريف وإنما يتم إعادة تشكيل الفيتشرز). لقد قمنا هضه العملية لأن الطبقة التي تلي طبقة التضمين هي طبقة من نوع Dense وهي طبقة تستقبل 2D tensor ولاتستقبل 3D وبالتالي وجب علينا تسطيح مخرجات طبقة التضمين. مثال آخر: def lstm_model_flatten(): embedding_dim = 128 model = Sequential() model.add(layers.Embedding(vocab_size, embedding_dim, input_length=maxlen)) model.add(layers.LSTM(128, return_sequences = True, dropout=0.2)) # Flatten layer هنا أيضاً سنحتاج model.add(layers.Flatten()) model.add(layers.Dense(1,activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary() return model هنا استخدمنا طبقة التسطيح لأن مخرجات طبقة lstm هي 3D كما نعلم وذلك لأننا ضبطنا return_sequences على true، والطبقة التالية هي dense وبالتالي لابد من تسطيح المخرجات بنفس الطريقة. الآن حالة آخرى مع الطبقات التلاففية حيث أنني بنيت نموذج لتصنيف الأرقام المكتوبة بخط اليد: from keras import layers from keras import models from keras.datasets import mnist from keras.utils import to_categorical (train_images, train_labels), (test_images, test_labels) = mnist.load_data() train_images = train_images.reshape((60000, 28, 28, 1)) train_images = train_images.astype('float32') / 255 test_images = test_images.reshape((10000, 28, 28, 1)) test_images = test_images.astype('float32') / 255 train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels) # بناء النموذج model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) # هنا سنتحتاجها model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax')) # تدريب النموذج model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=5, batch_size=64) حسناً، إن خرج كل طبقة Conv2D و MaxPooling2D هو 3D Tensor من الشكل (height, width, channels). إن آخر خطوة من بناء الشبكة التلاففية هو إضافة طبقة أو مجموعة طبقات dense وبالتالي تتم تغذية هذه الطبقة بآخر tensor أنتجتها طبقاتنا التلاففية (هنا (64, 3, 3)) وكما ذكرنا فإن dense لاتستقبل 3D وبالتالي يجب تسطيحها، ,وبالتالي هنا سيكون ناتج تسطيح الخرج هو شعاع 1D أبعاده 64*3*3 وهذا ماسوف تتغذى به طبقات ال dense.
  19. إن الطبقات التي نقوم باستخدامها في keras و tensorflow هي طبقات تتعامل مع بنية بيانات نسميها tensor (بنية خاصة أكثر كفاءة من بنى المصفوفات العادية)، حيث أن هذه الطبقات صممت بحيث يمكنها أن تستقبل بيانات من نوع numpy.array ثم تحولها تلقائياً إلى tensor. لكن هذه الطبقات لاتتعامل مع القوائم وأنت تمرر لها قائمة وهذا خطأ شائع، لذا يجب أن تحول بياناتك إلى مصفوفة نمباي أولاً وستحل مشكلتك: import numpy data = numpy.array(data) label = numpy.array(label)
  20. لقد قمت بتعريف نموذجك مع مخرجين [output1, output2]، لذلك من المتوقع أن يتم عمل ال fitting مع مصفوفتين مختلفتين من ال label. واحدة بحجم (, 119) والأخرى (,2) وهذا مايتوافق مع طبقتي الإخراج Dense لديك. الحل: g = ImageDataGenerator() def generate_data_generator(g, X, Y1, Y2): genX1 = generator.flow(X, Y1, seed=7) genX2 = generator.flow(X, Y2, seed=7) while True: X1i = genX1.next() X2i = genX2 .next() yield X1i[0], [X1i[1], X2i[1]] model.fit_generator(generate_data_generator(generator, x_train, y_train, y_train_gender), steps_per_epoch=len(x_train) / 16, epochs=5)
  21. قم بتبديل: from keras.applications.imagenet_utils import _obtain_input_shape إلى: from keras_applications.imagenet_utils import _obtain_input_shape فهي غير موجودة في keras.applications.imagenet_utils، يمكنك أن تجدها في keras_applications.imagenet_utils
  22. فقط استدعي ()tensor.numpy على ال Tensor object # tensorflow_version 2.x # مثال1 import tensorflow as tf t = tf.constant([[1, 2], [4, 8]]) a = t.numpy() print(a) print(type(a)) """ [[1 2] [4 8]] <class 'numpy.ndarray'> """ # مثال 2 import tensorflow as tf a = tf.constant([[1, 2], [3, 4]]) b = tf.add(a, 1) a.numpy() # array([[1, 2], # [3, 4]], dtype=int32) b.numpy() # array([[2, 3], # [4, 5]], dtype=int32) tf.multiply(a, b).numpy() # array([[ 2, 6], # [12, 20]], dtype=int32) إذا كانت النسخة هي TensorFlow version 1.x استخدم: tensor.eval(session=tf.compat.v1.Session()) مثال: # tensorflow_version 1.x import tensorflow as tf t = tf.constant([[1, 2], [4, 8]]) a = t.eval(session=tf.compat.v1.Session()) print(a) print(type(a)) أيضاً يجب أن تعلم أنه بمجرد استخدامك لأي عملية من عمليات نمباي على ال tensor سوف تتحول تلقائياً إلى numpy array، في الكود التالي مثلاً ، نقوم أولاً بإنشاء Tensor وتخزينه في متغير t عن طريق إنشاء ثابت Tensor ثم استخدام تابع الضرب في TensorFlow والناتج هو نوع بيانات Tensor أيضاً . بعد ذلك ، نقوم بإجراء عملية np.add () على Tensor التي تم الحصول عليها من خلال العملية السابقة. وبالتالي ، تكون النتيجة عبارة عن NumPy ndarray حيث تم إجراء التحويل تلقائيًا بواسطة NumPy. import numpy as np import tensorflow as tf #tensor إنشاء كائن t = tf.constant([[1, 2], [4, 8]]) t = tf.multiply(t, 2) print(t) # تطبيق عملية من نمباي a = np.add(t, 1) print(a) # هذا كل شيء
  23. يحدد العنصر <a> ارتباطاً تشعبياً "hyperlink"، يتم استخدامه للربط والانتقال من صفحة إلى أخرى. وأهم واصفة فيه هي href التي من خلالها نحدد الوجهة"عنوان URL". أما لتحديد المكان الذي سيتم فيه فتح الصفحة فنستخدم الواصفة target كالتالي. فتح صفحة الرابط في نافذة أو علامة تبويب جديدة، نستخدم target=_blank: <a href="xyz.html" target="_blank"> Link </a> في نفس الإطار الذي تم النقر فوقه (هذا هو الشكل الافتراضي): <a href="xyz.html" target="_self"> Link </a> في الإطار الأب "parent frame": <a href="xyz.html" target="_parent"> Link </a> في كامل جسم النافذة "full body": <a href="xyz.html" target="_top"> Link </a> في إطار مسمى: <a href="xyz.html" target="framename"> Link </a>
  24. عندما تكون الصورة غير متلائمة مع التنسيق وتريد تغيير حجمها، فيمكنك القيام بذلك في HTML. من أبسط الطرق لتغيير حجم صورة في HTML استخدام سمات الطول والعرض height و width في العنصر img. حيث يمكنك من خلالهما أن تحدد ارتفاع وعرض الصورة. على سبيل المثال الصورة التالية حجمها 960*640 : يمكننا عرضها بارتفاع 500 بكسل وعرض 400 بكسل: <img src="https://ik.imagekit.io/ikmedia/women-dress-2.jpg" width="400" height="500" /> إذا كان الارتفاع والعرض المطلوبان للصورة لا يتطابقان مع الأبعاد الفعلية للصورة، فسيقوم المتصفح بتقليص أو توسيع الصورة تلقائياً. وتختلف عملية التوسيع أو التقليص حسب الخوارزمية التي يستخدمها المتصفح. لكن يجب أن تعلم أن عملية تغيير حجم الصورة له جوانب سلبية على جودة الصورة وعرضها (حيث يسبب بطئ في عرضها) وطبعاً هناك حلول أخرى لذلك مثل استخدام "ImageKit.io" لتغيير حجم الصورة بشكل ديناميكي اعتماداً على معاملات URL (يمكنك البحث في الموضوع فهو مهم جداً). انظر مثلاً: https://ik.imagekit.io/ikmedia/woman.jpg للحصول على صورة بعرض 200 بكسل، سنضيف معامل استعلام tr بقيمة w-200 كما هو موضح أدناه: https://ik.imagekit.io/ikmedia/woman.jpg?tr=w-200
  25. قبل كل شيء المتوسط المتحرك في علم الإحصاء، المتوسط المتحرك (MA) هو عملية حسابية تُستخدم لتحليل نقاط البيانات (العينات) عن طريق إنشاء سلسلة من المتوسطات لمجموعات فرعية مختلفة من مجموعة البيانات الكاملة. ويستخدم في عالم الأموال، حيث أن المتوسط المتحرك (MA) هو مؤشر سهم يستخدم بشكل شائع في التحليل التقني. والسبب في حساب المتوسط المتحرك للسهم هو المساعدة في تسهيل بيانات السعر عن طريق إنشاء متوسط سعر محدث باستمرار. ومن خلال حساب المتوسط المتحرك ، يتم تخفيف آثار التقلبات العشوائية قصيرة الأجل على سعر السهم خلال إطار زمني محدد. لن أخوض في تفاصيله الممتعة أكثر. له نوعان، Simple Moving Average: أبسط شكل من أشكال المتوسط المتحرك ، والمعروف باسم المتوسط المتحرك البسيط (SMA) ، يتم حسابه بأخذ المتوسط الحسابي لمجموعة معينة من القيم. بمعنى آخر ، يتم جمع مجموعة من الأرقام - أو الأسعار في المجال المالي - معًا ثم تقسيمها على عدد الأسعار في المجموعة. (وهو النوع الأكثر استخداماً) SMA=(A1+A2+..+AN)/n A:nهي المتوسط في الفترة N: عدد الفترات الزمنية Exponential Moving Average (EMA): يعطي وزناً أكبر للأسعار الحديثة في محاولة لجعله أكثر استجابة للمعلومات الجديدة. لحساب المتوسط المتحرك الأسي: EMAt=[Vt×S/(1+d)]+EMAy×[1−S/(1+d)] EMAt: لليوم Vt: هي القيمة لليوم EMAy: للأمس S: التنعيم d:عدد الأيام الآن كيف نطبقه في بايثون: 1.الطريقة الأولى: قم بإنشاء قائمة فارغة تحتوي على المتوسطات المتحركة. قم بالمرور على القائمة الأصلية باستخدام حلقة while. في كل تكرار ، استخدم فهرسة القائمة للحصول على النافذة الحالية. استخدم sum(iterable) / w_s ثم أضف هذه النتيجة إلى قائمة المتوسطات المتحركة: li = [6, 7, 10, 12] # حجم النافذة w_s = 3 i = 0 moving_averages = [] j=len(li) - w_s + 1 while i < j: this_window = li[i : i + w_s] window_avg = sum(this_window) / w_s moving_averages.append(window_avg) i += 1 print(moving_averages) 2. من أجل القوائم الكبيرة تقدم باندا طريقة فعالة هي pandas.Series(data) لتحويل القائمة إلى pandas.Series object. ثم استدعي pandas.Series.rolling (window_size) للحصول على كائن يحتوي كل نافذة، ثم استدعي pandas.Series.mean لإيجاد المتوسط لكل نافذة : li = [6, 7, 10, 12] w_s = 3 pd = pd.Series(li) windows = pd.rolling(w_s) moving_averages = windows.mean() # pandas.Series.tolist() لتحويلها لقائمة moving_averages_list = moving_averages.tolist() # حذف القيم Nan w = moving_averages_list[w_s - 1:] print(w) 3.باستخدام نمباي: 4. والطريقة الأكثر سرعة هي استخدام uniform_filter1d من scipy فهي أسرع بنحو 50 مرة من np.convolve و 2-5 مرات من cumsum : from scipy.ndimage.filters import uniform_filter1d import numpy N = 1000 x = numpy.random.random(100000) y = uniform_filter1d(x, size=N) لاحظ: %timeit y1 = np.convolve(x, np.ones((N,))/N, mode='same') 100 loops, best of 3: 9.28 ms per loop %timeit y2 = uniform_filter1d(x, size=N) 10000 loops, best of 3: 191 µs per loop إليك التحقيقات الثلاثة التي ذكرتها: import numpy as np import scipy.ndimage.filters as ndif from __future__ import division #cumsum استخدام def running_mean_cumsum(x, N): cumsum = np.cumsum(np.insert(x, 0, 0)) return (cumsum[N:] - cumsum[:-N]) / float(N) #convolve استخدام def running_mean_convolve(x, N): return np.convolve(x, np.ones(N) / float(N), 'valid') #uniform_filter1d وأخيراً def running_mean_uniform_filter1d(x, N): return ndif.uniform_filter1d(x, N, mode='constant', origin=-(N//2))[:-(N-1)]
×
×
  • أضف...