البرنامج التعليمي RNN (الشبكة العصبية المتكررة): مثال TensorFlow
لماذا نحتاج إلى شبكة عصبية متكررة (RNN)؟
تتيح لك الشبكة العصبية المتكررة (RNN) تصميم وحدات الذاكرة للاحتفاظ بالبيانات ونموذج التبعيات قصيرة المدى. كما أنها تستخدم في التنبؤ بالسلاسل الزمنية لتحديد ارتباطات البيانات وأنماطها. كما أنه يساعد على إنتاج نتائج تنبؤية للبيانات المتسلسلة من خلال تقديم سلوك مماثل للدماغ البشري.
هيكل الشبكة العصبية الاصطناعية بسيط نسبيًا ويتعلق بشكل أساسي بضرب المصفوفات. خلال الخطوة الأولى، يتم ضرب المدخلات بأوزان عشوائية مبدئية، ويتم تحويلها بوظيفة التنشيط ويتم استخدام قيم المخرجات لإجراء التنبؤ. تعطي هذه الخطوة فكرة عن مدى بعد الشبكة عن الواقع.
المقياس المطبق هو الخسارة. فكلما زادت دالة الخسارة، كلما كان النموذج أغبى. لتحسين معرفة الشبكة، يلزم إجراء بعض التحسينات عن طريق تعديل أوزان الشبكة. الانحدار التدرجي العشوائي هو الطريقة المستخدمة لتغيير قيم الأوزان في الاتجاه الصحيح. بمجرد إجراء التعديل، يمكن للشبكة استخدام دفعة أخرى من البيانات لاختبار معرفتها الجديدة.
ولحسن الحظ، فإن الخطأ أقل من ذي قبل، ولكنه ليس صغيرا بما فيه الكفاية. تتم خطوة التحسين بشكل متكرر حتى يتم تقليل الخطأ إلى الحد الأدنى، أي لا يمكن استخراج المزيد من المعلومات.
المشكلة في هذا النوع من النماذج هي أنه لا يحتوي على أي ذاكرة. وهذا يعني أن المدخلات والمخرجات مستقلة. بمعنى آخر، النموذج لا يهتم بما جاء من قبل. إنه يثير بعض التساؤلات عندما تحتاج إلى التنبؤ بالسلاسل الزمنية أو الجمل لأن الشبكة تحتاج إلى معلومات حول البيانات التاريخية أو الكلمات السابقة.
للتغلب على هذه المشكلة، تم تطوير نوع جديد من الهندسة المعمارية: الشبكة العصبية المتكررة (RNN فيما يلي)
ما هي الشبكة العصبية المتكررة (RNN)؟
A الشبكة العصبية المتكررة (RNN) هي فئة من شبكة اعصاب صناعية حيث يشكل الاتصال بين العقد المختلفة رسمًا بيانيًا موجهًا لإعطاء سلوك ديناميكي زمني. فهو يساعد على نمذجة البيانات التسلسلية المشتقة من شبكات التغذية الأمامية. إنه يعمل بشكل مشابه للأدمغة البشرية لتقديم نتائج تنبؤية.
تبدو الشبكة العصبية المتكررة مشابهة تمامًا للشبكة العصبية التقليدية فيما عدا أنه يتم إضافة حالة الذاكرة إلى الخلايا العصبية. حساب تضمين الذاكرة بسيط.
تخيل نموذجًا بسيطًا يحتوي على خلية عصبية واحدة فقط تتغذى بمجموعة من البيانات. في الشبكة العصبية التقليدية، ينتج النموذج المخرجات عن طريق ضرب المدخلات بالوزن ووظيفة التنشيط. باستخدام RNN، يتم إرسال هذا الإخراج مرة أخرى إلى نفسه لعدد من الوقت. نحن نتصل خطوة زمنية مقدار الوقت الذي يصبح فيه الإخراج مدخلاً لضرب المصفوفة التالية.
على سبيل المثال، في الصورة أدناه، يمكنك رؤية أن الشبكة تتكون من خلية عصبية واحدة. تقوم الشبكة بحساب ضرب المصفوفات بين المدخلات والوزن وإضافة اللاخطية مع وظيفة التنشيط. ويصبح الإخراج في t-1. هذا الإخراج هو مدخلات ضرب المصفوفة الثانية.

