Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Πριν από εσάς πάλι είναι το καθήκον της ανίχνευσης αντικειμένων. Προτεραιότητα είναι η ταχύτητα λειτουργίας με αποδεκτή ακρίβεια. Παίρνετε την αρχιτεκτονική YOLOv3 και την εκπαιδεύετε περαιτέρω. Η ακρίβεια (mAp75) είναι μεγαλύτερη από 0.95. Αλλά το ποσοστό εκτέλεσης είναι ακόμα χαμηλό. Σκατά.

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

Εισαγωγή

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

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

Μια ματιά στη βιολογία

Μου αρέσει όταν το Deep Learning εξετάζει ιδέες που προέρχονται από τη βιολογία. Μπορούν να εμπιστευτούν, όπως και την εξέλιξη (το γνωρίζατε ότι το ReLU μοιάζει πολύ με λειτουργία της ενεργοποίησης των νευρώνων στον εγκέφαλο?)

Η διαδικασία του Κλαδέματος Μοντέλου είναι επίσης κοντά στη βιολογία. Η απόκριση του δικτύου εδώ μπορεί να συγκριθεί με την πλαστικότητα του εγκεφάλου. Υπάρχουν μερικά ενδιαφέροντα παραδείγματα στο βιβλίο. Νόρμαν Ντόιτζ:

  1. Ο εγκέφαλος μιας γυναίκας που γεννήθηκε μόνο με το ένα μισό έχει επαναπρογραμματιστεί για να εκτελέσει τις λειτουργίες του μισού που λείπει.
  2. Ο τύπος πυροβόλησε το τμήμα του εγκεφάλου του που είναι υπεύθυνο για την όραση. Με την πάροδο του χρόνου, άλλα μέρη του εγκεφάλου ανέλαβαν αυτές τις λειτουργίες. (δεν προσπαθούμε να επαναλάβουμε)

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

Αγαπάτε το Transfer Learning ή μαθαίνετε από το μηδέν;

Επιλογή νούμερο ένα. Χρησιμοποιείτε το Transfer Learning στο Yolov3. Retina, Mask-RCNN ή U-Net. Αλλά τις περισσότερες φορές δεν χρειάζεται να αναγνωρίσουμε 80 κατηγορίες αντικειμένων όπως στο COCO. Στην πρακτική μου, όλα περιορίζονται στους βαθμούς 1-2. Θα μπορούσε κανείς να υποθέσει ότι η αρχιτεκτονική για 80 τάξεις είναι περιττή εδώ. Αυτό υποδηλώνει ότι η αρχιτεκτονική πρέπει να γίνει μικρότερη. Επιπλέον, θα ήθελα να το κάνω αυτό χωρίς να χάσω τα ήδη προπονημένα βάρη.

Επιλογή νούμερο δύο. Ίσως έχετε πολλά δεδομένα και υπολογιστικούς πόρους ή απλά χρειάζεστε μια εξαιρετικά προσαρμοσμένη αρχιτεκτονική. Δεν έχει σημασία. Αλλά μαθαίνετε το δίκτυο από την αρχή. Η συνήθης διαδικασία είναι να κοιτάξετε τη δομή δεδομένων, να επιλέξετε μια αρχιτεκτονική που είναι ΥΠΕΡΒΟΛΙΚΗ σε ισχύ και να σπρώξετε την εγκατάλειψη από την επανεκπαίδευση. Είδα 0.6 εγκαταλείψεις, Karl.

Και στις δύο περιπτώσεις, το δίκτυο μπορεί να μειωθεί. Με κίνητρο. Τώρα ας πάμε να καταλάβουμε τι είδους είναι το κλάδεμα περιτομής

Γενικός αλγόριθμος

