البرنامج التعليمي RNN (الشبكة العصبية المتكررة): مثال TensorFlow
⚡ ملخص ذكي
تُضيف الشبكات العصبية المتكررة حالة ذاكرة إلى الخلايا العصبية العادية، حيث تُعيد تغذية كل مُخرج كمدخل تالٍ، مما يسمح للنموذج بالتعلم من الترتيب. يشرح هذا الدليل كيفية بناء نموذج كهذا باستخدام TensorFlow والتنبؤ بسلسلة زمنية.
لماذا نحتاج إلى شبكة عصبية متكررة (RNN)؟
تتيح لك الشبكة العصبية المتكررة (RNN) تصميم وحدات الذاكرة للاحتفاظ بالبيانات ونموذج التبعيات قصيرة المدى. كما أنها تستخدم في التنبؤ بالسلاسل الزمنية لتحديد ارتباطات البيانات وأنماطها. كما أنه يساعد على إنتاج نتائج تنبؤية للبيانات المتسلسلة من خلال تقديم سلوك مماثل للدماغ البشري.
هيكل شبكة اعصاب صناعية هي بسيطة نسبيًا وتعتمد بشكل أساسي على ضرب المصفوفات. في الخطوة الأولى، تُضرب المدخلات بأوزان عشوائية مبدئية، ثم تُحوّل باستخدام دالة تنشيط، وتُستخدم قيم المخرجات للتنبؤ. تُعطي هذه الخطوة فكرة عن مدى قرب الشبكة من الواقع.
المقياس المطبق هو الخسارة. فكلما زادت دالة الخسارة، كلما كان النموذج أغبى. لتحسين معرفة الشبكة، يلزم إجراء بعض التحسينات عن طريق تعديل أوزان الشبكة. الانحدار التدرجي العشوائي هو الطريقة المستخدمة لتغيير قيم الأوزان في الاتجاه الصحيح. بمجرد إجراء التعديل، يمكن للشبكة استخدام دفعة أخرى من البيانات لاختبار معرفتها الجديدة.
لحسن الحظ، انخفض الخطأ عن السابق، ولكنه لا يزال غير كافٍ. تُجرى عملية التحسين بشكل تكراري حتى يتم تقليل الخطأ إلى أدنى حد، أي لا يمكن استخلاص المزيد من المعلومات.tracتيد.
المشكلة في هذا النوع من النماذج هي أنه لا يحتوي على أي ذاكرة. وهذا يعني أن المدخلات والمخرجات مستقلة. بمعنى آخر، النموذج لا يهتم بما جاء من قبل. إنه يثير بعض التساؤلات عندما تحتاج إلى التنبؤ بالسلاسل الزمنية أو الجمل لأن الشبكة تحتاج إلى معلومات حول البيانات التاريخية أو الكلمات السابقة.
للتغلب على هذه المشكلة، تم تطوير نوع جديد من الهندسة المعمارية: الشبكة العصبية المتكررة (RNN فيما يلي)
ما هي الشبكة العصبية المتكررة (RNN)؟
الشبكة العصبية المتكررة (RNN) هي نوع من الشبكات العصبية الاصطناعية، حيث تشكل الروابط بين العقد المختلفة رسمًا بيانيًا موجهًا، مما يُضفي سلوكًا ديناميكيًا زمنيًا. وهي تُساعد في نمذجة البيانات المتسلسلة المُستمدة من الشبكات الأمامية. وتعمل بطريقة مشابهة للدماغ البشري لتقديم نتائج تنبؤية.
تبدو الشبكة العصبية المتكررة مشابهة تمامًا للشبكة العصبية التقليدية فيما عدا أنه يتم إضافة حالة الذاكرة إلى الخلايا العصبية. حساب تضمين الذاكرة بسيط.
تخيل نموذجًا بسيطًا يحتوي على عصبون واحد فقط يتغذى بمجموعة من البيانات. في الشبكة العصبية التقليدية، يُنتج النموذج المخرجات بضرب المدخلات في الوزن ودالة التنشيط. أما في الشبكة العصبية المتكررة (RNN)، فتُعاد هذه المخرجات إلى نفسها عددًا من المرات. نسميها خطوة زمنية مقدار الوقت الذي يصبح فيه الناتج مدخلاً لعملية ضرب المصفوفة التالية.
على سبيل المثال، في الصورة أدناه، يمكنك رؤية أن الشبكة تتكون من خلية عصبية واحدة. تقوم الشبكة بحساب ضرب المصفوفات بين المدخلات والوزن وإضافة اللاخطية مع وظيفة التنشيط. ويصبح الإخراج في t-1. هذا الإخراج هو مدخلات ضرب المصفوفة الثانية.
الشبكة العصبية المتكررة (RNN)
أدناه، نقوم بترميز RNN بسيط في TensorFlow لفهم الخطوة وكذلك شكل الإخراج.
تتكون الشبكة من :
- أربعة مدخلات
- ستة خلايا عصبية
- 2-خطوات زمنية
سيتم تشغيل الشبكة كما هو موضح في الصورة أدناه.
تُسمى الشبكة "متكررة" لأنها تقوم بنفس العملية في كل مربع تنشيط. قامت الشبكة بحساب أوزان المدخلات والمخرجات السابقة قبل استخدام دالة التنشيط.
ملاحظة حول الإصدار: يستهدف الكود في هذا البرنامج التعليمي واجهة برمجة تطبيقات الرسم البياني TensorFlow 1.x. في TensorFlow 2.x، يستمر تشغيل نفس البرنامج النصي بعد ذلك. import tensorflow.compat.v1 as tf المزيد tf.disable_v2_behavior()لأن العناصر النائبة والجلسات ووحدة rnn_cell أصبحت الآن موجودة تحت tf.compat.v1. المكافئ الاصطلاحي 2.x هو tf.keras.layers.SimpleRNN.
import numpy as np import tensorflow as tf n_inputs = 4 n_neurons = 6 n_timesteps = 2 The data is a sequence of a number from 0 to 9 and divided into three batches of data. ## Data X_batch = np.array([ [[0, 1, 2, 5], [9, 8, 7, 4]], # Batch 1 [[3, 4, 5, 2], [0, 0, 0, 0]], # Batch 2 [[6, 7, 8, 5], [6, 5, 4, 2]], # Batch 3 ])
يمكننا بناء الشبكة باستخدام عنصر نائب للبيانات والمرحلة المتكررة والمخرجات.
تحديد العنصر النائب للبيانات
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
هنا:
- لا شيء: غير معروف وسيأخذ حجم الدفعة
- n_timesteps: عدد المرات التي ترسل فيها الشبكة المخرجات إلى الخلية العصبية
- n_inputs: عدد المدخلات لكل دفعة
تحديد الشبكة المتكررة
كما هو مذكور في الصورة أعلاه، تتكون الشبكة من 6 خلايا عصبية. ستقوم الشبكة بحساب منتجين نقطيين:
- إدخال البيانات بالمجموعة الأولى من الأوزان (أي 6: يساوي عدد الخلايا العصبية)
- المخرجات السابقة مع مجموعة ثانية من الأوزان (أي 6: بما يتوافق مع عدد المخرجات)
لاحظ أنه خلال عملية التغذية الأمامية الأولى، تكون قيم المخرجات السابقة مساوية للأصفار لأنه ليس لدينا أي قيمة متاحة.
الكائن المراد إنشاء RNN هو tf.contrib.rnn.BasicRNNCell مع الوسيطة num_units لتحديد عدد الإدخال
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
الآن بعد أن تم تعريف الشبكة، يمكنك حساب المخرجات والحالات
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
يستخدم هذا الكائن حلقة داخلية لضرب المصفوفات بالعدد المناسب من المرات.
لاحظ أن العصبون المتكرر هو دالة لجميع مدخلات الخطوات الزمنية السابقة. هكذا تبني الشبكة ذاكرتها الخاصة. يمكن للمعلومات من الزمن السابق أن تنتشر في الزمن اللاحق. هذا هو سر الشبكة العصبية المتكررة.
## Define the shape of the tensor X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs]) ## Define the network basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons) outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) init = tf.global_variables_initializer() init = tf.global_variables_initializer() with tf.Session() as sess: init.run() outputs_val = outputs.eval(feed_dict={X: X_batch}) print(states.eval(feed_dict={X: X_batch})) [[ 0.38941205 -0.9980438 0.99750966 0.7892596 0.9978241 0.9999997 ] [ 0.61096436 0.7255889 0.82977575 -0.88226104 0.29261455 -0.15597084] [ 0.62091285 -0.87023467 0.99729395 -0.58261937 0.9811445 0.99969864]]
لأغراض التوضيح، اطبع قيم الحالة السابقة. يُظهر الناتج المطبوع أعلاه ناتج الحالة الأخيرة. الآن، اطبع جميع النواتج، ستلاحظ أن الحالات هي الناتج السابق لكل دفعة. أي أن الناتج السابق يحتوي على معلومات حول التسلسل بأكمله.
print(outputs_val) print(outputs_val.shape) [[[-0.75934666 -0.99537754 0.9735819 -0.9722234 -0.14234993 -0.9984044 ] [ 0.99975264 -0.9983206 0.9999993 -1. -0.9997506 -1. ]] [[ 0.97486496 -0.98773265 0.9969686 -0.99950117 -0.7092863 -0.99998885] [ 0.9326837 0.2673438 0.2808514 -0.7535883 -0.43337247 0.5700631 ]] [[ 0.99628735 -0.9998728 0.99999213 -0.99999976 -0.9884324 -1. ] [ 0.99962527 -0.9467421 0.9997403 -0.99999714 -0.99929446 -0.9999795 ]]] (3, 2, 6)
يعرض الرسم التوضيحي أدناه نفس الموتر المطبوع دفعةً تلو الأخرى.
الإخراج له الشكل (3، 2، 6):
- 3: عدد الدفعات
- 2: عدد الخطوات الزمنية
- 6: عدد الخلايا العصبية
إن تحسين الشبكة العصبية المتكررة مماثل للشبكة العصبية التقليدية. ستشاهد بمزيد من التفاصيل كيفية تحسين التعليمات البرمجية في الجزء التالي من هذا البرنامج التعليمي للشبكة العصبية المتكررة.
تطبيقات RNN
RNN لها استخدامات متعددة، خاصة عندما يتعلق الأمر بالتنبؤ بالمستقبل. في الصناعة المالية، يمكن أن تكون RNN مفيدة في التنبؤ بأسعار الأسهم أو علامة اتجاه سوق الأوراق المالية (أي إيجابي أو سلبي).
يعد RNN مفيدًا للسيارة ذاتية القيادة حيث يمكنها تجنب وقوع حادث سيارة من خلال توقع مسار السيارة.
تُستخدم RNN على نطاق واسع في تحليل النصوص والتعليق على الصور وتحليل المشاعر والترجمة الآلية. على سبيل المثال، يمكن للمرء استخدام مراجعة الفيلم لفهم الشعور الذي يشعر به المشاهد بعد مشاهدة الفيلم. تعد أتمتة هذه المهمة مفيدة للغاية عندما لا يكون لدى شركة الأفلام الوقت الكافي لمراجعة المراجعات وتصنيفها وتوحيدها وتحليلها. يمكن للآلة القيام بهذه المهمة بمستوى أعلى من الدقة.
حدود RNN
من الناحية النظرية، من المفترض أن تقوم RNN بحمل المعلومات عدة مرات. ومع ذلك، من الصعب جدًا نشر كل هذه المعلومات عندما تكون الخطوة الزمنية طويلة جدًا. عندما تحتوي الشبكة على عدد كبير جدًا من الطبقات العميقة، تصبح غير قابلة للتدريب. هذه المشكلة تسمى: تلاشي مشكلة التدرج. إذا كنت تتذكر، تقوم الشبكة العصبية بتحديث الوزن باستخدام خوارزمية النسب المتدرج. تصبح التدرجات أصغر عندما تتقدم الشبكة إلى الطبقات السفلية.
في الختام، تبقى التدرجات ثابتة، مما يعني عدم وجود مجال للتحسين. يتعلم النموذج من تغير التدرج، وهذا التغير يؤثر على مخرجات الشبكة. مع ذلك، إذا كان الفرق في التدرج ضئيلاً للغاية (أي إذا تغيرت الأوزان قليلاً)، فلن تتمكن الشبكة من التعلم، وبالتالي لن تتمكن من الحصول على أي نتيجة. لذلك، لا يمكن للشبكة التي تواجه مشكلة التدرج المتلاشي أن تتقارب نحو حل جيد.
تحسين LSTM
للتغلب على مشكلة تلاشي التدرج التي تواجه الشبكات العصبية المتكررة (RNN)، قام ثلاثة باحثين، هم هوكريتر وشميدهوبر وبنجيو، بتحسين هذه الشبكات باستخدام بنية تُسمى الذاكرة طويلة المدى (LSTM). باختصار، تُزوّد LSTM الشبكة بمعلومات تاريخية ذات صلة بالأحداث الأخيرة. وتستخدم الآلة بنية محسّنة لاختيار المعلومات ونقلها إلى فترات زمنية لاحقة.
تتوفر بنية LSTM في TensorFlow، ضمن حزمة tf.contrib.rnn.LSTMCell. لكن LSTM خارج نطاق هذا الشرح. يمكنك الرجوع إلى المصدر الرسمي. توثيق لمزيد من المعلومات
في TensorFlow 2.x، يتم الوصول إلى تلك الخلية على النحو التالي: tf.compat.v1.nn.rnn_cell.LSTMCellبينما يستخدم الكود الجديد عادةً tf.keras.layers.LSTM أو البوابة الأخف وزناً tf.keras.layers.GRU، والتي تصل إلى دقة مماثلة باستخدام عدد أقل من المعلمات.
RNN في السلاسل الزمنية
في هذا الدرس التعليمي حول الشبكات العصبية المتكررة (RNN) باستخدام TensorFlow، ستستخدم شبكة عصبية متكررة مع بيانات السلاسل الزمنية. تعتمد السلاسل الزمنية على القيم السابقة، مما يعني أن القيم الماضية تتضمن معلومات مهمة يمكن للشبكة التعلم منها. تكمن فكرة التنبؤ بالسلاسل الزمنية في تقدير القيمة المستقبلية لسلسلة معينة، مثل سعر السهم، أو درجة الحرارة، أو الناتج المحلي الإجمالي، وما إلى ذلك.
قد يكون تحضير البيانات لشبكة Keras RNN والسلسلة الزمنية أمرًا صعبًا بعض الشيء. أولاً وقبل كل شيء، الهدف هو التنبؤ بالقيمة التالية للسلسلة، أي أنك ستستخدم المعلومات السابقة لتقدير القيمة عند t + 1. العلامة تساوي تسلسل الإدخال ويتم إزاحتها فترة واحدة للأمام. ثانيًا، يتم تعيين عدد الإدخالات على 1، أي ملاحظة واحدة لكل وقت. أخيرًا، تكون الخطوة الزمنية مساوية لتسلسل القيمة العددية. على سبيل المثال، إذا قمت بتعيين الخطوة الزمنية على 10، فسوف يعود تسلسل الإدخال عشر مرات متتالية.
انظر إلى الرسم البياني أدناه، لقد قمنا بتمثيل بيانات السلاسل الزمنية على اليسار وتسلسل الإدخال الوهمي على اليمين. يمكنك إنشاء دالة لإرجاع مجموعة بيانات ذات قيمة عشوائية لكل يوم من يناير 2001 إلى ديسمبر 2016
# To plot pretty figures %matplotlib inline import matplotlib import matplotlib.pyplot as plt import pandas as pd def create_ts(start = '2001', n = 201, freq = 'M'): rng = pd.date_range(start=start, periods=n, freq=freq) ts = pd.Series(np.random.uniform(-18, 18, size=len(rng)), rng).cumsum() return ts ts= create_ts(start = '2001', n = 192, freq = 'M') ts.tail(5)
الناتج
2016-08-31 -93.459631 2016-09-30 -95.264791 2016-10-31 -95.551935 2016-11-30 -105.879611 2016-12-31 -123.729319 Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222) # Left plt.figure(figsize=(11,4)) plt.subplot(121) plt.plot(ts.index, ts) plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A training instance") plt.title("A time series (generated)", fontsize=14) # Right plt.subplot(122) plt.title("A training instance", fontsize=14) plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance") plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red') plt.legend(loc="upper left") plt.xlabel("Time") plt.show()
يُظهر الجزء الأيمن من الرسم البياني جميع السلاسل الزمنية، بدءًا من عام ٢٠٠١ وحتى عام ٢٠١٩. لا جدوى من إدخال جميع البيانات في الشبكة، بل يجب إنشاء مجموعة بيانات بطول يساوي الخطوة الزمنية. ستكون هذه المجموعة هي المتغير X. أما المتغير Y فهو نفسه X ولكن بعد إزاحته بمقدار فترة زمنية واحدة (أي أنك تريد التنبؤ بالفترة t+1).
كلا المتجهين لهما نفس الطول. يمكنك رؤيته في الجزء الأيمن من الرسم البياني أعلاه. يمثل الخط القيم العشر لإدخال X، في حين أن النقاط الحمراء هي القيم العشر للملصق، Y. لاحظ أن التسمية تبدأ بفترة واحدة قبل X وتنتهي بفترة واحدة بعد ذلك.
قم ببناء RNN للتنبؤ بالسلاسل الزمنية في TensorFlow
الآن في تدريب RNN هذا، حان الوقت لبناء أول RNN الخاص بك للتنبؤ بالسلسلة أعلاه. تحتاج إلى تحديد بعض المعلمات الفائقة (معلمات النموذج، أي عدد الخلايا العصبية، وما إلى ذلك) للنموذج:
- عدد المدخلات: 1
- خطوة الوقت (النوافذ في السلسلة الزمنية): 10
- عدد الخلايا العصبية: 120
- عدد المخرجات: 1
ستتعلم شبكتك من سلسلة بيانات مدتها 10 أيام، وستحتوي على 120 عصبونًا متكررًا. تُدخل إلى النموذج بيانات يوم واحد. يمكنك تغيير القيم لمعرفة ما إذا كان النموذج قد تحسن.
قبل بناء النموذج، عليك تقسيم مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار. تحتوي مجموعة البيانات الكاملة على 222 نقطة بيانات؛ ستستخدم أول 201 نقطة لتدريب النموذج، وآخر 21 نقطة لاختباره.
بعد تحديد مجموعتي التدريب والاختبار، عليك إنشاء كائن يحتوي على الدُفعات. تحتوي هذه الدُفعات على قيم X وقيم Y. تذكر أن قيم X متأخرة بفترة واحدة. لذلك، ستستخدم أول 200 مشاهدة، وتكون الخطوة الزمنية 10. يجب أن يحتوي كائن X_batches على 20 دفعة بحجم 10×1. أما كائن y_batches فيحمل نفس شكل كائن X_batches، ولكن بفترة زمنية متقدمة.
الخطوة 1) إنشاء القطار والاختبار
أولاً، تقوم بتحويل السلسلة إلى ملف نمباي المصفوفة؛ ثم تقوم بتحديد النوافذ (أي عدد المرات التي ستتعلم منها الشبكة)، وعدد المدخلات والمخرجات وحجم مجموعة القطار كما هو موضح في مثال TensorFlow RNN أدناه.
series = np.array(ts) n_windows = 20 n_input = 1 n_output = 1 size_train = 201
بعد ذلك، يمكنك ببساطة تقسيم المصفوفة إلى مجموعتين من البيانات.
## Split data train = series[:size_train] test = series[size_train:] print(train.shape, test.shape) (201,) (21,)
الخطوة 2) قم بإنشاء الدالة لإرجاع X_batches وy_batches
لتسهيل الأمر، يمكنك إنشاء دالة تُرجع صفيفين مختلفين، أحدهما لـ X_batches والآخر لـ y_batches.
لنكتب دالة RNN TensorFlow لإنشاء الدُفعات.
لاحظ أن الدفعات X متأخرة بفترة واحدة (نأخذ القيمة t-1). يجب أن يكون لإخراج الدالة ثلاثة أبعاد. البعد الأول يساوي عدد الدفعات، والثاني حجم النوافذ، والأخير عدد المدخلات.
الجزء الصعب هو تحديد نقاط البيانات بشكل صحيح. بالنسبة لنقاط البيانات X، يمكنك اختيار الملاحظات من t = 1 إلى t = 200، بينما بالنسبة لنقطة البيانات Y، يمكنك إرجاع الملاحظات من t = 2 إلى 201. بمجرد حصولك على نقاط البيانات الصحيحة، يصبح من السهل إعادة التشكيل السلسلة.
لإنشاء الكائن باستخدام الدُفعات، تحتاج إلى تقسيم مجموعة البيانات إلى عشر دفعات متساوية الطول (أي 20). يمكنك استخدام طريقة إعادة التشكيل وتمرير -1 بحيث تكون السلسلة مشابهة لحجم الدفعة. القيمة 20 هي عدد الملاحظات لكل دفعة و1 هي عدد المدخلات.
عليك أن تفعل نفس الخطوة ولكن بالنسبة للملصق.
لاحظ أنه يجب عليك تعديل البيانات بعدد مرات التنبؤ المطلوبة. على سبيل المثال، إذا كنت ترغب في التنبؤ بفترة زمنية واحدة، فعليك تعديل السلسلة بمقدار 1. أما إذا كنت ترغب في التنبؤ بيومين، فعليك تعديل البيانات بمقدار 2.
x_data = train[:size_train-1]: Select all the training instance minus one day X_batches = x_data.reshape(-1, windows, input): create the right shape for the batch e.g (10, 20, 1) def create_batches(df, windows, input, output): ## Create X x_data = train[:size_train-1] # Select the data X_batches = x_data.reshape(-1, windows, input) # Reshape the data ## Create y y_data = train[n_output:size_train] y_batches = y_data.reshape(-1, windows, output) return X_batches, y_batches
الآن بعد أن تم تعريف الوظيفة، يمكنك استدعاؤها لإنشاء الدُفعات كما هو موضح في مثال RNN أدناه.
X_batches, y_batches = create_batches(df = train,
windows = n_windows,
input = n_input,
output = n_output)
يمكنك طباعة الشكل للتأكد من صحة الأبعاد.
print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)
تحتاج إلى إنشاء مجموعة اختبار تحتوي على دفعة واحدة فقط من البيانات و20 ملاحظة.
لاحظ أنه، إذا توقعت يومًا بعد يوم، فهذا يعني أن القيمة المتوقعة الثانية ستعتمد على القيمة الحقيقية لليوم الأول (t+1) لمجموعة بيانات الاختبار. والحقيقة هي أن القيمة الحقيقية سوف تعرف.
إذا كنت تريد التنبؤ بـ t+2 (أي قبل يومين)، فأنت بحاجة إلى استخدام القيمة المتوقعة t+1؛ إذا كنت تريد التنبؤ بـ t+3 (قبل ثلاثة أيام)، فستحتاج إلى استخدام القيمة المتوقعة t+1 وt+2. من المنطقي أنه من الصعب التنبؤ بدقة بعدد الأيام المقبلة.
X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1)
print(X_test.shape, y_test.shape)
(10, 20, 1) (10, 20, 1)
حسنًا، حجم الدفعة الخاص بك جاهز، يمكنك بناء بنية RNN. تذكر أن لديك 120 خلية عصبية متكررة.
الخطوة 3) قم ببناء النموذج
لإنشاء النموذج، تحتاج إلى تحديد ثلاثة أجزاء:
- المتغير مع الموترات
- آر إن إن
- الخسارة والتحسين
الخطوة 3.1) المتغيرات
تحتاج إلى تحديد متغيرات X وy بالشكل المناسب. هذه الخطوة تافهة. الموتر له نفس البعد مثل الكائنات X_batches و y_batches.
على سبيل المثال، الموتر X هو عنصر نائب (راجع البرنامج التعليمي على مقدمة إلى TensorFlow لتحديث عقلك حول إعلان المتغير) له ثلاثة أبعاد:
- ملاحظة: حجم الدفعة
- عدد النوافذ: طول النوافذ. أي عدد المرات التي ينظر فيها النموذج إلى الوراء
- n_input: عدد المدخلات
النتيجه هي:
tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output])
الخطوة 3.2) قم بإنشاء RNN
في الجزء الثاني من مثال TensorFlow الخاص بـ RNN، تحتاج إلى تحديد بنية الشبكة. وكما في السابق، يمكنك استخدام الكائن BasicRNNCell وdynamic_rnn من مقدر TensorFlow.
## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
الجزء التالي أصعب بعض الشيء ولكنه يسمح بإجراء عمليات حسابية أسرع. تحتاج إلى تحويل إخراج التشغيل إلى طبقة كثيفة ثم تحويله مرة أخرى ليكون له نفس بُعد الإدخال.
stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])
الخطوة 3.3) إنشاء الخسارة والتحسين
يعتمد تحسين النموذج على المهمة التي تقوم بتنفيذها. في الدرس السابق حول سي ان انفي الدرس السابق، كان هدفك تصنيف الصور، أما في هذا الدرس التعليمي حول الشبكات العصبية المتكررة، فالهدف مختلف قليلاً. يُطلب منك التنبؤ بقيمة متغير مستمر مقارنةً بتصنيفه إلى فئة.
هذا الاختلاف مهم لأنه سيغير مشكلة التحسين. مشكلة التحسين للمتغير المستمر هي تقليل متوسط مربع الخطأ. لإنشاء هذه المقاييس في TF، يمكنك استخدام:
tf.reduce_sum(tf.square(المخرجات - y))
ما تبقى من رمز RNN هو نفسه كما كان من قبل؛ يمكنك استخدام مُحسِّن Adam لتقليل الخسارة (على سبيل المثال، MSE):
tf.train.AdamOptimizer(learning_rate=learning_rate)
محسن.تقليل(الخسارة)
هذا كل شيء، يمكنك تجميع كل شيء معًا، ويكون النموذج الخاص بك جاهزًا للتدريب.
tf.reset_default_graph() r_neuron = 120 ## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output]) ## 2. create the model basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output]) ## 3. Loss + optimization learning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) training_op = optimizer.minimize(loss) init = tf.global_variables_initializer()
ستقوم بتدريب النموذج باستخدام 1500 حقبة وطباعة الخسارة كل 150 تكرارًا. بمجرد تدريب النموذج، يمكنك تقييم النموذج في مجموعة الاختبار وإنشاء كائن يحتوي على التنبؤات كما هو موضح في مثال الشبكة العصبية المتكررة أدناه.
iteration = 1500 with tf.Session() as sess: init.run() for iters in range(iteration): sess.run(training_op, feed_dict={X: X_batches, y: y_batches}) if iters % 150 == 0: mse = loss.eval(feed_dict={X: X_batches, y: y_batches}) print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test}) 0 MSE: 502893.34 150 MSE: 13839.129 300 MSE: 3964.835 450 MSE: 2619.885 600 MSE: 2418.772 750 MSE: 2110.5923 900 MSE: 1887.9644 1050 MSE: 1747.1377 1200 MSE: 1556.3398 1350 MSE: 1384.6113
أخيرًا، في هذا البرنامج التعليمي لـ RNN Deep Learning، يمكنك رسم القيمة الفعلية للسلسلة بالقيمة المتوقعة. إذا تم تصحيح النموذج الخاص بك، فيجب وضع القيم المتوقعة فوق القيم الفعلية.
كما ترون، لا يزال النموذج بحاجة إلى تحسين. الأمر متروك لكم لتغيير المعلمات الفائقة مثل النوافذ، وحجم الدفعة، أو عدد الخلايا العصبية المتكررة.
plt.title("Forecast vs Actual", fontsize=14) plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="Actual", color='green') plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="Forecast", color='red') plt.legend(loc="lower left") plt.xlabel("Time") plt.show()
توقعات مقابل الفعلي





