Ας ρίξουμε μια βαθιά βουτιά στη μάθηση ενίσχυσης. Σε αυτό το άρθρο, θα αντιμετωπίσουμε ένα συγκεκριμένο πρόβλημα με τις σύγχρονες βιβλιοθήκες όπως το TensorFlow, το TensorBoard, το Keras και το γυμναστήριο OpenAI. Θα δείτε πώς να εφαρμόσετε έναν από τους θεμελιώδεις αλγόριθμους που ονομάζεται deep $ Q $ -learning για να μάθετε την εσωτερική του λειτουργία. Όσον αφορά το υλικό, ολόκληρος ο κώδικας θα λειτουργήσει σε έναν τυπικό υπολογιστή και θα χρησιμοποιήσει όλους τους πυρήνες CPU που έχουν βρεθεί (αυτό διαχειρίζεται από το TensorFlow).
Το πρόβλημα ονομάζεται Mountain Car: Ένα αυτοκίνητο βρίσκεται σε μονοδιάστατη πίστα, τοποθετημένο ανάμεσα σε δύο βουνά. Ο στόχος είναι να ανεβείτε το βουνό στα δεξιά (φτάνοντας στη σημαία). Ωστόσο, ο κινητήρας του αυτοκινήτου δεν είναι αρκετά ισχυρός για να ανέβει στο βουνό με ένα μόνο πέρασμα. Επομένως, ο μόνος τρόπος να πετύχεις είναι να κινηθείς εμπρός και πίσω για να ενισχύσεις την ορμή.
Αυτό το πρόβλημα επιλέχθηκε επειδή είναι αρκετά απλό να βρει μια λύση με ενίσχυση εκμάθησης σε λίγα λεπτά σε έναν μόνο πυρήνα CPU. Ωστόσο, είναι αρκετά περίπλοκο για να είναι καλός εκπρόσωπος.
Πρώτον, θα δώσω μια σύντομη περίληψη για το τι κάνει η μάθηση ενίσχυσης γενικά. Στη συνέχεια, θα καλύψουμε βασικούς όρους και θα εκφράσουμε το πρόβλημά μας μαζί τους. Μετά από αυτό, θα περιγράψω τον βαθύ αλγόριθμο μάθησης $ Q $ και θα τον εφαρμόσουμε για να λύσουμε το πρόβλημα.
Η εκμάθηση ενίσχυσης με τις πιο απλές λέξεις είναι η μάθηση με δοκιμή και λάθος. Ο κύριος χαρακτήρας ονομάζεται «πράκτορας», ο οποίος θα ήταν ένα αυτοκίνητο στο πρόβλημά μας. Ο πράκτορας κάνει μια ενέργεια σε ένα περιβάλλον και του δίνεται μια νέα παρατήρηση και μια ανταμοιβή για αυτήν την ενέργεια. Ενισχύονται οι ενέργειες που οδηγούν σε μεγαλύτερες ανταμοιβές, εξ ου και το όνομα. Όπως με πολλά άλλα πράγματα στην επιστήμη των υπολογιστών, αυτό εμπνεύστηκε επίσης από την παρατήρηση ζωντανών πλασμάτων.
Οι αλληλεπιδράσεις του πράκτορα με ένα περιβάλλον συνοψίζονται στο ακόλουθο γράφημα:
ποια γλώσσα προγραμματισμού χρησιμοποιούν τα ρομπότ
Ο πράκτορας παίρνει μια παρατήρηση και ανταμοιβή για την εκτέλεση της δράσης. Στη συνέχεια, κάνει μια άλλη ενέργεια και κάνει το δεύτερο βήμα. Το περιβάλλον επιστρέφει τώρα (πιθανώς) ελαφρώς διαφορετική παρατήρηση και ανταμοιβή. Αυτό συνεχίζεται έως ότου επιτευχθεί η κατάσταση τερματικού, σηματοδοτώντας στέλνοντας «ολοκληρωμένο» σε έναν πράκτορα. Η όλη ακολουθία του παρατηρήσεις> ενέργειες> επόμενες_επιτηρήσεις> ανταμοιβές ονομάζεται επεισόδιο (ή τροχιά).
Επιστροφή στο Mountain Car: το αυτοκίνητό μας είναι πράκτορας. Το περιβάλλον είναι ένας κόσμος μαύρων κουτιών μονοδιάστατων βουνών. Η δράση του αυτοκινήτου κυμαίνεται σε έναν μόνο αριθμό: εάν είναι θετικό, ο κινητήρας σπρώχνει το αυτοκίνητο προς τα δεξιά. Εάν είναι αρνητικό, σπρώχνει το αυτοκίνητο προς τα αριστερά. Ο πράκτορας αντιλαμβάνεται ένα περιβάλλον μέσω μιας παρατήρησης: τη θέση Χ και την ταχύτητα του αυτοκινήτου. Εάν θέλουμε το αυτοκίνητό μας να οδηγεί στην κορυφή του βουνού, ορίζουμε την επιβράβευση με βολικό τρόπο: Ο πράκτορας παίρνει -1 στην ανταμοιβή του για κάθε βήμα στο οποίο δεν έχει φτάσει στο στόχο. Όταν φτάσει στο στόχο, το επεισόδιο τελειώνει. Έτσι, στην πραγματικότητα, ο πράκτορας τιμωρείται επειδή δεν είναι σε θέση που θέλουμε να είναι. Όσο πιο γρήγορα φτάνει, τόσο καλύτερο για αυτόν. Ο στόχος του πράκτορα είναι να μεγιστοποιήσει τη συνολική ανταμοιβή, που είναι το άθροισμα των ανταμοιβών από ένα επεισόδιο. Αν λοιπόν φτάσει στο επιθυμητό σημείο μετά από, π.χ., 110 βήματα, λαμβάνει συνολική απόδοση -110, κάτι που θα ήταν εξαιρετικό αποτέλεσμα για το Mountain Car, γιατί αν δεν φτάσει στον στόχο, τιμωρείται για 200 βήματα (ως εκ τούτου, μια απόδοση -200).
Αυτή είναι η όλη διατύπωση προβλημάτων. Τώρα, μπορούμε να το δώσουμε στους αλγόριθμους, οι οποίοι είναι ήδη αρκετά ισχυροί για την επίλυση τέτοιων προβλημάτων μέσα σε λίγα λεπτά (εάν είναι καλά συντονισμένοι). Αξίζει να σημειωθεί ότι δεν λέμε στον πράκτορα πώς να επιτύχει το στόχο. Δεν παρέχουμε καν υπαινιγμούς (ευρετικές). Ο πράκτορας θα βρει έναν τρόπο (μια πολιτική) να κερδίσει μόνος του.
Αρχικά, αντιγράψτε ολόκληρο τον κωδικό εκμάθησης στο δίσκο σας:
git clone https://github.com/AdamStelmaszczyk/rl-tutorial cd rl-tutorial
Τώρα, πρέπει να εγκαταστήσουμε πακέτα Python που θα χρησιμοποιήσουμε. Για να μην τα εγκαταστήσετε στο χώρο χρήστη σας (και συγκρούσεις κινδύνου), θα το κάνουμε καθαρό και θα τα εγκαταστήσουμε στο περιβάλλον conda. Εάν δεν έχετε εγκαταστήσει conda, ακολουθήστε https://conda.io/docs/user-guide/install/index.html .
Για να δημιουργήσουμε το περιβάλλον conda:
conda create -n tutorial python=3.6.5 -y
Για να το ενεργοποιήσετε:
source activate tutorial
Θα πρέπει να δείτε (tutorial)
κοντά στην προτροπή σας στο κέλυφος. Αυτό σημαίνει ότι ένα περιβάλλον conda με το όνομα «φροντιστήριο» είναι ενεργό. Από τώρα και στο εξής, όλες οι εντολές θα πρέπει να εκτελούνται σε αυτό το περιβάλλον.
Τώρα, μπορούμε να εγκαταστήσουμε όλες τις εξαρτήσεις στο ερμητικό περιβάλλον conda:
pip install -r requirements.txt
Τελειώσαμε με την εγκατάσταση, οπότε ας τρέξουμε κάποιον κώδικα. Δεν χρειάζεται να εφαρμόσουμε οι ίδιοι το περιβάλλον του Mountain Car. η βιβλιοθήκη OpenAI Gym παρέχει αυτήν την εφαρμογή. Ας δούμε έναν τυχαίο παράγοντα (έναν πράκτορα που κάνει τυχαίες ενέργειες) στο περιβάλλον μας:
import gym env = gym.make('MountainCar-v0') done = True episode = 0 episode_return = 0.0 for episode in range(5): for step in range(200): if done: if episode > 0: print('Episode return: ', episode_return) obs = env.reset() episode += 1 episode_return = 0.0 env.render() else: obs = next_obs action = env.action_space.sample() next_obs, reward, done, _ = env.step(action) episode_return += reward env.render()
Αυτό είναι see.py
αρχείο; για να το εκτελέσετε, εκτελέστε:
python see.py
Θα πρέπει να δείτε ένα αυτοκίνητο να πηγαίνει τυχαία μπρος-πίσω. Κάθε επεισόδιο θα αποτελείται από 200 βήματα. η συνολική απόδοση θα είναι -200.
Τώρα πρέπει να αντικαταστήσουμε τις τυχαίες ενέργειες με κάτι καλύτερο. Υπάρχουν πολλοί αλγόριθμοι που θα μπορούσε κανείς να χρησιμοποιήσει. Για ένα εισαγωγικό σεμινάριο, πιστεύω ότι μια προσέγγιση που ονομάζεται deep $ Q $ -learning είναι μια καλή εφαρμογή. Η κατανόηση αυτής της μεθόδου δίνει μια σταθερή βάση για την εκμάθηση άλλων προσεγγίσεων.
πώς λειτουργούν τα μετατρέψιμα χαρτονομίσματα
Ο αλγόριθμος που θα χρησιμοποιήσουμε περιγράφηκε για πρώτη φορά το 2013 από τους Mnih et al. σε Παίζοντας Atari με εκμάθηση βαθιάς ενίσχυσης και γυαλίστηκε δύο χρόνια αργότερα Έλεγχος σε ανθρώπινο επίπεδο μέσω μάθησης βαθιάς ενίσχυσης . Πολλά άλλα έργα βασίζονται σε αυτά τα αποτελέσματα, συμπεριλαμβανομένου του τρέχοντος αλγόριθμου τελευταίας τεχνολογίας ΟΥΡΑΝΙΟ ΤΟΞΟ (2017):
Το Rainbow επιτυγχάνει υπεράνθρωπες επιδόσεις σε πολλά παιχνίδια Atari 2600. Θα επικεντρωθούμε στη βασική έκδοση DQN, με όσο το δυνατόν μικρότερο αριθμό πρόσθετων βελτιώσεων, για να διατηρήσουμε αυτό το σεμινάριο σε λογικό μέγεθος.
Μια πολιτική, που συνήθως υποδηλώνεται $ π (s) $, είναι μια συνάρτηση που επιστρέφει τις πιθανότητες πραγματοποίησης μεμονωμένων ενεργειών σε μια δεδομένη κατάσταση $ s $. Έτσι, για παράδειγμα, μια τυχαία πολιτική Mountain Car επιστρέφει για οποιαδήποτε κατάσταση: 50% αριστερά, 50% δεξιά. Κατά τη διάρκεια του παιχνιδιού, λαμβάνουμε δείγματα από αυτήν την πολιτική (διανομή) για να λάβουμε πραγματικές ενέργειες.
$ Q $ -learning (το Q είναι για Ποιότητα) αναφέρεται στη συνάρτηση τιμής-ενέργειας που υποδηλώνεται $ Q_π (s, a) $. Επιστρέφει τη συνολική απόδοση από μια δεδομένη κατάσταση $ s $, επιλέγοντας δράση $ a $, ακολουθώντας μια συγκεκριμένη πολιτική $ π $. Η συνολική απόδοση είναι το άθροισμα όλων των ανταμοιβών σε ένα επεισόδιο (τροχιά).
Εάν γνωρίζαμε τη βέλτιστη λειτουργία $ Q $, που υποδηλώνεται $ Q ^ * $, θα μπορούσαμε να λύσουμε εύκολα το παιχνίδι. Θα ακολουθούσαμε απλώς τις ενέργειες με την υψηλότερη τιμή $ Q ^ * $, δηλαδή την υψηλότερη αναμενόμενη απόδοση. Αυτό εγγυάται ότι θα φτάσουμε στην υψηλότερη δυνατή απόδοση.
Ωστόσο, συχνά δεν γνωρίζουμε $ Q ^ * $. Σε τέτοιες περιπτώσεις, μπορούμε να προσεγγίσουμε - ή 'μάθουμε' - από τις αλληλεπιδράσεις με το περιβάλλον. Αυτό είναι το τμήμα '$ Q $ -learning' στο όνομα. Υπάρχει επίσης η λέξη «βαθιά» σε αυτήν, διότι, για να προσεγγίσουμε αυτήν τη λειτουργία, θα χρησιμοποιήσουμε βαθιά νευρωνικά δίκτυα, τα οποία είναι καθολικές προσεγγιστικές λειτουργιών. Βαθιά νευρωνικά δίκτυα που εκτιμούν περίπου $ Q $ -τιμές ονομάστηκαν Deep Q-Networks (DQN). Σε απλά περιβάλλοντα (με τον αριθμό καταστάσεων που ταιριάζουν στη μνήμη), κάποιος θα μπορούσε απλώς να χρησιμοποιήσει έναν πίνακα αντί ενός νευρικού δικτύου για να αντιπροσωπεύσει τη συνάρτηση $ Q $, οπότε θα ονομαζόταν «πίνακας $ Q $ -learning».
Έτσι, ο στόχος μας τώρα είναι να προσεγγίσουμε τη συνάρτηση $ Q ^ * $. Θα χρησιμοποιήσουμε την εξίσωση Bellman:
[Q (s, a) = r + γ space textrm {max} _ {a '} Q (s', a ') ]$ s ’$ είναι η κατάσταση μετά από $ s $. $ γ $ (gamma), συνήθως 0,99, είναι συντελεστής έκπτωσης (είναι υπερπαραμετρος). Δίνει μικρότερο βάρος στις μελλοντικές ανταμοιβές (επειδή είναι λιγότερο σίγουρες από τις άμεσες ανταμοιβές με τα ατελή μας $ Q $). Η εξίσωση Bellman είναι κεντρική για βαθιά μάθηση $ Q $. Λέει ότι η τιμή $ Q $ για μια δεδομένη κατάσταση και ενέργεια είναι μια ανταμοιβή $ r $ που έλαβε μετά την ανάληψη δράσης $ a $ περισσότερο η υψηλότερη τιμή $ Q $ για το κράτος στο οποίο προσφέρουμε $ $. Το υψηλότερο είναι με την έννοια ότι επιλέγουμε μια ενέργεια $ a ’$, η οποία οδηγεί στην υψηλότερη συνολική απόδοση από $ s’ $.
Με την εξίσωση Bellman, μπορούμε να χρησιμοποιήσουμε την εποπτευόμενη μάθηση για να προσεγγίσουμε $ Q ^ * $. Η συνάρτηση $ Q $ θα αναπαρασταθεί (παραμετρικοποιηθεί) από βάρη νευρωνικών δικτύων που υποδηλώνονται ως $ θ $ (θήτα). Μια απλή εφαρμογή θα πάρει μια κατάσταση και μια ενέργεια ως το δίκτυο εισόδου και εξόδου της τιμής Q. Η αναποτελεσματικότητα είναι ότι αν θέλουμε να μάθουμε $ Q $ -values για όλες τις ενέργειες σε μια δεδομένη κατάσταση, πρέπει να καλέσουμε $ Q $ όσες φορές υπάρχουν ενέργειες. Υπάρχει ένας πολύ καλύτερος τρόπος: να λαμβάνετε μόνο την κατάσταση ως είσοδο και έξοδο $ Q $ -values για όλες τις πιθανές ενέργειες. Χάρη σε αυτό, μπορούμε να λάβουμε $ Q $ -values για όλες τις ενέργειες σε ένα μόνο πάσο.
Αρχίζουμε να εκπαιδεύουμε το δίκτυο $ Q $ με τυχαία βάρη. Από το περιβάλλον, λαμβάνουμε πολλές μεταβάσεις (ή «εμπειρίες»). Πρόκειται για πλειάδες (κατάσταση, ενέργεια, επόμενη κατάσταση, ανταμοιβή) ή, εν συντομία, ($ s $, $ a $, $ s $, $ r $). Αποθηκεύουμε χιλιάδες από αυτούς σε ένα buffer δακτυλίου που ονομάζεται 'επανάληψη εμπειρίας'. Στη συνέχεια, δοκιμάζουμε εμπειρίες από αυτό το buffer με την επιθυμία ότι η εξίσωση Bellman θα τους κρατήσει. Θα μπορούσαμε να παραλείψουμε το buffer και να εφαρμόσουμε εμπειρίες ένα προς ένα (αυτό ονομάζεται 'online' ή 'on-policy'). Το πρόβλημα είναι ότι οι επακόλουθες εμπειρίες συσχετίζονται πολύ μεταξύ τους και το DQN εκπαιδεύεται άσχημα όταν συμβαίνει αυτό. Αυτός είναι ο λόγος για τον οποίο παρουσιάστηκε η επανάληψη της εμπειρίας (μια προσέγγιση 'εκτός σύνδεσης', 'εκτός πολιτικής') για τη διακοπή αυτής της συσχέτισης δεδομένων. Ο κώδικας της απλούστερης εφαρμογής buffer δακτυλίου βρίσκεται στο replay_buffer.py
αρχείο, σας ενθαρρύνω να το διαβάσετε.
Στην αρχή, δεδομένου ότι τα βάρη του νευρικού δικτύου μας ήταν τυχαία, η τιμή της αριστεράς πλευράς της εξίσωσης Bellman θα απέχει πολύ από τη δεξιά πλευρά. Η τετραγωνική διαφορά θα είναι η λειτουργία απώλειας. Θα ελαχιστοποιήσουμε τη λειτουργία απώλειας αλλάζοντας τα βάρη του νευρικού δικτύου $ θ $. Ας γράψουμε τη λειτουργία απώλειας:
[L (θ) = [Q (s, a) - r - γ space textrm {max} _ {a '} Q (s', a ')] ^ 2 ]Είναι μια επανεγγραφημένη εξίσωση Bellman. Ας υποθέσουμε ότι δοκιμάσαμε μια εμπειρία ($ s $, αριστερά, $ s, $, -1) από την επανάληψη της εμπειρίας Mountain Car. Κάνουμε μια προώθηση προς τα εμπρός μέσω του δικτύου μας $ Q $ με κατάσταση $ s $ και για δράση που μας αφήνει -120, για παράδειγμα. Έτσι, $ Q (s, textrm {αριστερά}) = -120 $. Στη συνέχεια τροφοδοτούμε $ $ στο δίκτυο, το οποίο μας δίνει, π.χ. -130 για αριστερά και -122 για δεξιά. Οπότε σαφώς η καλύτερη ενέργεια για $ $ είναι σωστή, έτσι $ textrm {max} _ {a '} Q (s', a ') = -122 $. Γνωρίζουμε $ r $, αυτή είναι η πραγματική ανταμοιβή, η οποία ήταν -1. Έτσι, η πρόβλεψη δικτύου $ Q $-ήταν λίγο λάθος, επειδή $ L (θ) = [-120 - 1 + 0,99 ⋅ 122] ^ 2 = (-0,22 ^ 2) = 0,0484 $. Έτσι, διαδώσαμε προς τα πίσω το σφάλμα και διορθώσαμε ελαφρώς τα βάρη $ θ $. Αν επρόκειτο να υπολογίσουμε ξανά την απώλεια για την ίδια εμπειρία, θα ήταν τώρα χαμηλότερο.
Μια σημαντική παρατήρηση πριν πάμε στον κώδικα. Ας παρατηρήσουμε ότι, για να ενημερώσουμε το DQN μας, θα κάνουμε δύο προωθητικά περάσματα στο ίδιο το DQN… Αυτό συχνά οδηγεί σε ασταθή μάθηση. Για να το μετριάσουμε αυτό, για την επόμενη πρόβλεψη $ Q $, δεν χρησιμοποιούμε το ίδιο DQN. Χρησιμοποιούμε μια παλαιότερη έκδοση της, η οποία στον κωδικό ονομάζεται target_model
(αντί για model
, το κύριο DQN). Χάρη σε αυτό, έχουμε έναν σταθερό στόχο. Ενημερώνουμε target_model
ορίζοντάς το σε model
βάρη κάθε 1000 βήματα. Αλλά model
ενημερώνει κάθε βήμα.
Ας δούμε τον κώδικα που δημιουργεί το μοντέλο DQN:
def create_model(env): n_actions = env.action_space.n obs_shape = env.observation_space.shape observations_input = keras.layers.Input(obs_shape, name='observations_input') action_mask = keras.layers.Input((n_actions,), name='action_mask') hidden = keras.layers.Dense(32, activation='relu')(observations_input) hidden_2 = keras.layers.Dense(32, activation='relu')(hidden) output = keras.layers.Dense(n_actions)(hidden_2) filtered_output = keras.layers.multiply([output, action_mask]) model = keras.models.Model([observations_input, action_mask], filtered_output) optimizer = keras.optimizers.Adam(lr=LEARNING_RATE, clipnorm=1.0) model.compile(optimizer, loss='mean_squared_error') return model
Πρώτον, η λειτουργία παίρνει τις διαστάσεις του χώρου δράσης και παρατήρησης από το δεδομένο περιβάλλον OpenAI Gym. Είναι απαραίτητο να γνωρίζουμε, για παράδειγμα, πόσες εξόδους θα έχει το δίκτυό μας. Πρέπει να ισούται με τον αριθμό των ενεργειών. Οι ενέργειες είναι μια καυτή κωδικοποίηση:
def one_hot_encode(n, action): one_hot = np.zeros(n) one_hot[int(action)] = 1 return one_hot
Έτσι (π.χ.) αριστερά θα είναι [1, 0] και δεξιά θα είναι [0, 1].
Μπορούμε να δούμε ότι οι παρατηρήσεις περνούν ως είσοδο. Περνάμε επίσης action_mask
ως δεύτερη είσοδος. Γιατί; Κατά τον υπολογισμό του $ Q (s, a) $, πρέπει να γνωρίζουμε την τιμή $ Q $-μόνο για μία δεδομένη ενέργεια και όχι όλες. action_mask
περιέχει 1 για τις ενέργειες που θέλουμε να περάσουμε στην έξοδο DQN. Εάν action_mask
έχει 0 για κάποια ενέργεια, τότε η αντίστοιχη τιμή $ Q $ θα μηδενιστεί στην έξοδο. Το filtered_output
στρώμα το κάνει αυτό. Αν θέλουμε όλες τις τιμές $ Q $ (για μέγιστο υπολογισμό), μπορούμε να περάσουμε όλες.
Ο κωδικός χρησιμοποιεί keras.layers.Dense
για να ορίσετε ένα πλήρως συνδεδεμένο επίπεδο. Το Keras είναι μια βιβλιοθήκη Python για άντληση υψηλότερου επιπέδου πάνω από το TensorFlow. Κάτω από την κουκούλα, ο Keras δημιουργεί ένα γράφημα TensorFlow, με προκαταλήψεις, σωστή προετοιμασία βάρους και άλλα πράγματα χαμηλού επιπέδου. Θα μπορούσαμε απλώς να χρησιμοποιήσουμε το Raw TensorFlow για να καθορίσουμε το γράφημα, αλλά δεν θα είναι ένα μονό στρώμα.
Έτσι, οι παρατηρήσεις μεταφέρονται στο πρώτο κρυφό στρώμα, με ενεργοποιήσεις ReLU (διορθωμένη γραμμική μονάδα). ReLU(x)
είναι απλώς μια συνάρτηση $ textrm {max} (0, x) $. Αυτό το επίπεδο είναι πλήρως συνδεδεμένο με ένα δεύτερο πανομοιότυπο, hidden_2
. Το επίπεδο εξόδου μειώνει τον αριθμό των νευρώνων στον αριθμό των δράσεων. Στο τέλος, έχουμε filtered_output
, το οποίο πολλαπλασιάζει την έξοδο με action_mask
.
Για να βρούμε βάρη $ θ $, θα χρησιμοποιήσουμε ένα εργαλείο βελτιστοποίησης με το όνομα 'Adam' με μέση απώλεια σφάλματος τετραγώνου.
Έχοντας ένα μοντέλο, μπορούμε να το χρησιμοποιήσουμε για να προβλέψουμε τιμές $ Q $ για συγκεκριμένες παρατηρήσεις κατάστασης:
def predict(env, model, observations): action_mask = np.ones((len(observations), env.action_space.n)) return model.predict(x=[observations, action_mask])
Θέλουμε $ Q $ -values για όλες τις ενέργειες, έτσι action_mask
είναι ένας φορέας αυτών.
Για να κάνουμε την πραγματική εκπαίδευση, θα χρησιμοποιήσουμε fit_batch()
:
πώς να φτιάξετε τη δική σας γλώσσα κωδικοποίησης
def fit_batch(env, model, target_model, batch): observations, actions, rewards, next_observations, dones = batch # Predict the Q values of the next states. Passing ones as the action mask. next_q_values = predict(env, target_model, next_observations) # The Q values of terminal states is 0 by definition. next_q_values[dones] = 0.0 # The Q values of each start state is the reward + gamma * the max next state Q value q_values = rewards + DISCOUNT_FACTOR_GAMMA * np.max(next_q_values, axis=1) one_hot_actions = np.array([one_hot_encode(env.action_space.n, action) for action in actions]) history = model.fit( x=[observations, one_hot_actions], y=one_hot_actions * q_values[:, None], batch_size=BATCH_SIZE, verbose=0, ) return history.history['loss'][0]
Η παρτίδα περιέχει BATCH_SIZE
εμπειρίες. next_q_values
είναι $ Q (s, a) $. q_values
είναι $ r + γ space textrm {max} _ {a '} Q (s', a ') $ από την εξίσωση Bellman. Οι ενέργειες που κάναμε είναι μία καυτή κωδικοποίηση και περάστηκαν ως action_mask
στην είσοδο κατά την κλήση model.fit()
. $ y $ είναι ένα κοινό γράμμα για έναν «στόχο» στην εποπτευόμενη μάθηση. Εδώ περνάμε το q_values
. Κάνω q_values[:. None]
για να αυξήσετε τη διάσταση του πίνακα επειδή πρέπει να αντιστοιχεί στη διάσταση του one_hot_actions
πίνακας. Αυτό ονομάζεται slice notation αν θέλετε να διαβάσετε περισσότερα γι 'αυτό.
Επιστρέφουμε την απώλεια για να την αποθηκεύσουμε στο αρχείο καταγραφής TensorBoard και αργότερα οπτικοποιήσουμε. Υπάρχουν πολλά άλλα πράγματα που θα παρακολουθούμε: πόσα βήματα ανά δευτερόλεπτο κάνουμε, συνολική χρήση μνήμης RAM, ποια είναι η μέση επιστροφή επεισοδίων κ.λπ. Ας δούμε αυτές τις γραφικές παραστάσεις.
Για να απεικονίσουμε το αρχείο καταγραφής TensorBoard, πρέπει πρώτα να έχουμε ένα. Ας ξεκινήσουμε λοιπόν την προπόνηση:
python run.py
Αυτό θα εκτυπώσει πρώτα τη σύνοψη του μοντέλου μας. Στη συνέχεια, θα δημιουργήσει έναν κατάλογο καταγραφής με την τρέχουσα ημερομηνία και θα ξεκινήσει την εκπαίδευση. Κάθε 2000 βήματα, μια γραμμή σύνδεσης θα εκτυπώνεται παρόμοια με αυτήν:
episode 10 steps 200/2001 loss 0.3346639 return -200.0 in 1.02s 195.7 steps/s 9.0/15.6 GB RAM
Κάθε 20.000, θα αξιολογούμε το μοντέλο μας σε 10.000 βήματα:
Evaluation 100%|█████████████████████████████████████████████████████████████████████████████████| 10000/10000 [00:07<00:00, 1254.40it/s] episode 677 step 120000 episode_return_avg -136.750 avg_max_q_value -56.004
Μετά από 677 επεισόδια και 120.000 βήματα, η μέση επιστροφή επεισοδίων βελτιώθηκε από -200 σε -136,75! Σίγουρα μαθαίνει. Τι avg_max_q_value
φεύγω ως καλή άσκηση στον αναγνώστη. Αλλά είναι ένα πολύ χρήσιμο στατιστικό στοιχείο που πρέπει να δούμε κατά τη διάρκεια της προπόνησης.
Μετά από 200.000 βήματα, η εκπαίδευσή μας ολοκληρώθηκε. Στην τετραπύρηνη CPU μου, χρειάζονται περίπου 20 λεπτά. Μπορούμε να κοιτάξουμε μέσα στο date-log
κατάλογος, π.χ. 06-07-18-39-log
. Θα υπάρχουν τέσσερα αρχεία μοντέλου με το .h5
επέκταση. Αυτό είναι ένα στιγμιότυπο των βαρών γραφήματος TensorFlow, τα αποθηκεύουμε κάθε 50.000 βήματα για να ρίξουμε μια ματιά στην πολιτική που μάθαμε. Για να το δείτε:
python run.py --model 06-08-18-42-log/06-08-18-42-200000.h5 --view
Για να δείτε τις άλλες πιθανές σημαίες: python run.py --help
.
Τώρα, το αυτοκίνητο κάνει πολύ καλύτερη δουλειά για την επίτευξη του επιθυμητού στόχου. Στο date-log
κατάλογος, υπάρχει επίσης το events.out.*
αρχείο. Αυτό είναι το αρχείο όπου το TensorBoard αποθηκεύει τα δεδομένα του. Γράφουμε σε αυτό χρησιμοποιώντας το απλούστερο TensorBoardLogger
ορίζεται στο loggers.py.
Για να δείτε το αρχείο συμβάντων, πρέπει να εκτελέσουμε τον τοπικό διακομιστή TensorBoard:
tensorboard --logdir=.
--logdir
απλά δείχνει τον κατάλογο στον οποίο υπάρχουν κατάλογοι ημερολογίου ημερομηνίας, στην περίπτωσή μας, αυτός θα είναι ο τρέχων κατάλογος, οπότε .
. Το TensorBoard εκτυπώνει τη διεύθυνση URL στην οποία ακούει. Εάν ανοίξετε http://127.0.0.1:6006 , θα πρέπει να δείτε οκτώ οικόπεδα παρόμοια με αυτά:
train()
κάνει όλη την εκπαίδευση. Αρχικά δημιουργήσαμε το μοντέλο και ξαναπαίξουμε το buffer. Στη συνέχεια, σε έναν βρόχο πολύ παρόμοιο με αυτόν από το see.py
, αλληλεπιδρούμε με το περιβάλλον και αποθηκεύουμε εμπειρίες στο buffer. Αυτό που είναι σημαντικό είναι ότι ακολουθούμε μια άπληστη πολιτική εποχής. Θα μπορούσαμε πάντα να επιλέξουμε την καλύτερη δράση σύμφωνα με τη συνάρτηση $ Q $. Ωστόσο, αυτό αποθαρρύνει την εξερεύνηση, η οποία βλάπτει τη συνολική απόδοση. Έτσι, για να επιβάλουμε την εξερεύνηση με πιθανότητα epsilon, εκτελούμε τυχαίες ενέργειες:
def greedy_action(env, model, observation): next_q_values = predict(env, model, observations=[observation]) return np.argmax(next_q_values) def epsilon_greedy_action(env, model, observation, epsilon): if random.random() Το Epsilon ορίστηκε στο 1%. Μετά από 2000 εμπειρίες, η επανάληψη γεμίζει αρκετά για να ξεκινήσει η προπόνηση. Το κάνουμε καλώντας fit_batch()
με μια τυχαία παρτίδα εμπειριών από το buffer επανάληψης:
batch = replay.sample(BATCH_SIZE) loss = fit_batch(env, model, target_model, batch)
Κάθε 20.000 βήματα, αξιολογούμε και καταγράφουμε τα αποτελέσματα (η αξιολόγηση γίνεται με epsilon = 0
, εντελώς άπληστη πολιτική):
if step >= TRAIN_START and step % EVAL_EVERY == 0: episode_return_avg = evaluate(env, model) q_values = predict(env, model, q_validation_observations) max_q_values = np.max(q_values, axis=1) avg_max_q_value = np.mean(max_q_values) print( 'episode {} ' 'step {} ' 'episode_return_avg {:.3f} ' 'avg_max_q_value {:.3f}'.format( episode, step, episode_return_avg, avg_max_q_value, )) logger.log_scalar('episode_return_avg', episode_return_avg, step) logger.log_scalar('avg_max_q_value', avg_max_q_value, step)
Ολόκληρος ο κώδικας είναι περίπου 300 γραμμές και run.py
περιέχει περίπου 250 από τα πιο σημαντικά.
Κάποιος μπορεί να παρατηρήσει ότι υπάρχουν πολλές υπερπαραμέτρους:
DISCOUNT_FACTOR_GAMMA = 0.99 LEARNING_RATE = 0.001 BATCH_SIZE = 64 TARGET_UPDATE_EVERY = 1000 TRAIN_START = 2000 REPLAY_BUFFER_SIZE = 50000 MAX_STEPS = 200000 LOG_EVERY = 2000 SNAPSHOT_EVERY = 50000 EVAL_EVERY = 20000 EVAL_STEPS = 10000 EVAL_EPSILON = 0 TRAIN_EPSILON = 0.01 Q_VALIDATION_SIZE = 10000
Και δεν είναι όλα αυτά. Υπάρχει επίσης μια αρχιτεκτονική δικτύου - χρησιμοποιήσαμε δύο κρυφά στρώματα με 32 νευρώνες, ενεργοποιήσεις ReLU και βελτιστοποίηση Adam, αλλά υπάρχουν πολλές άλλες επιλογές. Ακόμη και οι μικρές αλλαγές μπορούν να έχουν τεράστιο αντίκτυπο στην εκπαίδευση. Μπορεί να αφιερωθεί πολύς χρόνος συντονίζοντας υπερπαραμέτρους. Σε έναν πρόσφατο διαγωνισμό OpenAI, ένας διαγωνιζόμενος δεύτερης θέσης ανακάλυψα είναι σχεδόν πιθανό διπλό Η βαθμολογία του Rainbow μετά από συντονισμό υπερπαραμέτρων. Φυσικά, πρέπει να θυμόμαστε ότι είναι εύκολο να ταιριάζει. Επί του παρόντος, οι αλγόριθμοι ενίσχυσης αγωνίζονται με τη μεταφορά γνώσεων σε παρόμοια περιβάλλοντα. Το Mountain Car μας δεν γενικεύεται σε όλους τους τύπους βουνών αυτήν τη στιγμή. Μπορείτε πραγματικά να τροποποιήσετε το περιβάλλον OpenAI Gym και να δείτε πόσο μακριά μπορεί να γενικεύσει ο πράκτορας.
ξεκινώντας με το angular js
Μια άλλη άσκηση θα είναι να βρείτε ένα καλύτερο σύνολο υπερπαραμέτρων από το δικό μου. Είναι σίγουρα δυνατό. Ωστόσο, μια προπόνηση δεν θα είναι αρκετή για να κριθεί εάν η αλλαγή σας είναι βελτίωση. Συνήθως υπάρχει μεγάλη διαφορά μεταξύ των προπονήσεων. η διακύμανση είναι μεγάλη. Θα χρειαστείτε πολλές διαδρομές για να διαπιστώσετε ότι κάτι είναι καλύτερο. Εάν θέλετε να διαβάσετε περισσότερα για ένα τόσο σημαντικό θέμα όπως η αναπαραγωγιμότητα, σας ενθαρρύνω να διαβάσετε Βαθιά Ενίσχυση Μάθηση που έχει σημασία . Αντί να συντονίζουμε με το χέρι, μπορούμε να αυτοματοποιήσουμε αυτήν τη διαδικασία σε κάποιο βαθμό - αν θέλουμε να ξοδέψουμε περισσότερη υπολογιστική ισχύ στο πρόβλημα. Μια απλή προσέγγιση είναι να προετοιμάσετε ένα πολλά υποσχόμενο εύρος τιμών για ορισμένους υπερπαραμέτρους και να εκτελέσετε μια αναζήτηση πλέγματος (έλεγχος των συνδυασμών τους), ενώ οι προπονήσεις εκτελούνται παράλληλα. Ο ίδιος ο παραλληλισμός είναι ένα μεγάλο θέμα από μόνο του, καθώς είναι ζωτικής σημασίας για υψηλή απόδοση.
Το Deep $ Q $ -learning αντιπροσωπεύει μια μεγάλη οικογένεια αλγορίθμων εκμάθησης ενίσχυσης που χρησιμοποιούν επαναληπτική αξία. Προσπαθήσαμε να προσεγγίσουμε τη συνάρτηση $ Q $, και το χρησιμοποιούσαμε με απληστία τις περισσότερες φορές. Υπάρχει μια άλλη οικογένεια που χρησιμοποιεί επανάληψη πολιτικής. Δεν επικεντρώνονται στην προσέγγιση της λειτουργίας $ Q $, αλλά στην εύρεση της βέλτιστης πολιτικής $ π ^ * $ απευθείας. Για να δείτε πού ταιριάζει η επανάληψη αξίας στο τοπίο των αλγορίθμων εκμάθησης ενίσχυσης:
Πηγή: https://github.com/NervanaSystems/coach Οι σκέψεις σας θα μπορούσαν να είναι ότι η εκμάθηση βαθιάς ενίσχυσης φαίνεται εύθραυστη. Θα έχεις δίκιο. υπάρχουν πολλά προβλήματα. Μπορείτε να ανατρέξετε Η εκμάθηση βαθιάς ενίσχυσης δεν λειτουργεί ακόμα και Η Ενίσχυση της Μάθησης δεν λειτούργησε ποτέ και το «βαθύ» βοήθησε λίγο .
Αυτό ολοκληρώνει το σεμινάριο. Εφαρμόσαμε το δικό μας βασικό DQN για μαθησιακούς σκοπούς. Πολύ παρόμοιος κωδικός μπορεί να χρησιμοποιηθεί για την επίτευξη καλής απόδοσης σε μερικά από τα παιχνίδια Atari. Σε πρακτικές εφαρμογές, συχνά πραγματοποιούνται δοκιμασμένες εφαρμογές υψηλής απόδοσης, π.χ. Γραμμές βάσης OpenAI . Εάν θέλετε να δείτε ποιες προκλήσεις μπορεί να αντιμετωπίσει κάποιος όταν προσπαθεί να εφαρμόσει τη μάθηση βαθιάς ενίσχυσης σε ένα πιο περίπλοκο περιβάλλον, μπορείτε να διαβάσετε Το NIPS 2017: Εκμάθηση της προσέγγισης . Αν θέλετε να μάθετε περισσότερα σε ένα διασκεδαστικό περιβάλλον ανταγωνισμού, ρίξτε μια ματιά Διαγωνισμοί NIPS 2018 ή crowdai.org .
Εάν πρόκειται να γίνετε μηχανική εκμάθηση ειδικός και θα ήθελα να εμβαθύνει τις γνώσεις σας στην εποπτευόμενη μάθηση, ρίξτε μια ματιά Ανάλυση βίντεο μηχανικής εκμάθησης: Αναγνώριση ψαριών για ένα διασκεδαστικό πείραμα στον εντοπισμό ψαριών.
Σχετίζεται με: Schooling Flappy Bird: Ένα εκπαιδευτικό μάθημα ενίσχυσης Κατανόηση των βασικών
Τι είναι η εκμάθηση ενίσχυσης;
Η εκμάθηση ενίσχυσης είναι μια βιολογικά εμπνευσμένη μέθοδος δοκιμής και σφάλματος για την εκπαίδευση ενός πράκτορα. Ανταμείβουμε τον πράκτορα για καλές ενέργειες για την ενίσχυση της επιθυμητής συμπεριφοράς. Επίσης τιμωρήσαμε κακές ενέργειες, έτσι ώστε να συμβαίνουν λιγότερο συχνά.
Τι είναι το Q στην Q-learning;
Το Q είναι για «ποιότητα». Αναφέρεται στη συνάρτηση action-value που δηλώνεται Qπ (s, a). Επιστρέφει τη συνολική απόδοση από μια δεδομένη κατάσταση, επιλέγοντας ενέργεια α, ακολουθώντας μια συγκεκριμένη πολιτική π. Η συνολική απόδοση είναι το άθροισμα όλων των ανταμοιβών σε ένα επεισόδιο.
Τι είναι η εξίσωση Bellman;
Q (s, a) = r + γ maxa'Q (s ', a'). Προφορικά: Η τιμή Q για μια δεδομένη κατάσταση και μια ενέργεια είναι μια ανταμοιβή r που λαμβάνεται μετά την ανάληψη δράσης a + η υψηλότερη τιμή Q για την κατάσταση που προσγειώνουμε στο s '. Το υψηλότερο με την έννοια ότι επιλέγουμε μια ενέργεια «που οδηγεί στην υψηλότερη συνολική απόδοση από το s».
Ποια είναι η αρχή της βελτιστοποίησης του Bellman;
Αρχή της βελτιστοποίησης: Μια βέλτιστη πολιτική έχει την ιδιότητα ότι ανεξάρτητα από την αρχική κατάσταση και τις ενέργειες, οι υπόλοιπες ενέργειες πρέπει να αποτελούν τη βέλτιστη πολιτική σε σχέση με την κατάσταση που προκύπτει από την αρχική ενέργεια. Χρησιμοποιείται στην Q-learning, αλλά γενικά σε κάθε δυναμική τεχνική προγραμματισμού.
Τι είναι οι παράμετροι και οι υπερ-παράμετροι;
Οι παράμετροι αναφέρονται σε παραμέτρους μοντέλου, οπότε αν χρησιμοποιείτε νευρωνικά δίκτυα, αναφέρεται στα βάρη τους. Συνήθως, έχουμε χιλιάδες ή εκατομμύρια παραμέτρους. Οι υπερπαραμέτρους χρησιμοποιούνται για τον συντονισμό της μαθησιακής διαδικασίας - π.χ., ρυθμός εκμάθησης, αριθμός στρωμάτων, νευρώνες κ.λπ. Συνήθως, έχουμε λιγότερους από εκατό υπερπαραμέτρους.