make all
./scripts/run_all_tests.sh
time ./bin/main 'data/siftsmall/siftsmall_base.fvecs' 'data/siftsmall/siftsmall_query.fvecs' 'data/siftsmall/siftsmall_groundtruth.ivecs' 100 1.0 120 14 0
make clean
VIA = Vamana Indexing Algorithm
Τα δεδομένα που χρησιμοποιούνται για τον Αλγόριθμο Vamana Indexing. Είναι σετ διανυσμάτων 128 διαστάσεων (με αριθμούς κινητής υποδιαστολής (float)). Στον κώδικά μας αξιοποιήσαμε το σετ δεδομένων ANN_SIFT10K
. το οποίο περιέχει:
shiftsmall_base.fvecs
: 10.000 base vectors διάστασης 128. Κάθε vector θα αντιστοιχεί σε ένα κόμβο του γράφου Vamana, και περιέχει 128 floats.shiftsmall_query.fvecs
: 100 query vectors διάστασης 128. Οι "search" vectors μας. O VIA θα υπολογίσει τους πλησιέστερους γείτονες αυτών των vector.shiftsmall_groundtruth.ivecs
: Αυτό το αρχείο, για κάθε query vector, περιέχει 100 ακεραιες τιμές που αντιπροσωπεύουν τους identifiers (start 0) των base vectors που είναι οι εγγύτεροι γείτονες τους.shiftsmall_learn.fvecs
: 25,000 learn vectors διάστασης 128. Σε αντίθεση με τα query vectors, τα learn vectors χρησιμοποιούνται αποκλειστικά για το optimization phase της ανάπτυξης του project στην παραμετροποιήση και βελτιστοποίηση των συναρτήσεων RobustPrune()
και GreedySearch()
.Στο πρώτο μέρος του Project κληθήκαμε να υλοποιήσουμε τον Αλγόριθμο Vamana Indexing, o oποίος λειτουργεί ως μία Προσεγγιστική Λυση του Προβλήματος της Εύρεσης των Κ-Εγγύτερων Γειτόνων, μέσω της χρήσης κατευθυνόμενου γράφου για την αναπαράσταση και επεξεργασία των δεδομένων. Η υλοποίησή μας στηρίχθηκε πάνω στο αρθρο του 2019, DiskANN:Fast Accurate Billion-point Nearest Neighbour Search on a Single Node Search. Πιο συγκεκριμένα, μας ζητήθηκε να υλοποιήσουμε τα εξής:
VamanaIndex()
GreedySearch()
RobustPrune()
Για την εξέταση της λειτουργικότητας του VIA ήταν αναγκάιο να δημιουργήσουμε συμπληρωματικές κλάσεις και μεθόδους για:
Στην Ανάπτυξη του Project αξιοποιήθηκε το εργαλείο Issues του github για την επικοινωνία και τον συγχρονισμό των διεργασιών που είχε αναλάβει να διεκπεραιώσει το κάθε μέλος της ομάδας.
Καθόλη την διάρκεια της ανάπτυξης του Project υπήρξε συνεχείς επικοινωνία των μελών τόσο μέσω των εργαλείων του github όσο και με προγραμματισμένα online calls.
.fvecs
.CreateVamanaIndex()
.GreedySearch()
.ReadGroundtruth()
, για την ανάγνωση των ακέραιων δεδομένων του αρχείου shiftsmall_groundtruth.ivecs
.CalculateRecallEvaluation()
, για την εξέταση της εγγυρότητας των αποτέλεσμάτων του ANN Vamana Index, βάσει των τιμών του shiftsmall_groundtruth.ivecs
.GreedySearch()
.RobustPrune()
.FindMediod()
, για την εύρεση του μέσου κόμβου του γράφου.CreateVamanaIndex()
.ReadVectorFile()
και SaveVector()
, για την ανάγνωση και αποθήκευση των δεδομένων των διανυσμάτων των αρχείων .fvecs
.ReadVectorFile()
και SaveVector()
.CreateVamanaIndex()
.README.md
.Η υλοποίηση των συναρτήσεων VamanaIndex()
, GreedySearch()
, RobustPrune()
και Recall()
, έγινε σύμφωνα με τους ψευδοκώδικες που παρουσιάζονται στο άρθρο, και φάινονται παρακάτω:
Οι βασικότερες κλάσεις και μέθοδοι που υλοποιήθηκαν συμπληρωματικά αυτών που ζητήθηκαν στην εκφώνηση είναι:
FindMedoid()
, για την εύρεση του ενδιάμεσου στοιχείου του συνόλου G, που παράγεται μέσα στην Vamana.CalculateRecallEvaluation()
, για την εξέταση της εγγυρότητας των αποτέλεσμάτων του ANN Vamana Index, βάσει των τιμών του shiftsmall_groundtruth.ivecs
.DataVector
, για την αποθήκευση των δεδομένων των αρχείων .fvecs
.Graph
και GraphNode
. Δομές τι οποίες αξιοποιεί ο VIA.ReadVectorFile()
και SaveVector()
, για την ανάγνωση και αποθήκευση των δεδομένων.EuclidianDistance()
και ManhattanDistance()
, για τον υπολογισμό της απόστασης μεταξύ των διανυσμάτων.Για την εκτέλεση του κώδικα πληκτρολογούμε τις εντολές:
make all
time ./bin/main 'data/siftsmall/siftsmall_base.fvecs' 'data/siftsmall/siftsmall_query.fvecs' 'data/siftsmall/siftsmall_groundtruth.ivecs' 100 1.0 120 14 0
Οι τιμές στο τέλος αντιστοιχούν στις παραμέτρους:
GreedySearch()
Η εκτέλεση του Vamana Indexing Algorithm γίνεται σε τρεις φάσεις:
Στο Initialization phase, γίνεται η ανάγνωση και η αποθήκευση των δεδομένων μας από τις συναρτήσεις:
ReadVectorFile()
ReadgroundΤruth()
Η οποίες διαβάζουν από τα αρχεία siftsmall_base.fvecs
, siftsmall_query.fvecs
και siftsmall_groundtruth.ivecs
τα δεδομένα μας.
Σε δεύτερη φάση, ξεκινά η δημιουργία του τυχάιου γράφου από την Vamana()
, η οποία αναθέτει τα δεδομένα του siftsmall_base.fvecs
σε αντικείμενα της κλάσης node
, και ύστερα δημιουργεί τυχαίες εξερχόμενες ακμές από καθένα από αυτούς (με όριο τον αριθμό R που ορίζουμε από την γραμμή εντολών). Ο γράφος αναπαριστάται με λίστα γειτνίασης.
Ακολουθούν οι διαδικασίες GreedySearch()
και σε συνδυασμό με την RobustPrune()
, εκτελούν την βασική λειτουργία του Vamana Indexing Algorithm όπου είναι η αναζήτηση των K εγγύτερων γειτόνων του query vector (που το ορίζουμε από την γραμμή εντολών), με την βοήθεια της διαδικασίας του κλαδέματος ακμών.
Στην τελευταία φάση του αλγορίθμου, καλείται η GreedySearch()
για τον υπολογισμό των K εγγύτερων γειτόνων, και ακολουθεί η μέθοδος CalculateRecallEvaluation()
, η οποία εξετάζει την εγκυρότητα των αποτελεσμάτων που επιστράφηκαν από την δεύτερη φάση, με τις τιμές που βρίσκονται στο αρχείο siftsmall_groundtruth.ivecs
και επιστρέφει το ποσοστό "ομοιότητας" των πρσεγγιστικών τιμών του VIA με την πραγματική τιμή του K.