Οδηγός RNN (Recurrent Neural Network): Παράδειγμα TensorFlow
⚡ Έξυπνη Σύνοψη
Τα Επαναλαμβανόμενα Νευρωνικά Δίκτυα προσθέτουν μια κατάσταση μνήμης σε συνηθισμένους νευρώνες, τροφοδοτώντας κάθε έξοδο ως την επόμενη είσοδο, ώστε το μοντέλο να μπορεί να μάθει από τη σειρά. Αυτή η αναλυτική παρουσίαση δημιουργεί μια κατάσταση μνήμης στο TensorFlow και προβλέπει μια χρονοσειρά.
Γιατί χρειαζόμαστε ένα επαναλαμβανόμενο νευρωνικό δίκτυο (RNN);
Το επαναλαμβανόμενο νευρωνικό δίκτυο (RNN) σάς επιτρέπει να μοντελοποιείτε μονάδες μνήμης για να διατηρούνται δεδομένα και να μοντελοποιείτε βραχυπρόθεσμες εξαρτήσεις. Χρησιμοποιείται επίσης στην πρόβλεψη χρονοσειρών για τον προσδιορισμό συσχετίσεων και προτύπων δεδομένων. Βοηθά επίσης στην παραγωγή προγνωστικών αποτελεσμάτων για διαδοχικά δεδομένα, παρέχοντας παρόμοια συμπεριφορά με τον ανθρώπινο εγκέφαλο.
Η δομή ενός Τεχνητό Νευρωνικό Δίκτυο είναι σχετικά απλή και αφορά κυρίως τον πολλαπλασιασμό πινάκων. Κατά τη διάρκεια του πρώτου βήματος, οι είσοδοι πολλαπλασιάζονται με αρχικά τυχαία βάρη και μεροληψία, μετασχηματίζονται με μια συνάρτηση ενεργοποίησης και οι τιμές εξόδου χρησιμοποιούνται για να γίνει μια πρόβλεψη. Αυτό το βήμα δίνει μια ιδέα για το πόσο μακριά βρίσκεται το δίκτυο από την πραγματικότητα.
Η μέτρηση που εφαρμόζεται είναι η απώλεια. Όσο μεγαλύτερη είναι η συνάρτηση απώλειας, τόσο πιο χαζό είναι το μοντέλο. Για να βελτιωθεί η γνώση του δικτύου, απαιτείται κάποια βελτιστοποίηση με την προσαρμογή των βαρών του δικτύου. Η στοχαστική βαθμιδωτή κάθοδος είναι η μέθοδος που χρησιμοποιείται για την αλλαγή των τιμών των βαρών προς τη σωστή κατεύθυνση. Μόλις γίνει η προσαρμογή, το δίκτυο μπορεί να χρησιμοποιήσει μια άλλη παρτίδα δεδομένων για να δοκιμάσει τις νέες γνώσεις του.
Το σφάλμα, ευτυχώς, είναι μικρότερο από πριν, αλλά όχι αρκετά μικρό. Το βήμα βελτιστοποίησης γίνεται επαναληπτικά μέχρι να ελαχιστοποιηθεί το σφάλμα, δηλαδή, να μην μπορούν να εξαχθούν περισσότερες πληροφορίες.tracξυραίνω χόρτα.
Το πρόβλημα με αυτόν τον τύπο μοντέλου είναι ότι δεν έχει μνήμη. Σημαίνει ότι η είσοδος και η έξοδος είναι ανεξάρτητες. Με άλλα λόγια, το μοντέλο δεν ενδιαφέρεται για το τι προηγήθηκε. Εγείρει κάποιο ερώτημα όταν χρειάζεται να προβλέψετε χρονοσειρές ή προτάσεις, επειδή το δίκτυο πρέπει να έχει πληροφορίες σχετικά με τα ιστορικά δεδομένα ή τις προηγούμενες λέξεις.
Για να ξεπεραστεί αυτό το ζήτημα, έχει αναπτυχθεί ένας νέος τύπος αρχιτεκτονικής: Επαναλαμβανόμενο νευρωνικό δίκτυο (RNN εφεξής)
Τι είναι ένα επαναλαμβανόμενο νευρωνικό δίκτυο (RNN);
Ένα Επαναλαμβανόμενο Νευρωνικό Δίκτυο (RNN) είναι μια κατηγορία Τεχνητών Νευρωνικών Δικτύων στα οποία η σύνδεση μεταξύ διαφορετικών κόμβων σχηματίζει ένα κατευθυνόμενο γράφημα για να δώσει μια χρονική δυναμική συμπεριφορά. Βοηθά στη μοντελοποίηση διαδοχικών δεδομένων που προέρχονται από δίκτυα ανάδρασης. Λειτουργεί παρόμοια με τον ανθρώπινο εγκέφαλο για να παρέχει προγνωστικά αποτελέσματα.
Ένα επαναλαμβανόμενο νευρωνικό δίκτυο μοιάζει αρκετά με ένα παραδοσιακό νευρωνικό δίκτυο εκτός από το ότι προστίθεται μια κατάσταση μνήμης στους νευρώνες. Ο υπολογισμός για τη συμπερίληψη μνήμης είναι απλός.
Φανταστείτε ένα απλό μοντέλο με μόνο έναν νευρώνα που τροφοδοτείται από μια δέσμη δεδομένων. Σε ένα παραδοσιακό νευρωνικό δίκτυο, το μοντέλο παράγει την έξοδο πολλαπλασιάζοντας την είσοδο με το βάρος και τη συνάρτηση ενεργοποίησης. Με ένα RNN, αυτή η έξοδος αποστέλλεται πίσω στον εαυτό της όσες φορές χρειάζεται. Ονομάζουμε χρονικό βήμα ο χρόνος που η έξοδος γίνεται η είσοδος του επόμενου πολλαπλασιασμού πίνακα.
Για παράδειγμα, στην παρακάτω εικόνα, μπορείτε να δείτε ότι το δίκτυο αποτελείται από έναν νευρώνα. Το δίκτυο υπολογίζει τον πολλαπλασιασμό των πινάκων μεταξύ της εισόδου και του βάρους και προσθέτει μη γραμμικότητα με τη συνάρτηση ενεργοποίησης. Γίνεται η έξοδος στο t-1. Αυτή η έξοδος είναι η είσοδος του δεύτερου πολλαπλασιασμού του πίνακα.
Επαναλαμβανόμενο νευρωνικό δίκτυο (RNN)
Παρακάτω, κωδικοποιούμε ένα απλό RNN στο TensorFlow για να κατανοήσουμε το βήμα και επίσης το σχήμα της εξόδου.
Το δίκτυο αποτελείται από:
- Τέσσερις είσοδοι
- Έξι νευρώνες
- 2-χρονικά βήματα
Το δίκτυο θα προχωρήσει όπως φαίνεται στην παρακάτω εικόνα.
Το δίκτυο ονομάζεται «επαναλαμβανόμενο» επειδή εκτελεί την ίδια λειτουργία σε κάθε τετράγωνο ενεργοποίησης. Το δίκτυο υπολόγισε τα βάρη των εισόδων και της προηγούμενης εξόδου πριν χρησιμοποιήσει μια συνάρτηση ενεργοποίησης.
Σημείωση έκδοσης: Ο κώδικας σε αυτό το σεμινάριο στοχεύει στο API γραφήματος TensorFlow 1.x. Στο TensorFlow 2.x το ίδιο σενάριο εξακολουθεί να εκτελείται μετά import tensorflow.compat.v1 as tf συν tf.disable_v2_behavior(), επειδή τα placeholders, οι συνεδρίες και η ενότητα 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.BasicRNNCcell με το όρισμα 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 υποτίθεται ότι μεταφέρει τις πληροφορίες μέχρι και πολλές φορές. Ωστόσο, είναι αρκετά δύσκολο να διαδοθούν όλες αυτές οι πληροφορίες όταν το χρονικό βήμα είναι πολύ μεγάλο. Όταν ένα δίκτυο έχει πάρα πολλά βαθιά στρώματα, γίνεται μη εκπαιδεύσιμο. Αυτό το πρόβλημα ονομάζεται: εξαφανισμένο πρόβλημα διαβάθμισης. Αν θυμάστε, το νευρωνικό δίκτυο ενημερώνει το βάρος χρησιμοποιώντας τον αλγόριθμο gradient descent. Οι κλίσεις γίνονται μικρότερες όταν το δίκτυο προχωρά σε χαμηλότερα επίπεδα.
Συμπερασματικά, οι διαβαθμίσεις παραμένουν σταθερές, πράγμα που σημαίνει ότι δεν υπάρχει περιθώριο βελτίωσης. Το μοντέλο μαθαίνει από μια αλλαγή στην διαβάθμιση. Αυτή η αλλαγή επηρεάζει την έξοδο του δικτύου. Ωστόσο, εάν η διαφορά στην διαβάθμιση είναι πολύ μικρή (δηλαδή, τα βάρη αλλάζουν λίγο), το δίκτυο δεν μπορεί να μάθει τίποτα και άρα και την έξοδο. Επομένως, ένα δίκτυο που αντιμετωπίζει ένα πρόβλημα μηδενικής διαβάθμισης δεν μπορεί να συγκλίνει προς μια καλή λύση.
Βελτίωση LSTM
Για να ξεπεραστεί το πιθανό πρόβλημα της εξαφάνισης της κλίσης που αντιμετωπίζουν τα RNN, τρεις ερευνητές, οι Hochreiter, Schmidhuber και Bengio, βελτίωσαν το 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 σε χρονοσειρές
Σε αυτό το σεμινάριο 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 επαναλαμβανόμενους νευρώνες. Τροφοδοτείτε το μοντέλο με μία είσοδο, δηλαδή, μία ημέρα. Μη διστάσετε να αλλάξετε τις τιμές για να δείτε αν το μοντέλο βελτιώθηκε.
Πριν από την κατασκευή του μοντέλου, πρέπει να διαχωρίσετε το σύνολο δεδομένων σε ένα σύνολο δεδομένων (train set) και ένα σύνολο δεδομένων (test set). Το πλήρες σύνολο δεδομένων έχει 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 για την κατασκευή των παρτίδων.
Σημειώστε ότι, οι παρτίδες Χ υστερούν κατά μία περίοδο (λαμβάνουμε την τιμή t-1). Η έξοδος της συνάρτησης πρέπει να έχει τρεις διαστάσεις. Οι πρώτες διαστάσεις ισούνται με τον αριθμό των παρτίδων, η δεύτερη το μέγεθος των παραθύρων και η τελευταία με τον αριθμό των εισροών.
Το δύσκολο κομμάτι είναι να επιλέξετε σωστά τα σημεία δεδομένων. Για τα σημεία δεδομένων Χ, επιλέγετε τις παρατηρήσεις από 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. Είναι λογικό ότι, είναι δύσκολο να προβλεφθεί με ακρίβεια t+n ημέρες μπροστά.
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) Δημιουργήστε το μοντέλο
Για να δημιουργήσετε το μοντέλο, πρέπει να ορίσετε τρία μέρη:
- Η μεταβλητή με τους τανυστές
- Το RNN
- Η απώλεια και η βελτιστοποίηση
Βήμα 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
Στο δεύτερο μέρος αυτού του παραδείγματος RNN TensorFlow, πρέπει να ορίσετε την αρχιτεκτονική του δικτύου. Όπως και πριν, χρησιμοποιείτε το αντικείμενο 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) Δημιουργήστε την απώλεια και τη βελτιστοποίηση
Η βελτιστοποίηση του μοντέλου εξαρτάται από την εργασία που εκτελείτε. Στο προηγούμενο σεμινάριο CNN, ο στόχος σας ήταν να ταξινομήσετε εικόνες, σε αυτό το σεμινάριο RNN, ο στόχος είναι ελαφρώς διαφορετικός. Σας ζητείται να κάνετε μια πρόβλεψη για μια συνεχή μεταβλητή σε σύγκριση με μια κλάση.
Αυτή η διαφορά είναι σημαντική γιατί θα αλλάξει το πρόβλημα βελτιστοποίησης. Το πρόβλημα βελτιστοποίησης για μια συνεχή μεταβλητή είναι η ελαχιστοποίηση του μέσου τετραγώνου σφάλματος. Για να δημιουργήσετε αυτές τις μετρήσεις στο TF, μπορείτε να χρησιμοποιήσετε:
tf.reduce_sum(tf.square(έξοδοι – y))
Το υπόλοιπο του κώδικα RNN είναι το ίδιο με πριν. χρησιμοποιείτε ένα Adam optimizer για να μειώσετε την απώλεια (δηλαδή, MSE):
tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer.minimize(απώλεια)
Αυτό είναι όλο, μπορείτε να τα μαζέψετε όλα μαζί και το μοντέλο σας είναι έτοιμο για εκπαίδευση.
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()
Πρόβλεψη vs Πραγματική





