Για όλες τις εργασίεςΓενικές συμβουλέςΟρατό output στο ipynbKaggleΑναφορές - βιβλιογραφία - κώδικαςNon-interactive εκτέλεση κώδικαΕργασία 1. ΤαξινόμησηΒέλτιστες τιμές υπερπαραμέτρωνΕκτιμητές "out-of-the-box"Datasets ήδη χωρισμένα σε train και testMulticlass ClassificationDataset specific questionsU01U11U14Βελτιστοποίηση αρχιτεκτονικήςΕπεξεργασία αρχείων .arffConcatenate αρχείων δεδομένωνΤο delimiter δεν αποτελείται πάντα από τον ίδιο αριθμό κενών (“ “)Διαχείριση τιμών χαρακτηριστικών που απουσιάζουνrandom_stateΕξισορρόπηση με undersamplingΕπιτάχυνση for loopsΒέλτιστη αρχιτεκτονική pipelineΣυμβουλές για το grid searchΕργασία 2 Text mining - ΟμαδοποίησηΑποθήκευση αντικειμένου SOMΜεγέθη αρχείων & χρόνοι εκτέλεσηςΠώς αποθηκεύονται και πως κατεβαίνουν τοπικά τα joblib pkl dumpsGoogle ColaboratoryKaggleΕντός των κειμένων υπάρχουν κάποιοι χαρακτήρες της μορφής “\xd3”ΕμφυτεύματαΠοια εμφυτεύματα να δοκιμάσουμε;Recommender: ομοιότητα ή απόσταση συνημιτόνου;Recommender: τί εννοούμε στη βελτιστοποίηση του tf-idf με το “πολλά φαινόμενα που το σύστημα εκλαμβάνει ως ομοιότητα περιεχομένου, επί της ουσίας δεν είναι επιθυμητό να συνυπολογίζονται”.Εργασία 3. Βαθιά ΜάθησηAttributeError: ‘str’ object has no attribute ‘decode’ Keep alive script για το Kaggle (by Ben10)Αποθήκευση numpy arrays (.npy), checkpoints, pickle και άλλων αρχείωνColabKaggleDefault μέθοδοςΤοπική αποθήκευση και ανέβασμαΤοπική αποθήκευσηΑνέβασμαΜέθοδος 1: ως datasetΜέθοδος 2: gdownΑξιολόγηση του BLEUΣυμβουλές εκπαίδευσης
Η παράδοση του ipynb (το download) παρακαλούμε να γίνεται με όλα τα κελιά να έχουν τρέξει (να είναι ορατό το output του κώδικα)
Ειδικά στο Kaggle για να μείνει ορατό το output θα πρέπει να κάνετε commit.
Αν βρείτε πληροφορίες, αναφορές, papers στο Internet σχετικά με το πρόβλημα που μελετάτε η σωστή πρακτική είναι να βάζετε την πηγή (url, βιβλιογραφική αναφορά κοκ). Το ίδιο ισχύει και με τον κώδικα.
Όλοι δανειζόμαστε (αρκεί να καταλαβαίνουμε τί κάνει o κώδικας), η βέλτιστη πρακτική όμως επιβάλει να παραθέτουμε την πηγή (σε σχόλιο), και για εμάς, και για τρίτους που διαβάζουν τον κώδικα.
Οι οδηγίες αυτές είναι χρήσιμες όταν θέλουμε να τρέξουμε ένα ή περισσότερα κελιά κώδικα που μπορεί να πάρουν πολύ χρόνο να ολοκληρωθεί.
Αρχικά, όταν κλείνουμε το tab του browser ή τον browser o πυρήνας εξακολουθεί να εκτελείται μέχρι να λάβει εντολή τερματισμού, είτε από εμάς, είτε από το περιβάλλον του (ref). Αυτό που θα χάσουμε αν κλείσουμε το κελί θα είναι του output του κελιού που πιθανότατα περιέχει τα αποτελέσματα που μας ενδιαφέρουν. To output κατευθύνεται στο stdout (standard output) του λειτουργικού και το jupyter το φέρνει μέσα στο browser.
Προκειμένου να σώσουμε την έξοδο στο stdout είναι να βάλουμε στην αρχή του κελιού τη μαγική εντολή "capture" με %%capture output
η οποία θα σώσει στη μεταβλητή "output" την έξοδο του κελιού ή του notebook όταν αυτό ολοκληρώσει.
Τρέχουμε το κελί και μπορούμε άνετα να κλείσουμε το tab ή το browser (άσχετα αν μας προειδοποιεί ο browser να μην φύγουμε). Αν αργότερα ανοίξουμε το browser και το κελί έχει τερματίσει, με ένα απλό print(output)
θα πάρουμε την έξοδο του κελιού. Αν η έξοδος περιλαμβάνει και γραφικά θα πρέπει να δώσετε output.show()
.
Προσοχή: τα περιβάλλοντα cloud αφήνουν τους πυρήνες των notebooks να τρέχουν μόνο μέχρι ένα maximum χρόνου οπότε δεν ενδείκνυται για πολύ μεγάλα πειράματα. Use at your own risk.
To gridsearchCV πραγματοποιείται εντός του training set και μας δίνει τον καλύτερο συνδυασμό υπερπαραμέτρων με βάση το μέσο όρο του metric που χρησιμοποιούμε σε όλα τα folds του crossvalidation. Αυτό δεν σημαίνει πάντοτε ότι αυτές οι υπερπαράμετροι θα δώσουν τη μέγιστη δυνατή τιμή στο test set (δεν αποκλείεται πχ ένας άλλος συνδυασμός να δώσει λίγο καλύτερες τιμες - υπάρχει ένα τέτοιο παράδειγμα στα notebooks) για το metric ωστόσο πάντα θα δώσουν μια πολύ καλή τιμή. Συνεπώς, επειδή η χρήση του test set απαγορεύεται πλήρως στην εκπαίδευση, ο μόνος τεκμηριωμένα ορθός τρόπος για να βρίσκουμε βέλτιστες υπερπαραμέτρους είναι το gridsearchcv.
Οι εκτιμητές (estimators) "out-of-the-box" έχουν κάποιες default τιμές για όλες τις υπερπαραμέτρους. Όταν ζητείται η απόδοσή τους "out-of-the-box" σημαίνει με αυτές τις default τιμές, δηλαδή κάνετε αμέσως fit στο training set και predict στο test. Σε κάποιες περιπτώσεις μπορεί καν να μην δίνουν αποτελέσματα.
Το crossvalidation είναι μέρος της βελτιστοποίησης των ταξινομητών που στοχεύει στην εύρεση των βέλτιστων τιμών των υπερπαραμέτρων.
Αν τα ποσοστά του test και του train είναι κοντά σε αυτά που ζητάει η εκφώνηση, μπορείτε να χρησιμοποιήσετε το train ως έχει για διασταυρούμενη επικύρωση πλέγματος. Αν τα ποσοστά είναι πολύ διαφορετικά, μπορείτε να τα ενοποιήσετε και διαχωρίσετε με την train_test_split. Όπως και να έχει εξηγήστε την επιλογή σας.
Σε κάποια προβλήματα οι κατηγορίες εξόδου δεν είναι μόνο δύο (binary) αλλά περισσότερες (multiclass). Υπάρχουν ταξινομητές που μπορούν να κάνουν multiclass ταξινόμηση απευθείας (inherently multiclass) και άλλοι που δεν μπορούν, στους οποίους πρέπει να μετασχηματισουμε το πρόβλημα από multiclass συνήθως σε one-vs-all (binary). Στο UCI, όλοι οι ταξινομητές που χρησιμοποιούμε (GNB, kNN, LR) είναι inherently multiclass (το είδαμε στο Iris που έχει 3 κατηγορίες εξόδου) και δεν χρειάζεται να κάντε one-vs-all. Περισσότερα εδώ.
Το χαρακτηριστικό εξοδου (η κλάση) είναι το 13ο “alive-at-1”. Θα κρατήσετε μόνο όσα δείγματα δεν έχουν “?” στο “alive-at-1”. Τα χαρακτηριστικά είναι τα 3 έως 9 (τα υπόλοιπα μπορούν να αγνοηθούν). Η πρόβλεψη μπορεί να γίνει και με τα χαρακτηριστικά 1-9 (όπως διατυπώθηκε αρχικά) απλά θα δίνει πολύ υψηλές τιμές (που δεν προσφέρονται για πολύ περεταίρω βελτιστοποίηση) γιατί υπάρχει μεγάλη συσχέτιση (αν και όχι απόλυτη) μεταξύ των χαρακτηριστικών 1 και 2 και της μεταβλητής εξόδου. Δείτε εδώ τη συσχέτιση Pearson μεταξύ χαρακτηριστικών και εξόδου. Οι κολόνες 1-9 είναι τα χαρακτηριστικά εισόδου (έχουμε αφαιρέσει τα 3 άχρηστα αρχικά χαρακτηριστικά) και η 10η κολόνα είναι η έξοδος. Τιμές κοντά στο -1 ή στο 1 δείχνουν υψηλή συσχέτιση, αντίστροφη (-1) ή ανάλογη (1). Δείτε εδώ μια βιβλιογραφική αναφορά για τη διαχείριση του dataset.
Μπορείτε να το αναλύσετε ως binary classification παίρνοντας ως κατηγορία εξόδου μόνο το consensus.
Προχωρήστε κανονικά σε crossvalidation.
Πέραν της εύρεσης των βέλτιστων τιμών υπερπαραμέτρων, πρέπει να βρούμε και τη βέλτιστη αρχιτεκτονική των μετασχηματιστών. Δεν είναι καθόλου υποχρεωτικό να κάνουμε όλα τα βήματα scaling, variance threshold, PCA, μπορεί να μην χρειάζεται τίποτα από αυτά για τη βέλτιστη επίδοση. Μπορεί να χρειάζεται ένα από αυτά, δύο ή και τα τρία.
Συνήθως ξεκινάμε χωρίς μετασχηματιστές, να δούμε την επίδοση μόνο του ταξινομητή για να έχουμε ένα μέτρο και αρχίζουμε να προσθέτουμε μετασχηματιστές παρακολουθώντας την επίδραση τους στις επιδόσεις, πάντα με αναζήτηση πλέγματος με διασταυρούμενη επικύρωση. Το topic αυτό είναι almost duplicate με αυτό.
Ορισμός του format .arff. Για να το μετατρέψετε ένα arff σε ένα συνηθισμένο csv αρκεί να κρατήσετε μόνο τις γραμμές που δεν ξεκινάνε με “%”, “@” και δεν είναι κενές. Μπορείτε να το κάνετε manually σε ένα editor ή με ένα oneliner στο shell:
linux
cat data.arff | grep -ve "^@\|^%" | grep -v "^[[:space:]]*$" > data.csv
windows
xxxxxxxxxx
findstr /BV "@" data.arff | findstr /BV "%" | findstr /V /R /C:"^[ ]*$" > data.csv
Για να ενώσουμε όλα τα csv σε ένα:
linux
xxxxxxxxxx
cat *.csv > all.csv
windows
xxxxxxxxxx
copy *.csv all.csv
Σε αυτή την περίπτωση χρησιμοποιήστε στην pd.read_csv option delim_whitespace=True χωρίς να θέσετε καθόλου option delimiter. read the docs. Γενικά μπορούμε να ορίσουμε τα delimiters με full σύνταξη regular expressions που είναι πολύ ισχυρή μέθοδος (non Python specific).
Έστω ότι μια τιμή που απουσιάζει συμβολίζεται με “?” (χωρίς τα εισαγωγικά). Βρίσκουμε πρώτα τον αριθμό δειγμάτων (γραμμών) που έχουν έστω μια τιμή χαρακτηριστικού που απουσιάζει:
linux
xxxxxxxxxx
cat data.csv | grep "?" | wc -l
windows
xxxxxxxxxx
findstr "?" data.csv | find /c /v
Aν το ποσοστό των δειγμάτων με τιμές που απουσιάζουν είναι σχετικά μικρό (πχ <5% του συνόλου του dataset μπορούμε να αφαιρέσουμε τα συγκεκριμένα δείγματα
linux
xxxxxxxxxx
cat data.csv | grep -v "?" > nomissing.data.csv
windows
xxxxxxxxxx
findstr /V "?" data.csv > nomissing.data.csv
Αν αφαιρέσουμε δείγματα με απουσιάζουσες τιμές, το κάνουμε πριν το το χωρισμό σε train και test set, πριν ή μετά την εισαγωγή του csv στο notebook.
Αν το ποσοστό είναι μεγαλύτερο, δεν θέλουμε να “θυσιάσουμε” σημαντικό μέρος των δεδομένων. Χρησιμοποιούμε το μετασχηματιστή “Imputer” του scikit learn που αντικαθιστά κάθε απουσιάζουσα τιμή χαρακτηριστικού με τη μέση τιμή (συνεχείς μεταβλητές) ή την πιο συχνή τιμή (κατηγορικές μεταβλητές) του χαρακτηριστικού στο train set.
Για να διαβάσετε ένα αρχείο csv με απουσιάζουσες τιμές που συμβολίζονται με “?” (χωρίς τα εισαγωγικά) μπορείτε να περάσετε στην read_csv των pandas την παράμετρο na_values=["?"]. Στη συνέχεια αν θέλετε για παράδειγμα να αντικαταστήσετε με τη μέση τιμή μπορείτε απλά να θέσετε imp = Imputer(strategy='mean', axis=0) , δηλαδή χωρίς την παράμετρο missing_values.
Ο μετασχηματισμός με Imputer γίνεται στην απόλυτη αρχή της προεπεξεργασίας αλλά μετά το διαχωρισμό σε train και test set. Μπορεί επίσης να χρησιμοποιηθεί σε pipeline, ως το απολύτως πρώτο βήμα, καθώς όλοι οι υπόλοιποι estimators του scikit δεν διαχειρίζονται απουσιάζουσες τιμές.
Αν υπάρχουν και μη διατεταγμένες μεταβλητές τις μετατρέπουμε σε δυαδικές αφού διαχειριστούμε τις απουσιάζουσες τιμές.
Αν μετατρέψουμε κατηγορικές μεταβλητές σε one-hot encoding και έρθει τιμή του χαρακτηριστικού στο test set που δεν έχουμε συμπεριλάβει στο mapping του one-hot, θα πρέπει να απορρίψουμε το δείγμα αυτό του test set.
Σε κάποια παραδείγματα χρησιμοποιούμε τη random_state για να έχουμε συγκεκριμένες αρχικοποιήσεις της γεννήτριας τυχαίων αριθμών. Εσείς μην την χρησιμοποιείτε στις αρχικοποιήσεις σας.
Σε μεγάλα datasets είναι πιθανό η εξισορρόπηση με oversampling να μεγαλώσει πολύ το μέγεθός τους. Μπορεί να δοκιμαστεί και η μέθοδος undersampling του imblearn που μειώνει το μέγεθος του dataset κατά την εξισορρόπηση.
Θα μπορούσε να γίνει παράλληλη επεξεργασία με τη βιβλιοθήκη joblib. Εγκατάσταση εντός notebook με “!pip install --upgrade joblib” (doc).
Η βέλτιστη αρχιτεκτονική για ένα dataset και ένα ταξινομητή βρίσκεται μόνο εμπειρικά. Μπορείτε να προχωρήσετε bottom up (μόνο με estimator και να προσθέτετε μετασχηματιστές) ή top down δηλαδή με όλα τα στάδια (επιλογή χαρακτηριστικών, κανονικοποίηση, εξαγωγή χαρακτηριστικών, ταξινομητής) και να κάνετε δοκιμές αφαιρώντας κάποιο μετασχηματιστή.
Εφόσον έχετε αρχικοποιήσει και εκπαιδεύσει ένα αντικείμενο “som” με τις somoclu.Somoclu(...) και som..train(...) και αφότου υπολογίσετε και τα clusters με som.cluster(...) αποθηκεύετε ολόκληρο το αντικείμενο με joblib.dump(som, 'som.pkl').
Ένα συμπιεσμένο corpus_tf_idf.pkl ενός αποτελεσματικού recommender μπορεί να είναι και κάτω από 4MB. Ένας συμπιεσμένος χάρτης 25x25 μπορεί να είναι κάτω από 3ΜΒ. Εάν το training του SOM παίρνει πολύ ώρα και τα αρχεία σας βγαίνουν υπερβολικά μεγάλα δεν έχετε βελτιστοποιήσει τη διανυσματική αναπαράσταση των κειμένων όσο πρέπει. Όπως αναφέρεται στην εκφώνηση “Χρησιμοποιήστε την time για να έχετε μια εικόνα των χρόνων εκπαίδευσης. Ενδεικτικά, σε εκτέλεση στα clouds, με σωστή κωδικοποίηση tf-idf, μικροί χάρτες για λίγα δεδομένα (1000-2000) παίρνουν γύρω στο ένα λεπτό ενώ μεγαλύτεροι χάρτες με όλα τα δεδομένα μπορούν να πάρουν 10 λεπτά ή και περισσότερο.”. Προσπαθήστε να βελτιστοποιήσετε τους μικρούς χάρτες πρωτού δοκιμάσετε μεγαλύτερους για να μην περιμένετε πολύ.
Κάντε expand το αριστερό sidebar του notebook. Στο tab “Files” θα δείτε όλα τα αρχεία εντός του χώρου του workspace. Κάντε δεξί κλικ και “Download” σε αυτό που θέλετε να κατεβάσετε.
Θεωρούμε ότι έχουμε δημιουργήσει τα αρχεία .pkl. Σε επόμενο κελί κώδικα γράψτε
xxxxxxxxxx
from IPython.display import FileLink, FileLinksFileLinks('.') #lists all downloadable files on server
και κάντε run. Θα εμφανιστεί κάτι τέτοιο:
με απλό κλικ στα ονόματα κατεβαίνουν τα αρχεία.
Πρόκειται για την hex κωδικοποίηση unicode χαρακτήρων. Αγνοήστε το στην επεξεργασία σας καθώς είναι λίγοι σε αριθμό σε σχέση με τη συλλογή. Αν θέλετε να δείτε ποιος χαρακτήρας είναι μπορείτε να τρέξετε
xxxxxxxxxx
print u'\xd3'
Ó
Μπορείτε επίσης να συμβουλευτείτε και ένα πίνακα unicode lookup.
Μπορείτε πρώτα να δείτε τα μεγέθη των embeddings. Ίσως να μην είναι αποτελεσματικά τα μικρότερα όλων. Στη συνέχεια δοκιμάστε διαφορετικά εμφυτεύματα σε σχέση με τον τρόπο που σχηματίστηκαν, σε ποια κείμενα βασίζονται (πχ news, twitter κλπ.)
Μην εξετάζετε κοντινές παραλλαγές εμφυτευμάτων.
Κάντε οπωσδήποτε pickle τα ετοιμασμένα corpora προκειμένου να μπορείτε να τα φορτώνετε άμεσα.
Στην εκφώνηση της άσκησης ζητάμε να υπολογίσετε την ομοιότητα συνημιτόνου της ταινίας στόχου με όλες τις ταινίες της συλλογής, να φτιάξετε μια λίστα με φθίνουσα σειρά ομοιότητας και να επιστρέψετε τα πρώτα max_recommendations. Στο lab “Text mining” έχουμε μιλήσει και για ομοιότητα και για απόσταση συνημιτόνου και το παράδειγμα που δίνουμε είναι με την απόσταση (sp.spatial.distance.cosine). Γενικά ισχύειτο πολύ απλό “cos_similarity = 1 - cos_distance”, δηλαδή, για παράδειγμα, μια ταινία έχει ομοιότητα με τον εαυτό της 1 και απόσταση 0. Συνεπώς αν θέλετε να χρησιμοποιήσετε απόσταση συνημιτόνου στο recommender, πρέπει να φτιάξετε μια λίστα με αύξουσα απόσταση συνημιτόνου και να επιστρέψετε τα πρώτα max_recommendations.Αν ακολουθήσετε τη μέθοδο της ομοιότητας όπως λέει η άσκηση, θα πρέπει να χρησιμοποιήσετε την cosine_similarity. Είναι προφανώς τελείως ισοδύναμες οι προσεγγίσεις.
Επειδή η database μας είναι περιγραφές υποθέσεων ταινιών πολύ συχνά η σύνοψη ξεκινά με φράσεις όπως “The plot of this film is about…”. Είναι φανερό ότι τα ουσιαστικά “plot” και “film” δεν αποτελούν μέρος της σημασιολογικής περιγραφής του ίδιου του φιλμ. Υπάρχουν και κάποιες ακόμα τέτοιες λέξεις. Παρόμοιο φαινόμενο παρατηρείται σε κάποιες περιπτώσεις και με κύρια ονόματα κλπ. Υπάρχει τρόπος να το διαχειριστείτε διαβάζοντας το documentation.
δοκιμάστε:
Προκειμένου να πετύχετε πολύωρη “unattended” εκπαίδευση πρέπει να “ξεγελάσετε” το Kaggle ώστε να νομίζει ότι εκτελείτε διαδραστικά το notebook. Μπορείτε να τρέξετε τοπικά (στον υπολογιστή σας) αυτό το python script (οδηγίες στα σχόλια).
Καταρχάς σημειώστε ότι για να λειτουργήσουν τα checkpoints χρειάζεστε ολόκληρο το folder τους και όχι μεμονωμένα αρχεία ckpt
.
Στο Colab ο καλύτερος τρόπος για αποθήκευση και φόρτωση checkpoints και άλλων ενδιάμεσων αρχείων που χρειάζονται για την εκπαίδευση των δικτύων είναι να κάνετε mount έναν λογαριασμό Google Drive όπως εδώ.
Παρότι το Kaggle ισχυρίζεται ότι αν κάνεις commit ένα notebook τα δεδομένα που βρίσκονται ενός του directory working
(εκεί που δουλεύεις by default) σώζονται, η διαδικασία είναι λίγο πιο πολύπλοκη.
Συγκεκριμένα, έστω ότι έχετε κάνει commit το notebook σας. Αν θέλετε να πάρετε την έξοδό του σε ένα άλλο notebook (ή στο ίδιο αργότερα) θα πρέπει εντός του notebook να κάνετε Add data
πάνω δεξιά και να διαλέξετε Notebook Output Files
, να εφαρμόσετε το φίλτρο Your Work
και να κάνετε Add
το notebook με τα αρχεία εξόδου.
Τα δεδομένα θα είναι διαθέσιμα στο directory /kaggle/input/
το οποίο είναι στο ίδιο ύψος με το working.
Ο default τρόπος είναι δύσχρηστος κυρίως γιατί απαιτεί commit που σημαίνει ότι πρέπει να τρέξει ολόκληρο το notebook. Εναλλακτικά, μπορούμε να ακολουθήσουμε την ακόλουθη διαδικασία:
Αν έχετε αρχεία σε ένα directory dir
μπορείτε να τα συμπιέσετε σε ένα αρχείο με μια εντολή όπως
xxxxxxxxxx
tar czvf dir.tar.gz dir
Εφόσον το αρχείο dir.tar.gz
βρίσκεται στο dirctory working
(το default) τότε τρέχοντας
xxxxxxxxxx
from IPython.display import FileLink
FileLink(r'dir.tar.gz')
θα παραχθεί ένα link για να κατεβάσουμε τοπικά το αρχείο.
Ο default τρόπος για το ανέβασμα δεδομένων στο Kaggle είναι να τα ανεβάσετε ως datasets (ακόμα και αν δεν είναι). Μπορείτε εύκολα να το ξεγελάσετε και να ανεβάσετε ό,τι αρχείο έχετε τοπικά επιλέγοντας "Datasets"
στο αριστερό sidebar και πατώντας "New Dataset"
.
Μια μάλλον καλύτερη μέθοδος είναι να χρησιμοποιήσετε το gdown. Τοποθετήστε το τοπικό αρχείο σε ένα Google Drive και δημιουργήστε ένα share link. Εντός του notebook στο Kaggle γράψτε:
xxxxxxxxxx
import gdown
url = 'Google DRIVE LINK'
output = 'FILENAME'
gdown.download(url, output, quiet=False)
Υλοποιήστε πρώτα μια συνάρτηση που να σας δίνει bleu score για μια εικόνα (sentence_bleu) και για ένα σύνολο εικόνων (corpus_bleu), κάντε εκπαίδευση κατά βήματα 20-30 epochs και δείτε πως αποδίδει το σύστημα σε μεμονωμένες εικόνες (ποιοτική αξιολόγηση) και στο validation (ποσοτική). Δεν χρειάζεται να εκπαιδεύσετε για άπειρα epochs μετά από κάθε αλλαγή.
Στην παρακάτω εικόνα
βλέπετε ένα παράδειγμα του τί μπορεί να επιστρέφει μια συνάρτηση get_image_bleu.
Σε πόσα epochs να σταματήσουμε; όσο κάνετε δοκιμές, στο σημείο που αρχίζετε να έχετε καλά catpions. Σημειώνετε το loss και τον αριθμό των epochs. Το προηγούμενο πολύ καλό παράδειγμα captioning, με πολύ υψηλό bleu το πετύχαμε με το vanilla σύστημα όταν το training loss είχε φτάσει στο 0.206126.
O τρόπος που παράγονται τα captions είναι στοχαστικός, κάθε φορά θα παίρνετε διαφορετικό bleu. Προφανώς όσο περισσότερο εκπαιδευμένο είναι ένα σύστημα, τόσο μικρότερη θα είναι η διακύμανση.
Κάντε μια πολύ μεγάλη εκπαίδευση μόνο στο τελικό σας σύστημα.