أدناه، نقوم بترميز RNN بسيط في TensorFlow لفهم الخطوة وكذلك شكل الإخراج.
تتكون الشبكة من :
- أربعة مدخلات
- ستة خلايا عصبية
- 2-خطوات زمنية
سيتم تشغيل الشبكة كما هو موضح في الصورة أدناه.
تُسمى الشبكة "متكررة" لأنها تقوم بنفس العملية في كل مربع تنشيط. قامت الشبكة بحساب أوزان المدخلات والمخرجات السابقة قبل استخدام دالة التنشيط.
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، قام ثلاثة باحثين، Hochreiter وSchmidhuber وBengio، بتحسين RNN باستخدام بنية تسمى الذاكرة طويلة المدى القصيرة (LSTM). باختصار، توفر LSTM للشبكة معلومات سابقة ذات صلة بالأوقات الأكثر حداثة. تستخدم الآلة بنية أفضل لاختيار المعلومات ونقلها إلى وقت لاحق.
تتوفر بنية LSTM في TensorFlow، tf.contrib.rnn.LSTMcell. LSTM خارج نطاق البرنامج التعليمي. يمكنك الرجوع إلى الدليل الرسمي توثيق لمزيد من المعلومات
RNN في السلاسل الزمنية
في هذا البرنامج التعليمي TensorFlow RNN، ستستخدم RNN مع بيانات السلاسل الزمنية. تعتمد السلاسل الزمنية على الوقت السابق مما يعني أن القيم السابقة تتضمن معلومات ذات صلة يمكن للشبكة التعلم منها. الفكرة وراء التنبؤ بالسلاسل الزمنية هي تقدير القيمة المستقبلية للسلسلة، على سبيل المثال، سعر السهم ودرجة الحرارة والناتج المحلي الإجمالي وما إلى ذلك.
قد يكون تحضير البيانات لشبكة 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()
يُظهر الجزء الأيمن من الرسم البياني جميع السلاسل. بدأت من عام 2001 وانتهت في عام 2019. لا معنى لتغذية جميع البيانات في الشبكة، بل تحتاج بدلاً من ذلك إلى إنشاء دفعة من البيانات بطول يساوي خطوة الوقت. ستكون هذه الدفعة هي المتغير 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_windows: طول النوافذ. أي عدد المرات التي ينظر فيها النموذج إلى الخلف
- 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) إنشاء الخسارة والتحسين
يعتمد تحسين النموذج على المهمة التي تقوم بها. في البرنامج التعليمي السابق على سي ان ان، كان هدفك هو تصنيف الصور، في هذا البرنامج التعليمي RNN، الهدف مختلف قليلاً. يُطلب منك إجراء تنبؤ على متغير مستمر مقارنة بفصل دراسي.
هذا الاختلاف مهم لأنه سيغير مشكلة التحسين. مشكلة التحسين للمتغير المستمر هي تقليل متوسط مربع الخطأ. لإنشاء هذه المقاييس في 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()
ملخص
الشبكة العصبية المتكررة عبارة عن بنية قوية للتعامل مع السلاسل الزمنية أو تحليل النصوص. ويكون ناتج الحالة السابقة عبارة عن ردود فعل للحفاظ على ذاكرة الشبكة بمرور الوقت أو تسلسل الكلمات.
في TensorFlow، يمكنك استخدام الرموز التالية لتدريب الشبكة العصبية المتكررة TensorFlow للسلاسل الزمنية:
معلمات النموذج
n_windows = 20 n_input = 1 n_output = 1 size_train = 201
حدد النموذج
X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output]) 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])
بناء التحسين
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()
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})



