Maison > Article > Périphériques technologiques > Un examen de la technologie de modèle de programmation automatique PNL
Ces dernières années, en raison de l'essor des transformateurs dans le domaine du traitement du langage naturel, nous avons vu une gamme étonnante de modèles d'apprentissage profond codés. La capacité à écrire des programmes informatiques, souvent appelée problème de synthèse de programmes, est étudiée depuis au moins la fin des années 1960 et le début des années 1970.
Dans les années 2010 et 20, le succès des modèles basés sur l'attention dans d'autres domaines a de nouveau inspiré la recherche en synthèse procédurale, c'est-à-dire le pré-entraînement avec des millions ou des milliards de paramètres sur des centaines de gigaoctets de texte. Stratégies d'attention à grande échelle- modèles neuronaux basés sur (transformateurs).
Les modèles pré-entraînés ont montré des capacités impressionnantes en méta-apprentissage, grâce à leur mécanisme d'attention, et semblent avoir une application pratique dans le développement de tâches de texte - en fournissant uniquement dans le contenu de l'invite Quelques exemples (appelés "zéro-shot ou quelques -shot learning" dans la littérature de recherche).
Les modèles PNL peuvent être entraînés davantage à l'aide d'ensembles de données spécialisés pour affiner les performances de tâches spécifiques. L’écriture de code est un cas d’usage particulièrement intéressant pour cette application.
Le projet Copilot sur GitHub, présenté comme « Your AI Pair Programmer », a suscité toute une controverse lors de son lancement en 2021. Cela est dû en grande partie à l’utilisation de tout le code public GitHub dans l’ensemble de données de formation. Selon les instructions, ces bases de code incluent des projets avec des licences copyleft, qui peuvent ne pas autoriser l'utilisation de code dans des projets tels que Copilot, à moins que Copilot lui-même ne soit open source.
Copilot est le produit d'une relation entre l'organisation OpenAI et Microsoft Corporation, et est basé sur une version formée au code de GPT-3. La version démontrée par OpenAI et disponible via son API s'appelle Codex. La description expérimentale formelle utilisant Copex est détaillée dans l'article publié par Chen et al.
Début 2022, DeepMind n'était pas en reste et a développé son propre système de PNL profonde synthétisé de manière procédurale : AlphaCode.
Comme Codex et Copilot avant lui, AlphaCode est un modèle PNL à grande échelle conçu et entraîné pour l'écriture de code. Comme Copilot, AlphaCode n'a pas été développé pour utiliser AlphaCode comme outil de productivité pour les ingénieurs logiciels, mais pour défier les performances de programmation au niveau humain dans des tâches de programmation compétitives.
La difficulté des défis de codage du concours utilisés pour former et évaluer AlphaCode (qui constitue le nouvel ensemble de données CodeContests) se situe quelque part entre la difficulté des ensembles de données précédents et la difficulté de l'ingénierie logicielle du monde réel.
Pour ceux qui ne sont pas familiers avec les sites de défis de programmation compétitifs, cette tâche s'apparente un peu à une version simplifiée du développement piloté par les tests. À partir de quelques descriptions textuelles et de quelques exemples, l'essentiel de ce défi est d'écrire un programme qui réussit un ensemble de tests, dont la plupart sont cachés au programmeur.
Idéalement, les tests cachés devraient être complets, et réussir tous les tests signifie qu'un problème donné a été résolu avec succès. Cependant, couvrir tous les cas extrêmes avec des tests unitaires est un problème difficile. Une contribution importante au domaine de la synthèse de programmes est en fait l'ensemble de données CodeContests lui-même, car l'équipe DeepMind a fait un effort significatif pour générer des tests supplémentaires via un processus de mutation, dans le but de réduire le taux de faux positifs (tests réussis, mais le problème a été résolu). pas été résolu) et un taux de positivité lent (le test réussit, mais la solution est trop lente).
Les performances d'AlphaCode sont évaluées par rapport au contenu d'un défi de programmation compétitif sur le site Web du concours CodeForces. Dans l'ensemble, AlphaCode s'est classé en moyenne dans le « top 54,3 % » des programmeurs concurrents (éventuellement humains).
Veuillez noter que cette mesure peut être un peu trompeuse car elle équivaut en réalité à 45,7 % de performances. Incroyablement, le système AlphaCode est capable d'écrire n'importe quel algorithme qui réussit tous les tests cachés. Cependant, soyez prévenu : AlphaCode utilise une stratégie très différente de celle des humains pour résoudre les problèmes de programmation.
Alors qu'un concurrent humain pourrait écrire un algorithme pour résoudre la plupart des routines - en intégrant les informations issues de l'exécution de versions antérieures de la solution et en l'améliorant continuellement jusqu'à ce qu'elle réussisse tous les tests, AlphaCode adopte une approche plus large qui génère plusieurs échantillons pour chacun ; question et sélectionnez 10 échantillons à soumettre.
Une grande contribution aux performances d'AlphaCode sur l'ensemble de données CodeContests réside dans les résultats du filtrage et du clustering post-génération : après avoir généré environ 1 000 000 de solutions candidates, il commence à filtrer les candidats pour supprimer les exemples de tests ayant échoué dans les candidats de description de problème, éliminant ainsi environ 99 % du bassin de candidats.
L'auteur a mentionné qu'environ 10 % des problèmes n'ont pas de solutions candidates qui réussissent tous les exemples de tests à ce stade.
Les candidats restants sont ensuite filtrés par regroupement en 10 candidatures ou moins. En bref, ils ont formé un autre modèle pour générer des entrées de test supplémentaires basées sur la description du problème (mais notez qu'ils ne disposaient pas de sorties valides pour ces tests).
Les solutions candidates restantes (le nombre après filtrage peut être inférieur à 1 000) sont regroupées en fonction de leur sortie sur l'entrée de test générée. Un candidat de chaque cluster est sélectionné pour soumission, du plus grand au plus petit. S'il y a moins de 10 clusters, les clusters sont échantillonnés plusieurs fois.
Bien que les étapes de filtrage/regroupement soient uniques et qu'AlphaCode soit affiné sur le nouvel ensemble de données CodeContests, il est initialement formé à peu près de la même manière que Codex ou Copilot. AlphaCode a d'abord été pré-entraîné sur un vaste ensemble de données de code accessible au public sur GitHub (récupéré le 14 juillet 2021). Ils ont entraîné 5 variantes et le nombre de paramètres est passé de 284 millions à 41 milliards.
Dans le même esprit que la série AlphaGo ou le robot AlphaStar qui joue au jeu StarCraft II, AlphaCode est aussi un projet de recherche visant à développer un système qui se rapproche des capacités humaines dans des domaines de tâches spécialisés, mais aussi avec l'utilitaire développé au passage. de synthèse du programme Le seuil est plus bas.
Du point de vue du développement d'outils pratiques pour résoudre des problèmes, les représentants des robots dans ce domaine sont les outils Codex et Copilot basés sur GPT-3. Codex est une variante OpenAI de GPT-3, formée sur un corpus de code accessible au public. Sur la base de l'ensemble de données HumanEval publié avec l'article, OpenAI rapporte que le Codex est capable de résoudre plus de 70 % des problèmes en générant 100 échantillons dans des tâches au format « docstring to code ».
Ensuite, nous explorerons cette technique de programmation rapide en utilisant le Codex pour générer automatiquement du code. Nous utiliserons simultanément le modèle donné ci-dessous pour développer le Game of Life de John Conway.
GitHub Copilot adopte la méthode de complétion automatique du code. Le formulaire de packaging actuel est une extension des environnements de développement intégrés tels que Visual Studio, VSCode, Neovim et JetBrains. Selon la description sur la page Web de Copilot, Copilot a réussi à réécrire un ensemble de fonctions Python bien testées selon la description donnée, dont 57 % sont similaires à l'ensemble de données HumanEval.
Nous examinerons quelques cas d'utilisation réels de Copilot, tels que l'automatisation de l'écriture de tests à l'aide d'une version bêta dédiée de l'extension Copilot pour VSCode.
Dans cette section, nous aborderons la tâche d'écriture d'un simulateur d'automate cellulaire basé sur le jeu de la vie de John Conway. Avec quelques modifications et sans coder en dur les règles, notre programme devrait être capable de simuler n'importe quel ensemble de règles d'automates cellulaires réalistes.
Au lieu de générer 100 exemples et de sélectionner le meilleur (soit manuellement, soit en exécutant des tests), nous adopterons une approche interactive. Lorsque le Codex donne une mauvaise solution, nous procédons à des ajustements pour essayer de guider une meilleure réponse. Bien sûr, si cela est absolument nécessaire, nous pouvons continuer à modifier le code pour obtenir un exemple fonctionnel au cas où le Codex échouerait complètement.
Écrivez un CA (Cellular Automata) réaliste, c'est-à-dire des "automates cellulaires". Il s'agit d'un modèle de dynamique de grille dans lequel le temps, l'espace et l'état sont discrets, et l'interaction spatiale et la causalité temporelle sont locales. Il a une complexité de simulation. La première étape dans le simulateur est de proposer une fonction qui calcule les voisins. Nous avons écrit l'invite docstring suivante et l'avons fournie à code-davinci-001, qui est le plus grand modèle Codex de la bibliothèque API OpenAI :
# PROMPT<br>import numpy as np<br>def compute_neighborhood(grid: np.array) -> np.array:<br>"""<br>Compute the sum of cell states in the Moore neighborhood<br>for each cell in the input grid.<br>A Moore neighborhood includes 8 cells,<br>diagonally and orthogonally adjacent to, but not including, the center cell.<br>The cells denoted by '1' correspond to the Moore neighborhood for cell a:<br>1 1 1<br>1 a 1<br>1 1 1<br>If cell 'a' is on the edge of the grid,<br>the Moore neighborhood wraps around to the cells on the opposite edge,<br>i.e. grid is on a toroid.<br><br>args:<br>grid, a numpy array with binary values 0 or 1. grid contains the current cell state values<br>Returns:<br><br>neighorhood_grid, a numpy array with integer values from 0 to 8.<br>For each cell (element in grid) in grid, neighborhood_grid should<br>contain the sum of states in that cell's Moore neighborhood<br>"""
Dans le code ci-dessus, l'ajout des lignes de commentaires "#PROMPT" et "#GENERATED" est Pour indiquer plus clairement où se termine l'invite.
Avez-vous soigneusement analysé l'invite docstring assez complète ci-dessus ? Comment fonctionne le Codex ? En fait, la première tentative du Codex ressemblait à ceci :
# GENERATED<br># TODO: implement this function<br>pass
Cela n’augure probablement rien de bon pour notre petite expérience. Même après avoir réglé l'hyperparamètre de valeur P pour obtenir un échantillonnage de noyau plus lâche (et, espérons-le, une meilleure diversité), le Codex ne semble toujours pas avoir de réponse à la question ci-dessus.
Heureusement, il nous suffit d'ajouter un petit quelque chose comme ci-dessous à l'invite docstring et le Codex produira un résultat plus prometteur.
# PROMPT (appended to previous prompt)<br><br>this function is completed and does not include any TODOs<br>"""<br><br># GENERATED<br><br># get the dimensions of the grid<br>n_rows, n_cols = grid.shape<br><br># initialize the output array<br>neighborhood_grid = np.zeros((n_rows, n_cols), dtype=int)<br><br># loop over the grid<br>for i in range(n_rows):<br>for j in range(n_cols):<br><br># get the current cell value<br>cell_val = grid[i, j]<br><br># get the Moore neighborhood of the current cell<br># using the get_neighborhood function<br>neighborhood = get_neighborhood(grid, i, j)<br><br># sum the cell values in the neighborhood<br>neighborhood_sum = np.sum(neighborhood)<br><br># store the sum in the neighborhood grid<br>neighborhood_grid[i, j] = neighborhood_sum<br><br>return neighborhood_grid
Bien sûr, ce n'est pas encore une bonne solution, car elle introduit une variable cell_val inutilisée et délègue l'essentiel de son travail à une autre fonction qu'elle vient d'ajouter, get_neighborhood. Mais dans l’ensemble, cela semble être un début réalisable.
Ensuite, nous avons écrit une simple docstring pour la fonction get_neighborhood mentionnée ci-dessus :
def get_neighborhood(grid: np.array, i: int, j: int) -> np.array:<br>"""<br>get_neighborhood is used by compute_neighborhood <br>to return the 3x3 Moore neighborhood for the cell <br>located at coordinates i,j If i,j coordinates are <br>on the edge of the grid (i.e. i or j equal 0, or i == <br>grid.shape[0]-1 or j == grid.shape[1]), the Moore<br>Neighborhood should wrap around to include cells on the<br>opposite edge. In other words the grid can be considered to <br>be the surface of a toroid, like 'Pac-Man'<br><br>args:<br>grid, np.array, this is the current state of<br>the cellular automata grid<br>i, int, this coordinate corresponds to the row<br>j, int, coordinate corresponding to column<br><br>returns:<br>moore_neighborhood - np.array, should always have<br>dimensions 3x3 and<br>contain the Moore neighborhood for the cell at i,j <br>in grid.Because the center cell is not part of the<br>neighborhood, moore_neighborhood[1,1] should always <br>be 0<br>"""<br><br># GENERATED<br><br># get the dimensions of the grid<br>n_rows, n_cols = grid.shape<br><br># initialize the output array<br>moore_neighborhood = np.zeros((3, 3), dtype=int)<br><br># get the coordinates of the Moore neighborhood<br># using the get_neighborhood_coordinates function<br>neighborhood_coords = <br>get_neighborhood_coordinates(i, j, n_rows, n_cols)<br><br># loop over the coordinates<br>for coord in neighborhood_coords:<br># get the cell value at the coordinate<br>cell_val = grid[coord[0], coord[1]]<br><br># store the cell value in the output array<br>moore_neighborhood[coord[0], coord[1]] = cell_val<br><br>return moore_neighborhood
La sortie du programme ci-dessus semblait réalisable mais après inspection, elle contenait en fait une erreur importante.
Dans la boucle sur les coordonnées voisines, il attribue la valeur au quartier Moore en utilisant les mêmes coordonnées que celles qui ont récupéré la valeur de la grille.
Nous n'avons pas trouvé de moyen clair d'inviter le Codex à éviter les erreurs ; nous avons donc dû modifier manuellement le code :
# FIXED loop over the coordinates <br>for index, coord in enumerate(neighborhood_coords): <br># get the cell value at the coordinate<br>cell_val = grid[coord[0], coord[1]] <br><br># FIXED store the cell value in the output array<br>moore_neighborhood[index // 3, index % 3] = cell_val<br><br>return moore_neighborhood
De plus, une autre fonction get_neighborhood_coordonnées a été introduite dans le code précédent pour gérer la partie la plus "délicate".
Ensuite, nous devons écrire une invite pour la fonction get_neighborhood_coordonnées.
# PROMPT <br>def get_neighborhood_coordinates(<br>i: int, j: int, n_rows: int, n_cols: int) -> list:<br>"""<br>get_neighborhood_coordinates is used by get_neighborhood <br>to return the coordinates of the 3x3 Moore neighborhood for<br>the cell located at coordinates i,j If i,j coordinates are on<br>the edge of the grid (i.e. i or j equal 0, or i ==<br>grid.shape[0]-1 or j == grid.shape[1]), the Moore<br>Neighborhood should wrap around to include cells on the<br>opposite edge. In other words the grid can be considered to <br>be the surface of a toroid, like 'Pac-Man'<br><br>args:<br>i, int, this coordinate corresponds to the row<br>j, int, coordinate corresponding to column<br>n_rows, int, number of rows in the grid<br>n_cols, int, number of columns in the grid<br><br>returns:<br>neighborhood_coords - list of tuples, <br>each tuple contains the coordinates<br>of a cell in the Moore neighborhood<br>"""<br><br># GENERATED<br><br># initialize the output list<br>neighborhood_coords = []<br><br># get the coordinates of the Moore neighborhood<br># using the get_neighborhood_coordinates function<br>for row in range(i-1, i+2):<br>for col in range(j-1, j+2):<br># skip the center cell<br>if row == i and col == j:<br>continue<br><br># check if the cell is on the edge of the grid<br># if so, wrap around to the opposite edge<br>if row row = n_rows - 1<br>elif row == n_rows:<br>row = 0<br><br>if col col = n_cols - 1<br>elif col == n_cols:<br>col = 0<br><br># store the cell coordinates<br>neighborhood_coords.append((row, col))<br><br>return neighborhood_coords
这比我们预期的函数式编程深度要深一点(compute_neighborhood调用get_neighborhood,反过来get_neighborhood又调用get_neighborhood_coordinates),但看起来我们终于有了一组函数,可以返回一个邻居和的网格。
还剩下update函数,它对应的docstring提示如下所示:
# PROMPT<br><br>def update_grid(grid: np.array, rules: list) -> np.array:<br>"""<br>update input arg grid according the the Life-like rules<br>contained in input arg rules. rules is a list of lists, <br>with the first element containing a list of 'birth'<br>conditions (cells go from 0 -> 1) and the second element<br>containing a list of 'survival' conditions (cells are<br>unchanged).<br>Cells which have a neighborhood sum that is not in the<br>'birth' (B) or 'survival' (S) rules go to 0. <br><br>This functions uses function compute_neighborhood to compute <br>the neighborhood value for each cell in grid.<br><br>args:<br>grid, np.array. grid contains the cell values (0 or 1)<br> rules, list of lists. rules contains the B/S rules <br> for Life-like cellular automatafor example, to<br> simulate Conway's Life CA, `rules = [[3], [2,3]]`,<br> i.e. B3/S23 Life Without Death has rules<br> B3/S012345678, so `rules = [[3],<br> [0,1,2,3,4,5,6,7,8]]`<br><br>update_grid should raise an Exception if rules contains <br>values greater than 8 (maximum number of live cells in a<br>Moore neighborhood) or less than 0. <br>"""<br><br># GENERATED<br><br># get the dimensions of the grid<br>n_rows, n_cols = grid.shape<br><br># get the neighborhood grid<br>neighborhood_grid = compute_neighborhood(grid)<br><br># loop over the grid<br>for i in range(n_rows):<br>for j in range(n_cols):<br># get the current cell value<br>cell_val = grid[i, j]<br><br># get the neighborhood value for the current cell<br>neighborhood_val = neighborhood_grid[i, j]<br><br># check if the cell is alive<br>if cell_val == 1:<br># check if the cell should die<br>if neighborhood_val not in rules[1]:<br>grid[i, j] = 0<br>else:<br># check if the cell should be born<br>if neighborhood_val in rules[0]:<br>grid[i, j] = 1<br><br>return grid
这看起来是解决上面问题的一种非常合理的方法;尽管我们确实明确建议,如果邻居网格包含错误的值并且在生成的输出中找不到,就会引发异常。
只需进行一些修复:在函数get_neighborhood中进行手动干预,并且尝试给出一些提示,我们就可以成功地设计出一个完全可行的类似生命的细胞自动机模拟器。
上面的代码不是一个特别快的实现方案,但它的质量与程序员在开始使用一种新语言时可能做出的那种“Hello World”尝试相似。值得注意的是,在训练数据集中包含了许多示例,供研究者参考。
在康威的《生命游戏》中,我们可以想象这段程序在微型滑翔机的发展过程中取得的成功。
虽然我们确实通过一组函数完成了CA模拟器的编写,但这种方法对于日常软件工程来说并不是非常有用或现实的开发方式。但另一方面,这并不能阻止像SourceAI这样的初创公司(本质上是OpenAI Codex API的包装商)将其服务宣传为“给每个人创造有价值的定制软件的机会”。
“我们构建了一个独立的系统,可以开发出世界上最熟练的工程师级别的软件。”不过,与Codex交互的确是学习或实践编程的一种潜在有用的方式,尤其是针对CodeSignal、CodeForces或HackerRank等网站的编程问题方面。
接下来,我们将尝试评估Codex/Copilot,以获得自动编写测试和docstring的更现实的使用情形。
对于本例来说,我们选择使用VSCode开发工具的GitHub Copilot扩展来编写测试。
# PROMPT (in VSCode)<br>import numpy as np<br>def pythagorean(a: np.float, b: np.float) -> np.float:<br>"""<br>Use the Pythagorean theorem to comput the hypotenuse for<br>a triangle with side lengths a and b<br><br>args:<br>a, np.float, side of the triangle<br>b, np.float, the other side of the triangle<br><br>returns:<br>c, np.float, the length of the hypotenuse<br>"""<br>c = np.sqrt(a**2 + b**2)<br>return c<br><br>def test_pythagorean():<br><br># GENERATED (Copilot autocomplete)<br>"""<br>Test the pythagorean function<br>"""<br>a = np.array([3, 4, 5])<br>b = np.array([4, 5, 6])<br>c = pythagorean(a, b)<br><br>assert np.allclose(c, np.sqrt(a**2 + b**2))
虽然毕达哥拉斯定理函数可能过于简单,但Copilot建议进行一次合理的测试。如果您运行它,它就会通过。你会注意到,自动完成建议能够正确地获得测试的结构和数字内容。
如果我们想使用自己喜欢的框架以更系统的方式编写测试,该怎么办?不用太担心,因为我们已经使用numpy库和自动微分技术编写了大量的低级学习模型,供给测试者使用。因此,虽然接下来的这个示例不是100%真实地来自真实世界,但效果还是比较贴近真实情况的。
在本例中,我们将使用autograd和numpy以及unittest中的TestCase类设置一个简单的多层感知器前向传递、损失函数和梯度函数进行测试。
#PROMPT<br>import unittest<br>from autograd import numpy as np<br>from autograd import grad<br><br>def forward_mlp(input_x: np.array, <br>weights: list, biases: list) -> np.array:<br>"""<br>compute the forward pass of a multilayer perceptron. <br>The number of layers is equal to the length of the list of<br>weights, which must be the same as the list of biases,<br>biases. <br><br>args:<br>input_x, np.array, input data<br>weights, list of np.arrays, a list of np.array matrices,<br> representing the weights<br>biases: list of np.arrays, a list of biases for each<br> layer<br><br>returns:<br>result, np.array, the output of the network<br>"""<br><br>assert len(weights) == len(biases)<br><br>for layer_index in range(len(weights) - 1):<br>input_x = np.tanh(np.matmul(input_x,<br>weights[layer_index]) + biases[layer_index])<br><br>output = np.matmul(input_x, weights[-1]) + biases[-1]<br>return output<br>def get_loss(input_x: np.array, weights: list, <br>biases: list, target: np.array) -> np.float:<br>"""<br>compute the mean squared error loss for an mlp with weights<br>and biases, with respect to the input data input_x and the<br>target array target.<br><br>args:<br>input_x, np.array, input data<br>weights, list of np.arrays, a list of np.array matrices,<br>representing the weights<br>biases: list of np.arrays, a list of biases for each<br>layer<br>target: np.array, the target values<br><br>returns:<br>loss, np.float, the loss<br>"""<br><br>output = forward_mlp(input_x, weights, biases)<br><br>return np.mean((output - target)**2)<br><br>get_loss_grad = grad(get_loss, argnum=(1,2))<br><br><br>class TestMLP(unittest.TestCase):<br>"""<br>tests for MLP, get_loss, and get_grad_loss<br>"""<br># GENERATED (chosen from Copilot suggestions)<br>def setUp(self):<br>pass<br><br>def test_forward_mlp(self):<br>"""<br>test forward_mlp<br>"""<br><br>input_x = np.array([[1, 2, 3], [4, 5, 6]])<br>weights = [np.array([[1, 2], [3, 4]]), <br>np.array([[5, 6], [7, 8]]), <br>np.array([[9, 10], [11, 12]])]<br>biases = [np.array([[1, 2]]), np.array([[3, 4]]),<br>np.array([[5, 6]])]<br><br>output = forward_mlp(input_x, weights, biases)<br>self.assertTrue(np.allclose(output, <br>np.array([[-0.9, -0.9], [-0.9, -0.9]])))<br><br>def test_get_loss(self):<br>"""<br>test get_loss<br>"""<br>input_x = np.array([[1, 2, 3], [4, 5, 6]])<br>weights = [np.array([[1, 2], [3, 4]]), <br>np.array([[5, 6], [7, 8]]), <br>np.array([[9, 10], [11, 12]])]<br>biases = [np.array([[1, 2]]), np.array([[3, 4]]),<br>np.array([[5, 6]])]<br>target = np.array([[1, 1], [1, 1]])<br><br>loss = get_loss(input_x, weights, biases, target)<br><br>self.assertTrue(np.allclose(loss, 0.5))<br><br>def test_get_loss_grad(self):<br>"""<br>test get_loss_grad<br>"""<br><br>input_x = np.array([[1, 2, 3], [4, 5, 6]])<br>weights = [np.array([[1, 2], [3, 4]]), <br>np.array([[5, 6], [7, 8]]), <br>np.array([[9, 10], [11, 12]])]<br>biases = [np.array([[1, 2]]), np.array([[3, 4]]), <br>np.array([[5, 6]])]<br>target = np.array([[1, 1], [1, 1]])<br><br>loss_grad = get_loss_grad(<br>input_x, weights, biases, target)<br><br>self.assertTrue(<br>np.allclose(loss_grad[0], <br>np.array([[-0.9, -0.9], [-0.9, -0.9]])))<br>self.assertTrue(<br>np.allclose(loss_grad[1], <br>np.array([[-0.9, -0.9], [-0.9, -0.9]])))<br>self.assertTrue(<br>np.allclose(loss_grad[2],<br>np.array([[-0.9, -0.9], [-0.9, -0.9]])))<br><br># END GENERATED (the final two lines are part of the prompt)<br>if __name__ == "__main__":<br>unittest.main(verbosity=1)
Copilot的建议虽然并不完美,但确实为测试类提供了合理的思路。不过,如果您尝试原封不动地运行代码的话,则不会执行任何测试,更不用说通过测试了。
输入数据和第一个权重矩阵之间存在维度不匹配,数据类型也是错误的(所有数组都是整数数据类型),而且无法使用Autograd梯度函数。
当然,上面这些问题并不是很难解决,如果用3x2矩阵替换权重矩阵列表中的第一个条目,那么前向传播应该可以运行。要使得梯度计算测试顺利进行,或者需要在np.array定义的数字上添加小数点,或者显式定义数组数据类型。
有了这些更改后,测试即可成功执行并失败,但预期值在数字表现方面还不正确。
Copilot有很大潜力的一项任务是自动编写文档,特别是为已经编写的函数填写docstring内容。这方面几乎是比较实用了。
对于毕达哥拉斯定理的示例程序,Copilot运行结果已经非常接近,但它将问题描述为查找两点a和b之间的距离,而不是查找边长c到边长a和边长b的距离。不出所料,随同Copilot一同发行的docstring中的示例也与函数的实际内容不匹配:返回的是一个标量,而不是c的值数组。
Copilot对前向MLP函数的docstrings的建议也很接近,但并不完全正确。
Copilot支持的自动Docstring建议
对于软件工程师来说,程序合成方面的每一项新进展都可能引发一次经济恐慌。
Après tout, si les programmes informatiques peuvent programmer des ordinateurs tout comme les programmeurs, cela ne signifie-t-il pas que les machines devraient « prendre nos emplois » ? Est-ce que ce sera le cas dans un futur proche ?
En apparence, la réponse semble être « pas encore » ; cependant, cela ne signifie pas que la nature du génie logiciel est susceptible de rester la même à mesure que ces outils deviennent plus matures. À l’avenir, l’utilisation d’outils d’auto-complétion sophistiqués pour un raisonnement réussi pourrait s’avérer aussi importante que l’utilisation d’outils de formatage de code.
Copilot est actuellement en version bêta et le nombre d'options pour l'utiliser est limité. De même, Codex dispose également d'une API disponible en version bêta via OpenAI. Les conditions d'utilisation du programme pilote et les considérations en matière de confidentialité limitent les cas d'utilisation potentiels de la technologie.
Conformément à la politique de confidentialité actuelle, tout code saisi dans ces systèmes peut être utilisé pour affiner les modèles et peut être examiné par le personnel de GitHub/Microsoft ou d'OpenAI. Cela exclut la possibilité d’utiliser Codex ou Copilot dans des projets sensibles.
Copilot ajoute de nombreux utilitaires au modèle Codex sur lequel il est basé. Vous pouvez écrire un squelette ou un plan pour le code souhaité (comme écrire un exemple pour un test du framework unittest) et déplacer le curseur au milieu du plan pour obtenir des suggestions de saisie semi-automatique OK judicieuses.
Actuellement, il est peu probable que Copilot suggère un code complet correct pour un problème plus complexe que de simples pratiques de codage, mais il peut généralement créer un aperçu raisonnable et économiser une saisie manuelle ;
Il convient également de noter que Copilot fonctionne dans le cloud. Cela signifie qu'il ne fonctionne pas hors ligne et que les suggestions de saisie semi-automatique sont un peu lentes. À ce stade, vous pouvez parcourir les suggestions en appuyant sur Alt+], mais parfois il n'y a que quelques suggestions parmi lesquelles choisir, voire une seule parmi lesquelles choisir.
Quand Copilot fonctionne bien, c'est en fait assez bon pour être un peu dangereux. Les tests suggérés dans l'exemple de test unitaire et la docstring suggérée pour la fonction pythagoricienne semblent corrects à première vue et passeront probablement l'examen minutieux d'un ingénieur logiciel blasé. Mais lorsqu’ils contiennent des erreurs mystérieuses, cela ne mène qu’à des souffrances plus tard !
Pour résumer, même si Copilot/Codex est plutôt un jouet ou un outil d’apprentissage dans son état actuel, c’est incroyable qu’il fonctionne réellement. Si vous rencontriez un ours qui valse, je ne pense pas que ce qui vous impressionnerait serait la façon dont il danse. De même, si vous tombez sur un outil de complétion de code intelligent, ce qui vous impressionne ne devrait pas être la perfection du code qu'il écrit.
En conclusion, avec le développement ultérieur de la technologie des modèles de programmation automatique NLP et le grand nombre d'ajustements effectués par les programmeurs humains pour utiliser les outils de complétion automatique NLP, il est probable qu'il y aura une application majeure des modèles de synthèse de programmes dans le futur proche.
Zhu Xianzhong, rédacteur en chef de la communauté 51CTO, blogueur expert 51CTO, conférencier, professeur d'informatique dans une université de Weifang et vétéran de l'industrie de la programmation indépendante. Au début, il s'est concentré sur diverses technologies Microsoft (compilé trois livres techniques liés à ASP.NET AJX et Cocos 2d-X. Au cours des dix dernières années, il s'est consacré au monde open source (familier avec les logiciels complets populaires). technologie de développement Web de pile) et découvert OneNet/AliOS+Arduino/ESP32/Raspberry Pi et d'autres technologies de développement IoT et Scala+Hadoop+Spark+Flink et d'autres technologies de développement Big Data.
Titre original : Modèles NLP pour l'écriture de code : synthèse de programme, auteur : Kevin Vu
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!