Πώς λειτουργεί το backpropagation και πώς μπορείτε να χρησιμοποιήσετε το Python για να δημιουργήσετε ένα νευρικό δίκτυο

Τα νευρικά δίκτυα μπορεί να είναι εκφοβιστικά, ειδικά για άτομα που έχουν νέα γνώση στη μηχανική μάθηση. Ωστόσο, αυτό το σεμινάριο θα αναλύσει πώς λειτουργεί ακριβώς ένα νευρωνικό δίκτυο και θα έχετε ένα λειτουργικό ευέλικτο νευρικό δίκτυο μέχρι το τέλος. Ας αρχίσουμε!

Κατανόηση της διαδικασίας

Με περίπου 100 δισεκατομμύρια νευρώνες, ο ανθρώπινος εγκέφαλος επεξεργάζεται δεδομένα με ταχύτητες τόσο γρήγορα όσο 268 mph! Στην ουσία, ένα νευρικό δίκτυο είναι μια συλλογή νευρώνων που συνδέονται με συνάψεις .

Αυτή η συλλογή οργανώνεται σε τρία κύρια επίπεδα: την είσοδο αργότερα, το κρυφό στρώμα και το επίπεδο εξόδου.

Μπορείτε να έχετε πολλά κρυμμένα στρώματα, που είναι όπου ο όρος βαθιά μάθηση μπαίνει στο παιχνίδι. Σε ένα τεχνητό νευρωνικό δίκτυο, υπάρχουν αρκετές είσοδοι, οι οποίες ονομάζονται χαρακτηριστικά , οι οποίες παράγουν τουλάχιστον μία έξοδο - η οποία ονομάζεται ετικέτα .

Στο παραπάνω σχέδιο, οι κύκλοι αντιπροσωπεύουν νευρώνες ενώ οι γραμμές αντιπροσωπεύουν συνάψεις.

Ο ρόλος της σύναψης είναι να λαμβάνει και να πολλαπλασιάζει τις εισόδους και τα βάρη .

Μπορείτε να σκεφτείτε τα βάρη ως τη «δύναμη» της σύνδεσης μεταξύ των νευρώνων. Τα βάρη καθορίζουν κυρίως την έξοδο ενός νευρικού δικτύου. Ωστόσο, είναι εξαιρετικά ευέλικτα. Μετά, εφαρμόζεται μια λειτουργία ενεργοποίησης για την επιστροφή μιας εξόδου.

Ακολουθεί μια σύντομη επισκόπηση του τρόπου λειτουργίας ενός απλού νευρικού δικτύου feedforward:

  1. Λήψη εισόδων ως πίνακας (2D πίνακας αριθμών)
  2. Πολλαπλασιάστε τις εισόδους με ένα σύνολο βαρών.
  3. Εφαρμόστε μια λειτουργία ενεργοποίησης
  4. Επιστρέψτε μια έξοδο
  5. Το σφάλμα υπολογίζεται λαμβάνοντας τη διαφορά μεταξύ της επιθυμητής εξόδου από το μοντέλο και της προβλεπόμενης εξόδου. Αυτή είναι μια διαδικασία που ονομάζεται κλίση κατάβασης, την οποία μπορούμε να χρησιμοποιήσουμε για να αλλάξουμε τα βάρη.
  6. Τα βάρη στη συνέχεια προσαρμόζονται, σύμφωνα με το σφάλμα που βρέθηκε στο βήμα 5.
  7. Για να εκπαιδεύσετε, αυτή η διαδικασία επαναλαμβάνεται 1000+ φορές. Όσο περισσότερο εκπαιδεύονται τα δεδομένα, τόσο πιο ακριβείς θα είναι οι εξόδους μας.

Στον πυρήνα τους, τα νευρικά δίκτυα είναι απλά.

Απλώς εκτελούν πολλαπλασιασμό μήτρας με την είσοδο και τα βάρη και εφαρμόζουν μια λειτουργία ενεργοποίησης.

Όταν τα βάρη ρυθμίζονται μέσω της λειτουργίας διαβάθμισης της απώλειας, το δίκτυο προσαρμόζεται στις αλλαγές για να παράγει ακριβέστερες εξόδους.

Το νευρικό μας δίκτυο θα διαμορφώσει ένα μόνο κρυφό επίπεδο με τρεις εισόδους και μία έξοδο. Στο δίκτυο, θα προβλέψουμε τη βαθμολογία των εξετάσεών μας με βάση τις πληροφορίες για το πόσες ώρες μελετήσαμε και πόσες ώρες κοιμήσαμε την προηγούμενη μέρα. Η έξοδος είναι η «βαθμολογία δοκιμής».

Ακολουθούν τα δείγματα δεδομένων για το τι θα εκπαιδεύσουμε το Νευρωνικό μας Δίκτυο:

