- Les humains gèrent mal le spaghetti code
- Dans les projets de recherche, on écrit souvent des programmes qui extraient des informations à partir de données brutes
- Les données ne suivent pas de spécifications claires
- Exemples :
- identifier des entreprises et des dirigeants dans des articles de presse
- étiqueter des contrats de marchés publics par type de service
- identifier du code de programme dans des messages entre ingénieurs
Détecter du code de programme dans des messages
- Résolution du problème consistant à détecter, lors d'une revue de code, si un message fait référence à du code de programme
- Exemples de messages :
- LGTM with render_ipa_alloc()
- If the FTPSACK flag is set, then use a prespecified value
- AFAICT there is nothing else to check (unless you can think of something)
- Actually, debug_error() doesn’t return NULL, so we should use IS_ERROR() here
- This fails to build on aarch64 even though it works without issue on amd64
- I’ve added if (err) goto cleanup; but the code still leaks
Idée de règles de décision
- Approche consistant à utiliser des règles simples pour distinguer le code de programme de l'anglais courant
- Règles :
- un mot suivi de parenthèses est du code
- un mot entièrement en majuscules est du code
- un mot non anglais est du code
- Avantages et inconvénients de chaque règle :
- Règle 1 : simple, mais rate des cas positifs évidents
- Règle 2 : classe à tort des acronymes en majuscules comme code de programme
- Règle 3 : classe à tort des termes d'ingénierie comme code de programme
Algorithme écrit à la main
- Conclusion qu'un algorithme simple peut fonctionner suffisamment bien
- Décider en deux étapes si un message contient du code :
- prétraitement : convertir le message en une séquence de tokens
- inférence : appliquer des règles à la séquence de tokens pour déterminer si elle contient du code
- Exemple d'implémentation en Python :
from dataclasses import dataclass
Token = str
@dataclass
class State:
previous_was_identifier: bool = False
previous_was_open_paren: bool = False
previous_previous_was_identifier: bool = False
seen_code: bool = False
def contains_code(tokens: Iterable[Token]) -> bool:
state = State()
for token in tokens:
state = process(state, token)
return state.seen_code
def process(state: State, token: Token) -> State:
if state.seen_code:
return state
if (token == "close_paren" and state.previous_was_open_paren and state.previous_previous_was_identifier):
state.seen_code = True
return state
state.previous_previous_was_identifier = state.previous_was_identifier
state.previous_was_identifier = token in ("all_caps_identifier", "underscore_identifier", "misc_identifier")
state.previous_was_open_paren = token == "open_paren"
return state
L'aide des réseaux de neurones
- Il est possible d'encoder
contains_code et process comme une machine à états sous forme de RNN
- On peut utiliser un RNN pour trouver un meilleur algorithme
Idée générale
- Un RNN approxime des probabilités conditionnelles
- Il calcule un vecteur d'état pour chaque token
- Il classe le message à partir de l'état final
Du code Python vu par les mathématiques
- Explication de la manière dont un RNN encode la règle 1
- Représentation de chaque token sous forme de vecteur binaire
- Calcul de l'état caché pour appliquer la règle
Entraînement du réseau
- Changement de la fonction d'activation en ReLU pour entraîner le RNN
- Entraînement possible avec PyTorch
Une architecture avec une implémentation plus efficace
- Utilisation d'architectures fournies par PyTorch, comme l'Elman RNN
- Dans l'Elman RNN, chaque couche cachée prend en entrée à la fois la couche précédente et la couche courante
Une architecture avec des gradients plus stables
- Les messages longs posent problème, car les gradients deviennent proches de 0
- Des architectures comme GRU ou LSTM peuvent offrir de meilleures performances
Une discipline centrée sur les données
- Les RNN gèrent mieux le spaghetti code
- Ils imposent une discipline centrée sur les données qui clarifie le problème
L'avis de GN⁺
- Cet article explique bien comment utiliser un RNN pour résoudre un problème complexe
- L'utilisation d'un RNN facilite la maintenance du code
- Des outils comme PyTorch permettent une implémentation efficace
- Il faut envisager des architectures comme GRU ou LSTM
- Une approche centrée sur les données est utile pour résoudre le problème
1 commentaires
Commentaire Hacker News
Cet article ne traite pas beaucoup des tests ni des données d'entraînement
Cet article est intéressant si on le lit comme une méthode pour construire un réseau de neurones capable d'effectuer un travail pratique
Il existe un théorème d'approximation universelle (Universal Approximation Theorem) pour les réseaux de neurones
Cet article aborde des concepts mathématiques profonds autour des RNN, tout en proposant des idées intéressantes
Certains se demandent si les RNN ont été complètement remplacés par les transformeurs
Le Genetic Programming mérite qu'on s'y intéresse
Cet article présente les RNN comme une expérience d'apprentissage, en les comparant au RNN de PyTorch
Les RNN peuvent effectuer des calculs arbitraires, mais ce n'est pas pratique
Certains pensent que les réseaux de neurones ressembleront de plus en plus à du code