Αποφασίσαμε ότι μπορούσαμε να αφαιρέσουμε τα πακέτα. Φαίνεται αρκετά απλό:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Η κατάργηση οποιασδήποτε συνέλιξης είναι αγχωτική για το δίκτυο, η οποία συνήθως οδηγεί σε κάποια αύξηση του σφάλματος. Από τη μία πλευρά, αυτή η αύξηση του σφάλματος είναι ένας δείκτης του πόσο σωστά αφαιρούμε τις περιελίξεις (για παράδειγμα, μια μεγάλη αύξηση δείχνει ότι κάνουμε κάτι λάθος). Αλλά μια μικρή αύξηση είναι αρκετά αποδεκτή και συχνά εξαλείφεται από την επόμενη ελαφριά πρόσθετη προπόνηση με ένα μικρό LR. Προσθέστε ένα επιπλέον βήμα εκπαίδευσης:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Τώρα πρέπει να καταλάβουμε πότε θέλουμε να σταματήσουμε τον βρόχο εκμάθησης<->Pruning. Μπορεί να υπάρχουν εξωτικές επιλογές εδώ όταν πρέπει να μειώσουμε το δίκτυο σε ένα συγκεκριμένο μέγεθος και ταχύτητα (για παράδειγμα, για κινητές συσκευές). Ωστόσο, η πιο συνηθισμένη επιλογή είναι να συνεχίσετε τον κύκλο έως ότου το σφάλμα γίνει μεγαλύτερο από το αποδεκτό. Προσθέστε μια προϋπόθεση:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

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

Αναζήτηση για διαγραμμένα πακέτα

Πρέπει να αφαιρέσουμε κάποιες περιελίξεις. Το να βιαστούμε μπροστά και να «πυροβολήσεις» οποιονδήποτε είναι κακή ιδέα, αν και θα λειτουργήσει. Αλλά επειδή έχετε ένα κεφάλι, μπορείτε να σκεφτείτε και να προσπαθήσετε να επιλέξετε "αδύναμες" περιελίξεις για αφαίρεση. Υπάρχουν πολλές επιλογές:

  1. Το μικρότερο L1-measure ή low_magnitude_pruning. Η ιδέα ότι οι περιελίξεις με μικρά βάρη συμβάλλουν ελάχιστα στην τελική απόφαση
  2. Το μικρότερο L1-μέτρηση λαμβάνοντας υπόψη τη μέση και τυπική απόκλιση. Συμπληρώνουμε με μια αξιολόγηση της φύσης της διανομής.
  3. Απόκρυψη περιελίξεων και εξαίρεση εκείνων που επηρεάζουν λιγότερο την τελική ακρίβεια. Ακριβέστερος προσδιορισμός ασήμαντων συνελίξεων, αλλά πολύ χρονοβόρος και πόρος.
  4. Άλλα

Κάθε μία από τις επιλογές έχει το δικαίωμα στη ζωή και τα δικά της χαρακτηριστικά υλοποίησης. Εδώ εξετάζουμε την επιλογή με το μικρότερο L1-μέτρο

Μη αυτόματη διαδικασία για το YOLOv3

Η αρχική αρχιτεκτονική περιέχει υπολειμματικά μπλοκ. Αλλά όσο cool και να είναι για βαθιά δίκτυα, θα μας εμποδίσουν κάπως. Η δυσκολία είναι ότι δεν μπορείτε να διαγράψετε συμφωνίες με διαφορετικά ευρετήρια σε αυτά τα επίπεδα:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Επομένως, ας επιλέξουμε επίπεδα από τα οποία μπορούμε ελεύθερα να διαγράψουμε συμφωνίες:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Τώρα ας φτιάξουμε έναν κύκλο εργασίας:

  1. Μεταφόρτωση ενεργοποιήσεων
  2. Να υπολογίσετε πόσο να κόψετε
  3. Κόφτο
  4. Εκμάθηση 10 εποχών με LR=1e-4
  5. Δοκιμές

Η εκφόρτωση των συνελίξεων είναι χρήσιμη για να εκτιμήσουμε ποιο τμήμα μπορούμε να αφαιρέσουμε σε ένα συγκεκριμένο βήμα. Παραδείγματα εκφόρτωσης:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

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

Η όλη διαδικασία ολοκληρώθηκε σε 4 βήματα (αριθμοί εδώ και παντού για το RTX 2060 Super):

Βήμα mAp75 Αριθμός παραμέτρων, εκατομμύρια Μέγεθος δικτύου, mb από το αρχικό, % Χρόνος εκτέλεσης, ms Συνθήκη περιτομής
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% όλων
2 0.9625 50 197 83 168 5% όλων
3 0.9633 39 155 64 155 15% για στρώσεις με 400+ περιελίξεις
4 0.9555 31 124 51 146 10% για στρώσεις με 100+ περιελίξεις

