البرنامج التعليمي RNN (الشبكة العصبية المتكررة): مثال TensorFlow

لماذا نحتاج إلى شبكة عصبية متكررة (RNN)؟

تتيح لك الشبكة العصبية المتكررة (RNN) تصميم وحدات الذاكرة للاحتفاظ بالبيانات ونموذج التبعيات قصيرة المدى. كما أنها تستخدم في التنبؤ بالسلاسل الزمنية لتحديد ارتباطات البيانات وأنماطها. كما أنه يساعد على إنتاج نتائج تنبؤية للبيانات المتسلسلة من خلال تقديم سلوك مماثل للدماغ البشري.

هيكل الشبكة العصبية الاصطناعية بسيط نسبيًا ويتعلق بشكل أساسي بضرب المصفوفات. خلال الخطوة الأولى، يتم ضرب المدخلات بأوزان عشوائية مبدئية، ويتم تحويلها بوظيفة التنشيط ويتم استخدام قيم المخرجات لإجراء التنبؤ. تعطي هذه الخطوة فكرة عن مدى بعد الشبكة عن الواقع.

المقياس المطبق هو الخسارة. كلما زادت دالة الخسارة، كلما كان النموذج أغبى. لتحسين المعرفة بالشبكة، يلزم إجراء بعض التحسينات عن طريق ضبط أوزان الشبكة. النسب المتدرج العشوائي هو الطريقة المستخدمة لتغيير قيم الأوزان في الاتجاه الصحيح. بمجرد إجراء التعديل، يمكن للشبكة استخدام مجموعة أخرى من البيانات لاختبار معرفتها الجديدة.

ولحسن الحظ، فإن الخطأ أقل من ذي قبل، ولكنه ليس صغيرا بما فيه الكفاية. تتم خطوة التحسين بشكل متكرر حتى يتم تقليل الخطأ إلى الحد الأدنى، أي لا يمكن استخراج المزيد من المعلومات.

المشكلة في هذا النوع من النماذج هي أنه لا يحتوي على أي ذاكرة. وهذا يعني أن المدخلات والمخرجات مستقلة. بمعنى آخر، النموذج لا يهتم بما جاء من قبل. إنه يثير بعض التساؤلات عندما تحتاج إلى التنبؤ بالسلاسل الزمنية أو الجمل لأن الشبكة تحتاج إلى معلومات حول البيانات التاريخية أو الكلمات السابقة.

للتغلب على هذه المشكلة، نوع جديد من archiتم تطوير التقنية: الشبكة العصبية المتكررة (RNN فيما بعد)

ما هي الشبكة العصبية المتكررة (RNN)؟

A الشبكة العصبية المتكررة (RNN) هي فئة من شبكة اعصاب صناعية حيث يشكل الاتصال بين العقد المختلفة رسمًا بيانيًا موجهًا لإعطاء سلوك ديناميكي زمني. فهو يساعد على نمذجة البيانات التسلسلية المشتقة من شبكات التغذية الأمامية. إنه يعمل بشكل مشابه للأدمغة البشرية لتقديم نتائج تنبؤية.

تبدو الشبكة العصبية المتكررة مشابهة تمامًا للشبكة العصبية التقليدية فيما عدا أنه يتم إضافة حالة الذاكرة إلى الخلايا العصبية. حساب تضمين الذاكرة بسيط.

تخيل نموذجًا بسيطًا يحتوي على خلية عصبية واحدة فقط تتغذى بمجموعة من البيانات. في الشبكة العصبية التقليدية، ينتج النموذج المخرجات عن طريق ضرب المدخلات بالوزن ووظيفة التنشيط. باستخدام RNN، يتم إرسال هذا الإخراج مرة أخرى إلى نفسه لعدد من الوقت. نحن نتصل خطوة زمنية مقدار الوقت الذي يصبح فيه الإخراج مدخلاً لضرب المصفوفة التالية.

على سبيل المثال، في الصورة أدناه، يمكنك رؤية أن الشبكة تتكون من خلية عصبية واحدة. تقوم الشبكة بحساب ضرب المصفوفات بين المدخلات والوزن وإضافة اللاخطية مع وظيفة التنشيط. ويصبح الإخراج في t-1. هذا الإخراج هو مدخلات ضرب المصفوفة الثانية.

الشبكة العصبية المتكررة (RNN)
الشبكة العصبية المتكررة (RNN)

أدناه، نقوم بترميز RNN بسيط في TensorFlow لفهم الخطوة وكذلك شكل الإخراج.

تتكون الشبكة من :

  • أربعة مدخلات
  • ستة خلايا عصبية
  • 2-خطوات زمنية

سيتم تشغيل الشبكة كما هو موضح في الصورة أدناه.

الشبكة العصبية المتكررة (RNN)