Όπως ίσως έχετε παρατηρήσει, η ?περίπτωση αυτή αντιπροσωπεύει αυτό που θέλουμε να προβλέψουμε το νευρικό μας δίκτυο. Σε αυτήν την περίπτωση, προβλέπουμε τη βαθμολογία δοκιμών κάποιου που μελετούσε για τέσσερις ώρες και κοιμήθηκε για οκτώ ώρες με βάση την προηγούμενη απόδοσή του.

Προώθηση πολλαπλασιασμού

Ας αρχίσουμε να κωδικοποιούμε αυτό το κακό αγόρι! Ανοίξτε ένα νέο αρχείο python. Θα θελήσετε να εισαγάγετε numpyκαθώς θα μας βοηθήσει με ορισμένους υπολογισμούς.

Αρχικά, ας εισαγάγουμε τα δεδομένα μας ως συστοιχίες numpy np.array. Θα θέλαμε επίσης να ομαλοποιήσουμε τις μονάδες μας καθώς οι εισροές μας είναι σε ώρες, αλλά η παραγωγή μας είναι μια βαθμολογία δοκιμής από 0-100. Επομένως, πρέπει να κλιμακώσουμε τα δεδομένα μας διαιρώντας με τη μέγιστη τιμή για κάθε μεταβλητή.

Στη συνέχεια, ας καθορίσουμε έναν πύθωνα classκαι να γράψουμε μια initσυνάρτηση όπου θα καθορίσουμε τις παραμέτρους μας, όπως τα επίπεδα εισόδου, κρυφής και εξόδου.

Είναι καιρός για τον πρώτο μας υπολογισμό. Θυμηθείτε ότι οι συνάψεις μας εκτελούν ένα προϊόν κουκκίδων ή πολλαπλασιασμό μήτρας της εισόδου και του βάρους. Σημειώστε ότι τα βάρη δημιουργούνται τυχαία και μεταξύ 0 και 1.

Οι υπολογισμοί πίσω από το δίκτυό μας

Στο σύνολο δεδομένων, τα δεδομένα εισόδου μας X, είναι μια μήτρα 3x2. Τα δεδομένα εξόδου μας y, είναι μήτρα 3x1. Κάθε στοιχείο στη μήτρα Xπρέπει να πολλαπλασιαστεί με ένα αντίστοιχο βάρος και στη συνέχεια να προστεθεί μαζί με όλα τα άλλα αποτελέσματα για κάθε νευρώνα στο κρυφό στρώμα. Δείτε πώς το πρώτο στοιχείο δεδομένων εισαγωγής (2 ώρες μελέτης και 9 ώρες ύπνου) θα υπολογίσει μια έξοδο στο δίκτυο:

Αυτή η εικόνα αναλύει τι κάνει το νευρωνικό μας δίκτυο για να παράγει έξοδο. Πρώτα, τα προϊόντα των τυχαίων παραγόμενων βαρών (.2, .6, .1, .8, .3, .7) σε κάθε σύναψη και οι αντίστοιχες εισόδους αθροίζονται για να φτάσουν ως οι πρώτες τιμές του κρυφού επιπέδου. Αυτά τα αθροίσματα είναι σε μικρότερη γραμματοσειρά, καθώς δεν είναι οι τελικές τιμές για το κρυφό επίπεδο.

Για να λάβουμε την τελική τιμή για το κρυφό επίπεδο, πρέπει να εφαρμόσουμε τη λειτουργία ενεργοποίησης.

Ο ρόλος μιας λειτουργίας ενεργοποίησης είναι να εισαγάγει τη μη γραμμικότητα. Ένα πλεονέκτημα αυτού είναι ότι η έξοδος χαρτογραφείται από εύρος 0 και 1, καθιστώντας ευκολότερη την αλλαγή βαρών στο μέλλον.

Υπάρχουν πολλές λειτουργίες ενεργοποίησης εκεί έξω, για πολλές διαφορετικές περιπτώσεις χρήσης. Σε αυτό το παράδειγμα, θα παραμείνουμε σε ένα από τα πιο δημοφιλή - τη λειτουργία σιγμοειδούς.

Τώρα, πρέπει να χρησιμοποιήσουμε ξανά τον πολλαπλασιασμό μήτρας, με ένα άλλο σύνολο τυχαίων βαρών, για να υπολογίσουμε την τιμή του επιπέδου εξόδου.

Τέλος, για να ομαλοποιήσετε την έξοδο, απλώς εφαρμόζουμε ξανά τη λειτουργία ενεργοποίησης.

Και, πήγαινε! Θεωρητικά, με αυτά τα βάρη, το νευρωνικό δίκτυο θα υπολογίσει .85ως βαθμολογία δοκιμής μας! Ωστόσο, ο στόχος μας ήταν .92. Το αποτέλεσμα δεν ήταν κακό, απλά δεν είναι το καλύτερο που μπορεί να είναι. Είχαμε λίγο τυχεροί όταν επέλεξα τα τυχαία βάρη για αυτό το παράδειγμα.

Πώς εκπαιδεύουμε το μοντέλο μας για μάθηση; Λοιπόν, θα το μάθουμε πολύ σύντομα. Προς το παρόν, ας μετρήσουμε την κωδικοποίηση του δικτύου μας.

Εάν εξακολουθείτε να είστε μπερδεμένοι, σας προτείνω να δείτε αυτό το ενημερωτικό βίντεο που εξηγεί τη δομή ενός νευρικού δικτύου με το ίδιο παράδειγμα.

Εφαρμογή των υπολογισμών

Τώρα, ας δημιουργήσουμε τα βάρη μας χρησιμοποιώντας τυχαία np.random.randn(). Θυμηθείτε, θα χρειαστούμε δύο ομάδες βαρών. Ένα για μετάβαση από την είσοδο στο κρυφό επίπεδο και το άλλο για μετάβαση από το επίπεδο κρυφό στην έξοδο.

Μόλις ρυθμίσουμε όλες τις μεταβλητές, είμαστε έτοιμοι να γράψουμε τη forwardλειτουργία διάδοσης. Ας περάσουμε στην είσοδο μας X, και σε αυτό το παράδειγμα, μπορούμε να χρησιμοποιήσουμε τη μεταβλητή zγια να προσομοιώσουμε τη δραστηριότητα μεταξύ των επιπέδων εισόδου και εξόδου.

Όπως εξηγήθηκε, πρέπει να πάρουμε ένα προϊόν κουκκίδων από τις εισόδους και τα βάρη, να εφαρμόσουμε μια συνάρτηση ενεργοποίησης, να πάρουμε ένα άλλο προϊόν κουκκίδων του κρυμμένου στρώματος και το δεύτερο σύνολο βαρών και τέλος να εφαρμόσουμε μια τελική συνάρτηση ενεργοποίησης για να λάβουμε την έξοδο μας:

Τέλος, πρέπει να ορίσουμε τη σιγμοειδή συνάρτηση:

Και, το έχουμε! Ένα (μη εκπαιδευμένο) νευρωνικό δίκτυο ικανό να παράγει έξοδο.

Όπως ίσως έχετε παρατηρήσει, πρέπει να εκπαιδεύσουμε το δίκτυό μας για να υπολογίσουμε πιο ακριβή αποτελέσματα.

Backpropagation - η «εκμάθηση» του δικτύου μας

Δεδομένου ότι έχουμε ένα τυχαίο σύνολο βαρών, πρέπει να τα αλλάξουμε για να κάνουμε τις εισόδους μας ίσες με τις αντίστοιχες εξόδους από το σύνολο δεδομένων μας. Αυτό γίνεται μέσω μιας μεθόδου που ονομάζεται backpropagation.

Το Backpropagation λειτουργεί χρησιμοποιώντας μια λειτουργία απώλειας για να υπολογίσει πόσο μακριά ήταν το δίκτυο από την έξοδο-στόχο.

Υπολογισμός σφάλματος

Ένας τρόπος αναπαράστασης της λειτουργίας απώλειας είναι με τη χρήση της συνάρτησης μέσου αθροίσματος τετραγώνου απώλειας :

Σε αυτήν τη λειτουργία, oείναι η προβλεπόμενη έξοδος yμας και είναι η πραγματική μας έξοδος. Τώρα που έχουμε τη λειτουργία απώλειας, στόχος μας είναι να το φτάσουμε όσο πιο κοντά μπορούμε στο 0. Αυτό σημαίνει ότι θα πρέπει να έχουμε σχεδόν καθόλου απώλεια. Καθώς εκπαιδεύουμε το δίκτυό μας, το μόνο που κάνουμε είναι να ελαχιστοποιήσουμε την απώλεια.

Για να καταλάβουμε ποια κατεύθυνση θα αλλάξουμε τα βάρη, πρέπει να βρούμε το ρυθμό αλλαγής της απώλειας σε σχέση με τα βάρη μας. Με άλλα λόγια, πρέπει να χρησιμοποιήσουμε το παράγωγο της συνάρτησης απώλειας για να καταλάβουμε πώς τα βάρη επηρεάζουν την είσοδο.

Σε αυτήν την περίπτωση, θα χρησιμοποιήσουμε ένα μερικό παράγωγο για να μας επιτρέψει να λάβουμε υπόψη μια άλλη μεταβλητή.

Αυτή η μέθοδος είναι γνωστή ως κλίση κατάβασης . Γνωρίζοντας με ποιο τρόπο να αλλάξουμε τα βάρη μας, τα αποτελέσματά μας μπορούν να γίνουν πιο ακριβή.