Ένα θετικό αποτέλεσμα προστέθηκε στο βήμα 2 - το μέγεθος παρτίδας 4 χωρούσε στη μνήμη, το οποίο επιτάχυνε σημαντικά τη διαδικασία της πρόσθετης εκπαίδευσης.
Στο βήμα 4, η διαδικασία σταμάτησε επειδή ακόμη και η μακροχρόνια πρόσθετη εκπαίδευση δεν ανέβασε το mAp75 σε παλιές τιμές.
Ως αποτέλεσμα, καταφέραμε να επιταχύνουμε το συμπέρασμα κατά 15%, μειώστε το μέγεθος κατά 35% και να μην χάσει ακριβώς.

Αυτοματοποίηση για απλούστερες αρχιτεκτονικές

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

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

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

Εάν είναι απαραίτητο, μπορείτε να αλλάξετε τις παραμέτρους διαμόρφωσης:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Επιπλέον, εφαρμόζεται ένας περιορισμός που βασίζεται στην τυπική απόκλιση. Ο στόχος είναι να περιοριστεί το τμήμα που αφαιρείται, εξαιρουμένων των συνελίξεων με ήδη «επαρκή» μέτρα L1:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Έτσι, σας επιτρέπουμε να αφαιρέσετε μόνο αδύναμες συνελίξεις από διανομές παρόμοιες με τη δεξιά και να μην επηρεάσετε την κατάργηση από διανομές παρόμοιες με την αριστερή:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Όταν η κατανομή προσεγγίζει την κανονική, ο συντελεστής pruning_standart_deviation_part μπορεί να επιλεγεί από:

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα
Προτείνω μια υπόθεση 2 σίγμα. Ή μπορείτε να αγνοήσετε αυτό το χαρακτηριστικό, αφήνοντας την τιμή < 1.0.

Η έξοδος είναι ένα γράφημα του μεγέθους του δικτύου, της απώλειας και του χρόνου εκτέλεσης δικτύου για ολόκληρη τη δοκιμή, κανονικοποιημένο σε 1.0. Για παράδειγμα, εδώ το μέγεθος του δικτύου μειώθηκε σχεδόν 2 φορές χωρίς απώλεια ποιότητας (μικρό συνελικτικό δίκτυο με βάρη 100k):

Τεχνική Jedi για τη μείωση των συνελικτικών δικτύων - κλάδεμα

Η ταχύτητα λειτουργίας υπόκειται σε κανονικές διακυμάνσεις και παραμένει ουσιαστικά αμετάβλητη. Υπάρχει μια εξήγηση για αυτό:

  1. Ο αριθμός των περιελίξεων αλλάζει από βολικές (32, 64, 128) σε μη πιο βολικές για κάρτες βίντεο - 27, 51 κ.λπ. Μπορεί να κάνω λάθος εδώ, αλλά πιθανότατα έχει αποτέλεσμα.
  2. Η αρχιτεκτονική δεν είναι ευρεία, αλλά συνεπής. Μειώνοντας το πλάτος, δεν επηρεάζουμε το βάθος. Έτσι, μειώνουμε το φορτίο, αλλά δεν αλλάζουμε την ταχύτητα.

Επομένως, η βελτίωση εκφράστηκε σε μείωση του φορτίου CUDA κατά τη διάρκεια της εκτέλεσης κατά 20-30%, αλλά όχι σε μείωση του χρόνου εκτέλεσης

Αποτελέσματα της

Ας αναλογιστούμε. Εξετάσαμε 2 επιλογές για κλάδεμα - για το YOLOv3 (όταν πρέπει να δουλέψετε με τα χέρια σας) και για δίκτυα με απλούστερες αρχιτεκτονικές. Μπορεί να φανεί ότι και στις δύο περιπτώσεις είναι δυνατό να επιτευχθεί μείωση μεγέθους δικτύου και επιτάχυνση χωρίς απώλεια ακρίβειας. Αποτελέσματα:

  • Μείωση του μεγέθους
  • Τρέξιμο επιτάχυνσης
  • Μείωση φορτίου CUDA
  • Ως αποτέλεσμα, φιλικότητα προς το περιβάλλον (Βελτιστοποιούμε τη μελλοντική χρήση των υπολογιστικών πόρων. Κάπου κάποιος είναι ευχαριστημένος Γκρέτα Τύνμπεργκ)

Παράρτημα

  • Μετά το βήμα κλαδέματος, μπορείτε να προσθέσετε κβαντισμό (για παράδειγμα, με το TensorRT)
  • Το Tensorflow παρέχει δυνατότητες για χαμηλού_μεγέθους_κλάδεμα. Εργα.
  • αποθήκη Θέλω να εξελιχθώ και θα χαρώ να βοηθήσω

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο