Il utilise curses, une bibliothèque pour créer TUI (interface utilisateur texte), pour afficher la progression d'apprentissage de BPE d'une manière agréable.
Le code entier est téléchargé sur gist. :arrow_right: bpe_curses.py
BPE
(Si vous voulez juste en savoir plus sur les malédictions, sautez-le)
L'encodage par paires d'octets est une technique également utilisée dans le tokenizer de traduction automatique neuronale Sentencepiece. La première apparition était Traduction automatique neuronale de mots rares avec des unités de sous-mots (ACL2016), et l'implémentation est également décrite dans l'article.
Par exemple, si vous avez des mots comme «inférieur», «plus récent», «plus large», vous pouvez réduire le nombre de vocabulaire en traitant le «e r» fréquent comme un symbole «plus».
Comme vous pouvez le voir, bien qu'il soit célèbre en tant qu'algorithme de division de sous-mots en PNL, c'est une méthode de compression de données en premier lieu, et elle est changée en [Byte vs. Encoding (Wikipedia)](https://ja.wikipedia.org/wiki/Byte vs. Encoding). Le principe est également introduit.
Cette fois, en fonction du code du papier, la progression de la compression est sortie.
Pour la mise en œuvre de BPE, j'ai simplement utilisé le code dans le papier et ajouté des indices de type.
L'implémentation se compose de deux fonctions principales, get_status ()
et merge_vocab ()
.
--get_status
prend un dictionnaire vocal et vérifie la fréquence des combinaisons de mots.
defaultdict
est utilisé pour gérer les combinaisons qui ne sont pas dans la clé. def get_stats(vocab: Dict) -> DefaultDict:
pairs = collections.defaultdict(int)
for word, freq in vocab.items():
symbols = word.split()
for i in range(len(symbols)-1):
pairs[symbols[i], symbols[i+1]] += freq
return pairs
--Dans merge_vocab
, parmi les combinaisons examinées par get_status
, la combinaison la plus fréquente est fusionnée pour la traiter comme un mot.
def merge_vocab(pair: List, v_in: Dict) -> Dict:
v_out = {}
bigram = re.escape(' '.join(pair))
p = re.compile(r'(?<!<\S)' + bigram + r'(?!\S)')
for word in v_in:
w_out = p.sub(''.join(pair), word)
v_out[w_out] = v_in[word]
return v_out
Cette fois, nous afficherons la transition d'état du mot après merge_vocab
.
Curses
La bibliothèque curses fournit un dessin d'écran indépendant du terminal et un traitement du clavier pour les terminaux basés sur du texte (terminaux) tels que les VT100, les consoles Linux et les terminaux d'émulation fournis par divers programmes. Depuis Curses Programming with Python
curses est un module python standard. (Il ne semble pas être inclus dans la version Windows ...) Si vous utilisez des malédictions, vous pouvez facilement créer quelque chose comme une application CUI.
Par exemple, life.py dans la démo de python est [Life Game](https: //) sur le terminal. ja.wikipedia.org/wiki/life game).
Nous allons implémenter l'affichage des transitions d'état avec des malédictions.
Comme décrit dans Curses Programming with Python, curses.wrapper est utilisé pour éviter la complexité de la gestion des erreurs et de l'initialisation. Utilisez la fonction ()
.
import curses
def main(stdscr):
#Traitement des malédictions d'appels avec stdscr
if __name__ == '__main__':
curses.wrapper(main)
Le flux de traitement de base est le suivant.
--stdscr.addstr (str)
: Ajouter du texte str
à la position actuelle
--stdscr.refresh ()
: Rafraîchir l'affichage
--ʻAddstr Afficher le texte --
stdscr.getkey () `: Accepte les frappes
for i in range(10):
stdscr.addstr('{}\n'.format(i))
stdscr.refresh()
stdscr.getkey()
Dans le cas du code ci-dessus, le numéro est affiché et l'état d'attente est répété.
Tenter d'afficher dans une plage plus longue que la hauteur de l'écran entraînera une erreur.
Afin d'éviter les erreurs, il faut d'abord obtenir la taille de l'affichage actuel et ensuite envisager de ne pas spécifier en dehors de la plage de l'affichage. Vous pouvez obtenir la taille avec getmaxyx ()
.
stdscr_y, stdscr_x = stdscr.getmaxyx()
S'il est laissé tel quel, il n'aura pas bon goût, j'essaierai donc de concevoir un présentoir.
Cette fois, si vous fusionnez les lettres, les mots seront en gras.
Plus précisément, ajoutez les informations d'attribut curses.A_BOLD
à ʻaddstr`.
Vous pouvez également le colorier ou le faire clignoter. Les attributs réels et les résultats d'exécution de Attributes et couleurs sont les suivants.
stdscr.addstr('This is A_BOLD\n', curses.A_BOLD)
stdscr.addstr('This is A_BLINK\n', curses.A_BLINK)
stdscr.addstr('This is A_DIM\n', curses.A_DIM)
stdscr.addstr('This is A_STANDOUT\n', curses.A_STANDOUT)
stdscr.addstr('This is A_REVERSE\n', curses.A_REVERSE)
stdscr.addstr('This is A_UNDERLINE\n\n', curses.A_UNDERLINE)
#Spécifiez la couleur de l'arrière-plan et du texte
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
stdscr.addstr("This is curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)\n", curses.color_pair(1))
Lorsque vous exécutez bpe_curses.py créé en tenant compte de ce qui précède, le résultat mis à jour est généré en fusionnant chaque fois que vous appuyez sur la touche comme indiqué ci-dessous. Sera fait.
C'est un peu déroutant car les lettres sont petites, mais c'est un mot qui contient des paires avec ** gras ** fusionné. Au départ, «plus récent» et «plus large» sont en gras car «e» et «r» sont les paires les plus fréquentes. (2e ligne)
De plus, en répétant la fusion 10 fois, vous pouvez voir que le nombre de vocabulaire affiché à l'extrême gauche a diminué. (14 → 6)
Je ne pense pas qu'il était vraiment nécessaire d'être interactif cette fois, mais les malédictions peuvent recevoir des frappes au clavier, donc je pense qu'il peut être utilisé de différentes manières en fonction de l'appareil. C'est plus facile que d'implémenter une interface graphique, il peut donc être bon d'afficher un peu de sortie.
--Document
Recommended Posts