تسمى الشبكة "متكررة" لأنها تقوم بنفس العملية في كل مربع تنشيط. قامت الشبكة بحساب أوزان المدخلات والمخرجات السابقة قبل استخدام وظيفة التنشيط.

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
    ])

يمكننا بناء الشبكة باستخدام عنصر نائب للبيانات والمرحلة المتكررة والمخرجات.

  1. تحديد العنصر النائب للبيانات
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

هنا:

  • لا شيء: غير معروف وسيأخذ حجم الدفعة
  • n_timesteps: عدد المرات التي ترسل فيها الشبكة المخرجات إلى الخلية العصبية
  • n_inputs: عدد المدخلات لكل دفعة
  1. تحديد الشبكة المتكررة

كما هو مذكور في الصورة أعلاه، تتكون الشبكة من 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)

الشبكة العصبية المتكررة (RNN)

الإخراج له الشكل (3، 2، 6):

  • 3: عدد الدفعات
  • 2: عدد الخطوات الزمنية
  • 6: عدد الخلايا العصبية

إن تحسين الشبكة العصبية المتكررة مماثل للشبكة العصبية التقليدية. ستشاهد بمزيد من التفاصيل كيفية تحسين التعليمات البرمجية في الجزء التالي من هذا البرنامج التعليمي للشبكة العصبية المتكررة.

تطبيقات RNN

RNN لها استخدامات متعددة، خاصة عندما يتعلق الأمر بالتنبؤ بالمستقبل. في الصناعة المالية، يمكن أن تكون RNN مفيدة في التنبؤ بأسعار الأسهم أو علامة اتجاه سوق الأوراق المالية (أي إيجابي أو سلبي).

يعد RNN مفيدًا للسيارة ذاتية القيادة حيث يمكنها تجنب وقوع حادث سيارة من خلال توقع مسار السيارة.

تُستخدم RNN على نطاق واسع في تحليل النصوص والتعليق على الصور وتحليل المشاعر والترجمة الآلية. على سبيل المثال، يمكن للمرء استخدام مراجعة الفيلم لفهم الشعور الذي يشعر به المشاهد بعد مشاهدة الفيلم. تعد أتمتة هذه المهمة مفيدة للغاية عندما لا يكون لدى شركة الأفلام الوقت الكافي لمراجعة المراجعات وتصنيفها وتوحيدها وتحليلها. يمكن للآلة القيام بهذه المهمة بمستوى أعلى من الدقة.

حدود RNN

من الناحية النظرية، من المفترض أن تقوم RNN بحمل المعلومات عدة مرات. ومع ذلك، من الصعب جدًا نشر كل هذه المعلومات عندما تكون الخطوة الزمنية طويلة جدًا. عندما تحتوي الشبكة على عدد كبير جدًا من الطبقات العميقة، تصبح غير قابلة للتدريب. هذه المشكلة تسمى: تلاشي مشكلة التدرج. إذا كنت تتذكر، تقوم الشبكة العصبية بتحديث الوزن باستخدام خوارزمية النسب المتدرج. تصبح التدرجات أصغر عندما تتقدم الشبكة إلى الطبقات السفلية.

في الختام، تظل التدرجات ثابتة مما يعني أنه لا يوجد مجال للتحسين. يتعلم النموذج من التغيير في التدرج؛ يؤثر هذا التغيير على إخراج الشبكة. ومع ذلك، إذا كان الفرق في التدرج صغيرًا جدًا (أي تتغير الأوزان قليلاً)، فلن تتمكن الشبكة من تعلم أي شيء وبالتالي الإخراج. لذلك، لا يمكن للشبكة التي تواجه مشكلة التدرج المتلاشي أن تتقارب نحو حل جيد.

تحسين LSTM

للتغلب على المشكلة المحتملة المتمثلة في اختفاء التدرج التي تواجهها RNN، قام ثلاثة باحثين، وهم هوشريتر وشميدهوبر وبينجيو، بتحسين شبكة RNN باستخدام archiمادة تسمى الذاكرة طويلة المدى (LSTM). باختصار، توفر LSMT للشبكة المعلومات السابقة ذات الصلة بالأوقات الأحدث. الجهاز يستخدم أفضل architecture لاختيار المعلومات ونقلها مرة أخرى إلى later مرة.

LSTM archiالتكنولوجيا متاحة في 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()

RNN في السلاسل الزمنية

يعرض الجزء الأيمن من الرسم البياني جميع السلاسل. لقد بدأت من عام 2001 وتنتهي في عام 2019. ليس من المنطقي تغذية جميع البيانات الموجودة في الشبكة، وبدلاً من ذلك، تحتاج إلى إنشاء مجموعة من البيانات بطول يساوي الخطوة الزمنية. ستكون هذه الدفعة هي المتغير X. المتغير Y هو نفس المتغير X ولكن يتم إزاحته بفترة واحدة (أي أنك تريد التنبؤ بـ t+1).