Δείτε πώς θα υπολογίσουμε τη σταδιακή αλλαγή στα βάρη μας:

  1. Βρείτε το περιθώριο σφάλματος του επιπέδου εξόδου (o) λαμβάνοντας τη διαφορά της προβλεπόμενης εξόδου και της πραγματικής εξόδου (y)
  2. Εφαρμόστε το παράγωγο της λειτουργίας σιγμοειδούς ενεργοποίησης στο σφάλμα επιπέδου εξόδου. Αυτό το αποτέλεσμα ονομάζεται άθροισμα εξόδου δέλτα .
  3. Χρησιμοποιήστε το άθροισμα εξόδου δέλτα του σφάλματος επιπέδου εξόδου για να υπολογίσετε πόσο συνέβαλε το στρώμα z² (κρυφό) στο σφάλμα εξόδου εκτελώντας ένα προϊόν κουκκίδας με τη δεύτερη μήτρα βάρους μας. Μπορούμε να το ονομάσουμε αυτό το σφάλμα z².
  4. Υπολογίστε το άθροισμα εξόδου δέλτα για το στρώμα z² εφαρμόζοντας το παράγωγο της λειτουργίας σιγμοειδούς ενεργοποίησης (όπως ακριβώς το βήμα 2).
  5. Προσαρμόστε τα βάρη για το πρώτο επίπεδο εκτελώντας ένα προϊόν κουκκίδας του επιπέδου εισαγωγής με το κρυφό άθροισμα εξόδου () . Για το δεύτερο βάρος, εκτελέστε ένα προϊόν κουκκίδας του κρυμμένου στρώματος (z²) και το άθροισμα εξόδου (o) delta εξόδου .

Ο υπολογισμός του αθροίσματος εξόδου δέλτα και, στη συνέχεια, η εφαρμογή του παραγώγου της σιγμοειδούς συνάρτησης είναι πολύ σημαντικοί για την αναπαράσταση. Το παράγωγο του σιγμοειδούς, επίσης γνωστό ως σιγμοειδές prime , θα μας δώσει το ρυθμό μεταβολής ή κλίση της συνάρτησης ενεργοποίησης στο άθροισμα εξόδου.

Ας συνεχίσουμε να κωδικοποιούμε την Neural_Networkτάξη μας προσθέτοντας μια συνάρτηση sigmoidPrime (παράγωγο του sigmoid):

Στη συνέχεια, θα θέλαμε να δημιουργήσουμε τη backwardλειτουργία διάδοσης που κάνει ό, τι ορίζεται στα τέσσερα παραπάνω βήματα:

Μπορούμε τώρα να καθορίσουμε την έξοδο μας μέσω της έναρξης της διάδοσης και να ενεργοποιήσουμε τη λειτουργία προς τα πίσω, καλώντας τη στη trainλειτουργία:

Για να εκτελέσετε το δίκτυο, το μόνο που πρέπει να κάνουμε είναι να εκτελέσουμε τη trainλειτουργία. Φυσικά, θα θέλαμε να το κάνουμε πολλές φορές, ή ίσως χιλιάδες φορές. Έτσι, θα χρησιμοποιήσουμε έναν forβρόχο.

Εδώ είναι οι πλήρεις 60 σειρές εκπληκτικότητας:

Ορίστε! Ένα πλήρες νευρωνικό δίκτυο που μπορεί να μάθει από εισόδους και εξόδους.

Ενώ σκεφτήκαμε τις εισροές μας ως ώρες μελέτης και ύπνου, και τα αποτελέσματά μας ως βαθμολογίες δοκιμής, μη διστάσετε να τα αλλάξετε σε ό, τι θέλετε και να παρατηρήσετε πώς προσαρμόζεται το δίκτυο!

Σε τελική ανάλυση, όλα τα δίκτυα που βλέπουν είναι οι αριθμοί. Οι υπολογισμοί που κάναμε, τόσο περίπλοκοι όσο φαινόταν, όλοι έπαιξαν μεγάλο ρόλο στο μαθησιακό μας μοντέλο.

Εάν θέλετε να προβλέψετε μια έξοδο βάσει των εκπαιδευμένων δεδομένων μας, όπως η πρόβλεψη της βαθμολογίας δοκιμής εάν μελετήσατε για τέσσερις ώρες και κοιμήσατε για οκτώ, δείτε το πλήρες σεμινάριο εδώ.

Επίδειξη και πηγή

βιβλιογραφικές αναφορές

Στίβεν Μίλερ

Εργαστήρια Welch

Kabir Shah

Αυτό το σεμινάριο δημοσιεύτηκε αρχικά στο Enlight, έναν ιστότοπο που φιλοξενεί μια ποικιλία από σεμινάρια και έργα για να μάθετε με την κατασκευή! Δείτε το για περισσότερα έργα όπως αυτά :)