كلا المتجهين لهما نفس الطول. يمكنك رؤيته في الجزء الأيمن من الرسم البياني أعلاه. يمثل الخط القيم العشر لإدخال X، في حين أن النقاط الحمراء هي القيم العشر للملصق، Y. لاحظ أن التسمية تبدأ بفترة واحدة قبل X وتنتهي بفترة واحدة بعد ذلك.

قم ببناء RNN للتنبؤ بالسلاسل الزمنية في TensorFlow

الآن في تدريب RNN هذا، حان الوقت لبناء أول RNN الخاص بك للتنبؤ بالسلسلة أعلاه. تحتاج إلى تحديد بعض المعلمات الفائقة (معلمات النموذج، أي عدد الخلايا العصبية، وما إلى ذلك) للنموذج:

  • عدد المدخلات: 1
  • خطوة زمنية (windows في السلاسل الزمنية): 10
  • عدد الخلايا العصبية: 120
  • عدد المخرجات: 1

ستتعلم شبكتك من سلسلة مدتها 10 أيام وستحتوي على 120 خلية عصبية متكررة. يمكنك تغذية النموذج بمدخل واحد، أي يوم واحد. لا تتردد في تغيير القيم لمعرفة ما إذا كان النموذج قد تحسن.

قبل إنشاء النموذج، تحتاج إلى تقسيم مجموعة البيانات إلى مجموعة قطار ومجموعة اختبار. تحتوي مجموعة البيانات الكاملة على 222 نقطة بيانات؛ ستستخدم أول 201 نقطة لتدريب النموذج وآخر 21 نقطة لاختبار النموذج الخاص بك.

بعد تحديد مجموعة التدريب والاختبار، تحتاج إلى إنشاء كائن يحتوي على الدُفعات. في هذه الدفعات، لديك قيم X وقيم Y. تذكر أن قيم X متأخرة بفترة واحدة. لذلك، يمكنك استخدام أول 200 ملاحظة والخطوة الزمنية تساوي 10. يجب أن يحتوي كائن X_batches على 20 دفعة بحجم 10*1. يحتوي y_batches على نفس شكل كائن X_batches ولكن بفترة واحدة للأمام.

الخطوة 1) إنشاء القطار والاختبار

أولاً، تقوم بتحويل السلسلة إلى ملف نمباي مجموعة مصفوفة؛ ثم تقوم بتحديد windows (أي عدد الوقت الذي ستتعلم منه الشبكة)، وعدد المدخلات والمخرجات وحجم مجموعة القطارات كما هو موضح في مثال 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). يجب أن يكون لمخرجات الدالة ثلاثة أبعاد. الأبعاد الأولى تساوي عدد الدفعات، والثانية حجم windows وآخر واحد عدد المدخلات.

الجزء الصعب هو تحديد نقاط البيانات بشكل صحيح. بالنسبة لنقاط البيانات 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 architecture. تذكر أن لديك 120 خلية عصبية متكررة.

الخطوة 3) قم ببناء النموذج

لإنشاء النموذج، تحتاج إلى تحديد ثلاثة أجزاء:

  1. المتغير مع الموترات
  2. آر إن إن
  3. الخسارة والتحسين

الخطوة 3.1) المتغيرات

تحتاج إلى تحديد متغيرات X وy بالشكل المناسب. هذه الخطوة تافهة. الموتر له نفس البعد مثل الكائنات X_batches و y_batches.

على سبيل المثال، الموتر X هو عنصر نائب (راجع البرنامج التعليمي حول مقدمة إلى Tensorflow لتحديث عقلك حول إعلان المتغير) له ثلاثة أبعاد:

  • ملاحظة: حجم الدفعة
  • n_windows: طول 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

في الجزء الثاني من مثال RNN TensorFlow، تحتاج إلى تحديد ملف archiبنية الشبكة. كما كان من قبل، يمكنك استخدام الكائن 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، يمكنك رسم القيمة الفعلية للسلسلة بالقيمة المتوقعة. إذا تم تصحيح النموذج الخاص بك، فيجب وضع القيم المتوقعة فوق القيم الفعلية.

كما ترون، النموذج لديه مجال للتحسين. الأمر متروك لك لتغيير المعلمات الفائقة مثل windows، حجم الدفعة من عدد الخلايا العصبية المتكررة.

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()
توقعات مقابل الفعلي

توقعات مقابل الفعلي

نبذة عامة

الشبكة العصبية المتكررة قوية archiتقنية للتعامل مع السلاسل الزمنية أو تحليل النص. ومخرجات الحالة السابقة هي التغذية الراجعة للحفاظ على ذاكرة الشبكة مع مرور الوقت أو تسلسل الكلمات.

في TensorFlow، يمكنك استخدام following رموز لتدريب الشبكة العصبية المتكررة 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})