Научная статья на тему 'Об определении названия функции по абстрактному синтаксическому дереву с помощью нейронной сети'

Об определении названия функции по абстрактному синтаксическому дереву с помощью нейронной сети Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
175
40
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ЯЗЫКИ ПРОГРАММИРОВАНИЯ / СИНТАКСИЧЕСКОЕ ДЕРЕВО / АДАПТИВНЫЙ АЛГОРИТМ / НЕЙРОННАЯ СЕТЬ / СЛОВАРЬ ТОКЕНОВ / МОДЕЛЬ CNN / МОДЕЛЬ LTSN / PROGRAMMING LANGUAGES / SYNTAX TREE / ADAPTIVE ALGORITHM / NEURAL NETWORK / TOKEN DICTIONARY / CNN MODEL / LTSN MODEL

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Красновидов А.В., Логинов П.А.

Языки программирования высокого уровня всегда грамматически структурированы, поэтому алгоритмы их синтаксического анализа хорошо разработаны. В своем большинстве они относятся к классу линейных алгоритмов, что позволяет с их помощью обнаруживать большинство синтаксических ошибок за один просмотр исходного текста программы. При этом почти все ошибки гарантированно обнаруживаются. Однако существует целый ряд задач синтаксического анализа, для решения которых не существует линейных алгоритмов. К числу таких задач принадлежит обнаружение копии кода, классификация кода, определение дефектных модулей и т. п. Подобные задачи могут быть решены с помощью адаптивных алгоритмов. Показано, что наиболее подходящим средством реализации подобных алгоритмов является использование аппарата нейронных сетей. В качестве примера решена задача разработки алгоритма определения названия функции языка программирования Python по абстрактному синтаксическому дереву этой функции. Построена и обучена нейронная сеть, основанная на рекуррентных слоях.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

ABOUT DETERMINING A FUNCTION NAME BY ABSTRACT SYNTACTIC TREE USING NEURAL NETWORK

High-level programming languages always have grammatical structure, do the algorithms for their parsing are well developed. Mainly they belong to the class of linear algorithms, which allows them to detect most syntax errors in a single scan of the source code of the program. In most cases, almost all errors are guaranteed to be detected. However, there are a number of syntactic analysis task for which linear algorithms do not exist. These are kinds of tasks embrace detecting a copy of the program code, classifying the code, identifying defective modules, etc. However, like tasks can be solved using adaptive algorithms. It is shown the most suitable means of implementing such algorithms is the use of means of neural networks. The task of developing an algorithm to determine the name of a function of the Python programming language according the abstract syntax tree of this function as an example considered. A neural network based on recurrent layers was built and trained.

Текст научной работы на тему «Об определении названия функции по абстрактному синтаксическому дереву с помощью нейронной сети»

Об определении названия функции по абстрактному синтаксическому дереву с помощью нейронной сети

к.т.н. А. В. Красновидов, бакалавр П. А. Логинов Петербургский государственный университет путей сообщения Императора Александра I

Санкт-Петербург, Россия alexkrasnovidow@mail.ru

Аннотация. Языки программирования высокого уровня всегда грамматически структурированы, поэтому алгоритмы их синтаксического анализа хорошо разработаны. В своем большинстве они относятся к классу линейных алгоритмов, что позволяет с их помощью обнаруживать большинство синтаксических ошибок за один просмотр исходного текста программы. При этом почти все ошибки гарантированно обнаруживаются. Однако существует целый ряд задач синтаксического анализа, для решения которых не существует линейных алгоритмов. К числу таких задач принадлежит обнаружение копии кода, классификация кода, определение дефектных модулей и т. п. Подобные задачи могут быть решены с помощью адаптивных алгоритмов. Показано, что наиболее подходящим средством реализации подобных алгоритмов является использование аппарата нейронных сетей. В качестве примера решена задача разработки алгоритма определения названия функции языка программирования Python по абстрактному синтаксическому дереву этой функции. Построена и обучена нейронная сеть, основанная на рекуррентных слоях.

Ключевые слова: языки программирования, синтаксическое дерево, адаптивный алгоритм, нейронная сеть, словарь токенов, модель CNN, модель LTSN.

Введение

При выполнении синтаксического анализа исходных текстов программ возникает целый ряд различных задач. Их можно условно разбить на две большие группы:

1. Анализ исходного текста программы с целью выявления синтаксических и, частично, семантических ошибок во время трансляции.

2. Анализ исходного текста программы, не связанный непосредственно с его трансляцией.

Задачи, относящиеся к первой группе, опираются на представлении языков программирования как некоторых формальных систем. Синтаксис языка формируется таким образом, чтобы можно было легко проверить, является ли некоторая последовательность символов правильным предложением языка. Благодаря хорошей структурированности подавляющего большинства современных языков высокого уровня для решения такой задачи возможно и целесообразно использовать линейные алгоритмы.

Ко второй группе можно отнести следующие задачи:

• Обнаружение копии кода. В больших проектах используется при рецензировании кода для обнаружения одинаковых методов. Один из них может быть удален, тогда оставшийся использовать повторно.

• Классификация кода. Может классифицировать код по задаче, которую он решает. Классификация позволит определить тип изменения и не выполнять просмотр незначительных изменений программного кода.

• Определение программных модулей, подверженных дефектам и требующих тщательного тестирования [1];

• Генерация словесного описания кода. Может быть использована для автоматического документирования программного кода. [2];

• Локализация ошибок.

Эти задачи решаются не во время компиляции или интерпретации программы, а в процессе выполнения специализированной обработки текстов программ. Особенностью таких задач является то, что они не требуют абсолютной точности решения. Для решения подобных задач не существует линейных алгоритмов, однако они могут быть решены с помощью адаптивных алгоритмов. Такие алгоритмы могут быть реализованы с помощью аппарата нейронных сетей. В настоящей статье рассматривается задача определения названия функции по ее абстрактному синтаксическому дереву. Обычно название функции в той или иной степени отражает ее назначение. Например, функция sin выполняет вычисление тригонометрической функции. Название функции может состоять из нескольких слов. Например, функция button1_Click языка C# обрабатывает событие нажатие кнопки № 1. Однако разработчики программного обеспечения часто присваивают функциям имена, не отражающие назначение функции. Присваивать функциям правильные названия особенно важно при выпуске программной документации [3]. Кроме того, решение этой задачи поможет реализовать плагин для подсказки правильного названия функции, например при вводе или редактировании исходного текста программы.

Абстрактное синтаксическое дерево программы

В процессе обработки исходного текста программы выполняются ее лексический и синтаксический анализы. На этапе лексического анализа входная строка из последовательности символов переводится в последовательность лексем (токенов) следующим образом: строка исходного текста position = position + rate * 60 после лексического анализа преобразуется в строку

<id><=><id><+><id><*><num><;> (*)

Суть лексического анализа заключается в выделении из последовательности символов входной последовательности лексем (токенов), неделимых с точки зрения последующего анализа. Токены делятся на классы [4].

Синтаксический анализ — это процесс сопоставления последовательности входных лексем с правилами языка. В простейшем случае синтаксический анализ позволяет определить принадлежность строки исходного текста данному языку. Однако на практике одного такого ответа (принадлежит или нет) недостаточно, и, как правило, параллельно с синтаксическим разбором происходят какие-либо действия, направленные на дальнейшее преобразование входной строки. Для выполнения дальнейшей обработки на этом этапе строится некоторое внутреннее представление программы, удобное для дальнейшего анализа и обработки. Часто в качестве такого представления используется абстрактное синтаксическое дерево (АСД [5]. Пример такого дерева для последовательности (*) показан на рисунке 1.

Рис. 1. Абстрактное синтаксическое дерево

Как можно видеть, АСД представляет собой структурное представление исходной программы, очищенное от элементов конкретного синтаксиса (в рассматриваемом примере в АСД не попал «разделитель», т. к. он не имеет отношения непосредственно к семантике данного фрагмента программы, а лишь к конкретному синтаксису языка). В качестве узлов в АСД выступают операторы, к которым присоединяются их аргументы, которые, в свою очередь, также могут быть составными узлами [4]. Узлы АСД получаются из лексем, выделенных на этапе лексического анализа. На рисунке 1 АСД построено полностью из лексем, кроме того, показано, что узлы, как и лексемы, содержат дополнительные атрибуты - имена идентификаторов, значения чисел и т. д.

Далее показано, что АСД могут быть использованы в качестве исходных данных при обучении нейронных сетей.

Векторное представление токена

Нейронная сеть принимает на вход данные в цифровом формате. Это значит, что токены (символы) перед подачей их на вход нейронной сети должны быть преобразованы в цифровой формат. Одним из часто используемых способов такого преобразования заключается в создании словаря, в котором каждый токен будет сопоставлен с числовым значением. После этого можно перевести входную последовательность токенов в цифровой формат. Однако число, которым закодирован токен, фактически является его весом. Поэтому, если токены будут пронумерованы

последовательно или в случайном порядке, то некоторые токены будут в несколько раз значимее других без каких-либо на то оснований. Такой способ приемлем, если экспериментатору известны веса токенов, и он задает их вручную. В других случаях следует воспользоваться методами подбора правильных весов.

Существует множество методов подготовки данных для обучения. Популярными в работе с текстами являются OneHotEncoding (OHE), TF-IDF (TF — termfrequency, IDF — inversedocumentfrequency) и векторное представление слов (Embedding).

TF-IDF

TF-IDF — это простой и удобный способ оценить важность токена для какой-либо последовательности относительно всех остальных последовательностей. Принцип работы метода заключается в следующем: если токен встречается в какой-либо последовательности часто, при этом встречаясь редко во всех остальных последовательностях, то такой токен имеет большую значимость для этой последовательности. Эта метрика хороша тем, что токены, не важные для вообще всех последовательностей, получат очень низкий вес TF-IDF (потому что часто встречаются во всех последовательностях), а важные — высокий. Значение TF-IDF рассчитывается для каждого токена. TF — это частота токена в последовательности, для расчета берется количество вхождений токена в последовательность и делится на длину (количество токе-нов) последовательности. IDF — обратная частота токена в последовательностях, рассчитывается следующим образом: количество всех последовательностей в коллекции делится на количество последовательностей, в которых употребляется токен. Таким образом, наибольший вес IDF будет иметь токен, который встречается только в одной последовательности. Итоговый вес токена является произведением величин TF и IDF. Данный метод подходит для решения задач классификации, поэтому он использован в рамках настоящей работы.

Решение задачи определения имени функции

по абстрактному синтаксическому дереву тела функции

Задачу определения названия функции по абстрактному синтаксическому дереву (АСД) тела этой функции логично решать при помощи классификации. Задача классификации заключается в определении по входным данным, к какому классу эти данные принадлежат. Задачи классификации с помощью нейронных сетей решаются следующим образом. Берется набор данных и размечается. Каждому примеру сопоставляют метку. В поставленной задаче примером является АСД тела функции, а метка — название этой функции. В итоге получается определенное количество уникальных меток. Каждая уникальная метка является уникальным классом, который будет определять нейронная сеть. Далее размеченный набор данных подается на вход нейронной сети. Нейронная сеть имеет свои внутренние параметры, отвечающие за определение класса (предсказание). Таким образом, нейронная сеть анализирует данные и пытается предсказать, к какому классу они относятся. Каждый раз, когда нейронная сеть ошибается, она корректирует свои внутренние параметры, чтобы улучшить качество предсказания. В задаче определения названия функции по абстрактному синтаксическому де-

реву тела этой функции данными являются АСД тела функций, а метками — названия функций. В результате подачи АСД тела функции на вход нейронной сети, она выдает вероятностное распределение между классами (массив значений вероятностей). Выбирается класс с наибольшей вероятностью.

Перед обучением нейронной сети необходимо собрать данные для обучения, обработать их и построить модель.

Данные для обучения В качестве примера в рамках настоящей статьи рассматривается задача определения названия функции языка

Python. Данные для обучения были взяты из набора данных «PythonASTs», включающего в себя более 150 тысяч функций, написанных на языке Python. Каждая программа преобразована в последовательность узлов АСД программы. К набору данных прилагается лексический анализатор, который может преобразовать исходный текст программы в последовательность узлов АСД. На рисунке 2 изображено абстрактное синтаксическое дерево следующей функции:

defsum(a, b): return a+b

Рис. 2. Абстрактное синтаксическое дерево функции на языке Python

Работа лексического анализатора заключается в следующем. Он имплементирует пакет ast стандартной библиотеки Python для преобразования исходного кода программы в абстрактное синтаксическое дерево. Далее он обходит АСД с помощью алгоритма прямого обхода дерева. Каждое посещенный узел дерева добавляется в последовательность. Каждый узел несет информацию: тип узла, дочерние узлы (если они есть), значение узла (если оно есть). Таким образом, получается последовательность

структур данных, где каждый элемент — это узел дерева. Дерево содержит узлы двух типов: терминальные и нетерминальные. Терминальные узлы имеют поле value (значение) и не имеют дочерних узлов [6]. Структура начала последовательности приведена на рисунке 3.

В итоге прямого обхода получается последовательность просмотренных узлов дерева в порядке их просмотра.

Рис. 3. Структура данных набора «PythonASTs»

Формирование словаря функций Модель нейронной сети в процессе работы решает задачу классификации: по АСД функции, модель относит эту функцию к одному из классов. Классами в данном

случае являются названия функций. Чтобы нейронная сеть смогла справиться с задачей классификации, необходимо производить обучение с большим количеством примеров для каждого класса. Если количество примеров какой-

нибудь функции недостаточно, то нейронная сеть не сможет запомнить зависимости, характерные для данной функции, и примеры этой функции будут классифицированы некорректно.

Первый шаг в формировании такого словаря заключается в подсчете для каждого названия функции количества примеров названия этой функции, содержащихся в данных (в метках, а не узлах). После этого получается большой словарь, который содержит все уникальные функции из данных.

Второй шаг заключается в выборе порога вхождения функции в словарь по количеству примеров этой функции. Все функции, которые ниже этого порога, отсекаются и не будут участвовать в обучении и тестах. Этот порог определяет качество и актуальность будущей модели. Если порог будет выбран очень большой, то получится мало различных функций, и модель будет классифицировать между маленьким количеством классов. Такая модель будет бесполезна. Если же выбрать маленький порог, то получится большое количество классов. У многих классов будет маленькое количество обучающих примеров, что негативно скажется на качестве модели. Выбор порога определяется размером набора данных, чем больше примеров функций с одинаковым названием, тем больше можно выбрать порог. С этим значением можно экспериментировать в небольшом диапазоне, подбирая оптимальное значение. Для набора данных «PythonASTs» выбран порог со значением 300. То есть функции, которые имеют менее 300 примеров, будут исключены из выборки. В результате отбора останется примерно 111 уникальных функций (111 классов).

Третий шаг заключается в исключении функций, которые сложно классифицировать. Существует ряд функций, структура которых во многих программах отличается. Например, если посмотреть на коды функций «setter», то все они очень похожи, поэтому их легко классифицировать. Но если сравнивать коды функций «main» или «run», то для большинства программ они уникальны. Отсюда следует необходимость исключения подобных функций из выборки. Также исключаются некоторые служебные функции и функции с названиями «f», «fo», «func» и т. д.

На четвертом шаге производится объединение в один класс некоторых классов. Некоторые названия функций в выборке одинаковы по смыслу, но имеют различные имена. Например, функции с именами «representation» и «string» выполняют одинаковую задачу, поэтому могут быть объединены в один класс «to_string». Также на этом шаге названия приводятся к нижнему регистру. Такие функции, как «setup» и «setUp» становятся одним классом.

После выполнения всех шагов получается словарь названий функций, которые будут учувствовать в обучении. По этому словарю производится фильтрация всех функций. В выборке остаются только те функции, название которых присутствуют в словаре.

Формирование словаря значений

Многие узлы АСД имеют собственное значение. Значение может многое сказать о функции. Например, если в функцию передается аргумент с именем «file_name», а в самой функции используются методы «open», «readline», то векторное представление АСД функции с таким набо-

ром токенов можно классифицировать намного точнее, чем если бы эти данные были неизвестны. Значениями являются константы, имена идентификаторов, строки (комментарии). Они дают дополнительную важную информацию, но так как существует огромное количество уникальных значений, целесообразно иметь возможность использования только части значений. Для этого необходимо произвести отбор тех значений, которые будут использоваться в качестве токенов в векторном представлении функций. Для отбора значений формируется словарь уникальных значений со счетчиком для каждого значения, чтобы определить его частоту (по аналогии со словарем названий функций). Словарь необходимо отсортировать в порядке убывания. Наиболее часто встречающиеся значения оказываются в начале словаря. Однако значительное количество часто встречающихся значений являются нейтральными и не оказывают значительного влияния на принятие решения. Таким образом, для завершения формирования словаря необходимо его укоротить.

Эта задача решается экспериментальным методом. Необходимо обучить модель с разным размером словаря, причем менять размер при экспериментах можно с большим разбросом [7].

Фильтрация данных

На предыдущих этапах был сформирован набор данных, который состоит из метки (названия функции) и векторного представления АСД этой функции. Каждый узел АСД хранит информацию о типе узла и значении узла (если есть).

После формирования набора данных необходимо преобразовать узлы функций путем выбора для каждого узла одного из двух возможных вариантов: использовать в качестве токена тип узла или значение узла.

Выбор производится при помощи сформированного словаря значений. Процесс выбора следующий: последовательно просматриваются все узлы всех функций и в каждом узле проверяется, есть ли у узла значение. Если его нет, то в качестве токена выбирается тип узла, если оно есть, то проверяется, входит ли значение в словарь значений: если да, то выбирается значение узла, если нет — то тип узла.

Последним шагом подготовки данных является удаление первого элемента векторов токенов, который несет информацию о названии функции. После этого имеется набор данных, имеющий следующую структуру: метка (название функции/класс) и сопоставленный с ней вектор токенов.

Архитектура нейронной сети

Архитектура нейронной сети определяет, из каких слоев состоит модель, и то, как эти слои соединены между собой. В настоящей работе используется последовательная архитектура модели. Это значит, что слои расположены друг за другом.

В данном случае модель нейронной сети решает задачу классификации. На ее вход поступает последовательность токенов, на выходе модели получается вероятностное распределение классов, где каждый класс является названием функции. таким образом, нейронная сеть определяет, с какой вероятностью последовательность токенов относится к каждому из классов.

В качестве данных для обучения используются последовательности токенов, где важен порядок токенов, и то-кены имеют зависимости. Использование представления последовательностей токенов в виде разреженного вектора в данной задаче неэффективно, так как токены имеют зависимости. Поэтому для решения этой задачи больше подходят рекуррентные нейронные сети или сверточные нейронные сети, потому что они учитывают связи между токенами.

Первым слоем выбран Embedding, потому что он работает с последовательностями, нормализует данные и подходит и для рекуррентных и для сверточных сетей.

Последний слой — полносвязный слой, у которого количество нейронов равно количеству определяемых классов (названий функций). На выходе этого слоя выдается вектор распределения вероятностей каждого класса. Общая архитектура модели нейронной сети для решения рассматриваемой задачи представлена на рисунке 4.

Рис. 4. Общая архитектура модели нейронной сети

Подготовка наборов данных Исходный набор данных «PythonASTs» был обработан несколько раз с различными параметрами. В результате получено несколько наборов данных для обучения, которые приведены в таблице 1.

Таблица 1

Сформированные наборы данных для обучения

Размер Порог Число Число

словаря вхождения функций классов

токенов функции в выборку для обучения

15 000 300 130 300 114

15 000 190 146 540 203

9 000 300 128 898 111

9 000 190 155 470 203

2 000 300 128 898 111

2 000 190 155 470 203

Так как модель нейронной сети предполагает, что первый слой - это слой Embedding, то последовательности токенов должны быть преобразованы в вектора чисел одинаковой длины. Поэтому необходимо выбрать оптимальную длину последовательностей. Сделать это можно

экспериментально, пробуя разные длины. Начать можно со значений, близких к средней длине последовательности.

После выбора длины последовательности необходимо привести вектора к одной длине. Последовательность обрезается, если она длиннее выбранного числа, и дополняется нулями, если короче, чем выбранное число. Причем нули добавляются в начале последовательности, так как при использовании рекуррентных сетей там теряется меньше информации [8, 9].

Далее подготавливаются метки, с которыми сверяется модель при обучении. Каждая метка сопоставлена с одной последовательностью. Метка несет информацию о названии функции.

Распределение вероятностей каждой метки происходит на последнем полносвязном слое модели. Количество нейронов этого слоя равно количеству классов. Выходом этого слоя является вектор со значением вероятности для каждой метки.

Все этапы подготовки данных для обучения были произведены с помощью языка программирования Python в среде Google Colab. В подготовке данных были использованы стандартные библиотеки Python 3 и возможности

Python 2. Следует отметить, что на этапах обработки и подготовки данных к обучению всегда использовалась пара наборов. Один набор является обучающим, второй — тестовым. Такое деление наборов необходимо для проверки того, как нейронная сеть справляется с примерами, которые она не наблюдала при обучении, так как нейронная сеть имеет свойство переобучаться и выдавать результат лучше на тех данных, на которых она учится.

Экспериментальный подбор архитектуры модели

Так как архитектура модели определяется большим количеством параметров, то имеется возможность построить множество разных моделей, решающих одну и ту же задачу, а затем выбрать ту, которая наилучшим способом справляется с решением поставленной задачи.

Для разрабатываемой модели ранее были определены первый и последний слои. Первый слой является слоем Embedding, а последний слой — полносвязный.

Построение моделей выполнялось при помощи языка Python. Для этого были использованы две популярные

библиотеки для работы с нейронными сетями: библиотека TensorFlow и библиотека Keras (является надстройкой над TensorFlow и еще несколькими библиотеками) [10].

Точность работы модели определяется по тому, правильно ли она определяет метки примеров тестовой выборки, то есть тех примеров, которых нейронная сеть не видела при обучении. Точность модели показывает, с какой вероятностью модель определяет правильную метку для примера данных. Именно такая точность является качественным показателем модели: чем больше эта точность, тем модель лучше.

Первая модель была построена на основе сверточных слоев. Эта модель имеет аббревиатуру CNN (Convolution Neural Network). Помимо входного, выходного и сверточ-ных слоев в модели присутствуют слои пулинга и слой прореживания. В библиотеке Keras сверточный слой называется ConvlD, полносвязный — Dense, а прореживание — Dropout. Структурная схема модели представлена на рисунке 5.

Рис. 5. Структурная схема модели CNN

На этой модели были опробованы различные наборы подготовленных данных. Обучение заканчивается, когда модель долгое время не улучшается или происходит большое переобучение. Результаты обучения приведены в таблице 2.

Таблица 2

Результаты обучения модели CNN

Таблица 3

Лучший результат модели CNN

№ Набор данных (словарь-порог-количество классов) Длина последовательности Число эпох Точность, %

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

1 2000-190-203 300 45 70,33

2 2000-300-111 300 25 73,53

3 9000-190-203 300 30 70,62

4 9000-300-111 300 30 75,14

5 15000-300-203 300 30 69,51

6 15000-300-114 300 40 75,00

7 9000-300-111 50 30 74,13

8 9000-300-111 150 30 75,07

9 9000-300-111 500 30 75,1

Размер словаря токенов 9 000

Число классов 111

Длина последовательности 300

Число эпох на обучение 30

Время обучения 14 минут 45 секунд

Размер модели 9,85 МБ

Точность классификации 75,14 %

Выполненные эксперименты с этой моделью показали, что ее переобучение происходит быстро, что демонстрирует рисунок 6.

Из анализа таблицы 2 видно, что модель выдает лучшую точность на наборе данных 9000-300-111. Поэтому дальнейшие эксперименты производились именно с этим набором. В таблице 3 приведены параметры лучшего результата работы модели.

Вторая модель построена на основе LSTM (Long Short Term Метогу)-слоев. Модели LSTM являются модификацией рекуррентных слоев [11]. Нейрон LSTM имеет более сложную структуру, которая лучше справляется с затуханием информации при обработке длинных последовательностей. Модель обучается на лучшем наборе по результатам работы первой модели, что дает возможность сравнить точность двух моделей.

Структура модели приведена на рисунке 7. Результаты обучения приведены в таблице 4. Результаты сравнения работы моделей приведены в таблице 5.

Таблица 4

Результаты обучения модели LSTM

Набор данных (словарь-порог-количество классов) Длина последовательности Число эпох Точность, %

9 000-300-111 300 89 77,8

0.9

0.8

ш

f

I ™

Q. ■I.1 □J

or s

0.6

м: О.Ё

04

Доля верных ответов на обучающем наборе Доля верных ответов на проверочном наборе

10 15

Эпока обучении

20

25

30

Рис. 6. График обучения модели CNN

Рис. 7. Структурная схема модели LSTM Таблица 5

Сравнение обученных моделей

CNN LSTM

Точность 75,14 % 77,8 %

Время обучения 14 минут 45 секунд 3 часа 12 минут 50 секунд

Размер модели 9,85 МБ 6,00 МБ

Реальные примеры Хорошо Очень хорошо

Приведенные в таблице результаты сравнения обученных моделей позволяют сделать вывод о предпочтительности использования модели LSTM.

Апробация результатов Апробация производилась на модели, основой которой являются рекуррентные слои (LSTM). Данными для обучения модели является набор данных «PythonASTs», который состоит из готовых абстрактных синтаксических деревьев программ. Деревья преобразованы в последовательности узлов этих деревьев. По последовательности

def f (self):

out = ""

for item in self.params: out += = %s\nrt % out += n\nn return out

узлов человеку сложно определить, что делает функция. Поэтому для проверки качества набора данных и обучения модели, производится проверка работы модели на примерах функций, взятых не из набора «РуШопАЗТБ». Примеры функций, на которых выполнялась проверка, взяты из некоторых открытых проектов, размещенных на GitHub — крупнейшем веб-сервисе для поддержки 1Т-проектов и их совместной разработки. Для проверки взято несколько примеров функций, которые умеет распознавать модель. С помощью предоставленного парсера, составителями набора «PythonASTs», исходные коды примеров функций преобразованы к такому же виду, как и в наборе, только теперь имеется исходный код функции.

Пример 1. Функция называется to_string. Такое название функции имеется в словаре классов модели. Результат определения имени функции показан на рисунке 8.

В левой части рисунка 8 приведен код функции to_string. В ней производится аккумуляция ключей и значений объекта рагат в строку, и эта строка передается на выходе из функции. Модель с очень высокой точностью определяет правильное название функции.

(item, self.params[item])

55 67%

0 15% 11 1 1 Ш illfo

0 12% ....... Ш show

0% ....... 11 qetstate

0% L 1 1 ] 1 1 1 ш SpecificCodeCPP

Рис. 8. Результат определения имени функции tostring

Intellectual Technologies on Transport. 2020. No 2

Пример 2. Функция называется test_module. Такого названия функции нет в словаре модели, поэтому ожидается увидеть похожее название. Результат определения имени функции test_module показан на рисунке 9.

Ключевым словом языка Python для проверки значений является assert. В функции (рис. 9) при помощи этого слова тестируются некоторые значения. Модель подбирает правильное название функции, а также выдает несколько семантически связанных названий.

Пример 3. Функция называется login_user. На рисунке 10 приведена функция авторизации пользователя на сайте. Оригинального названия в модели нет, но она определяет назначение функции верно.

Таким образом, в результате апробации было выяснено, что модель работает правильно на реальных примерах. Отсюда следует, что данные для обучения были корректными, и модель обучена правильно.

def f (self) ;

assert modlevel[0] == 42

assert not hasattr(test modlevel, 'answer1)

35. 95% LLLJ.I 111 Li test simple

34 .3% LLU.I 111 Li test

24. 57% tahkLL III U tear [town

5. 11% hllll 111 Li check.

0. n?% ..... 111 Li setup

Рис. 9. Результат определения имени функции testmodule

def f(request):

if request.user.is_authenticated{):

return redirect!'index'} elif request.POST:

username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password)

if user is not None:

if user.is_active:

login(request, user) return redirect('index1)

else:

return render(request,

'login/login,html'f('error'

98.78% и^ш login

1.19% ........... register

0. 03% ........... index

0% ........... reset

0% ........... create

Рис. 10. Результат определения имени функции loginuser

Заключение

В статье решена задача определения названия функции по абстрактному синтаксическому дереву ее тела. В качестве языка программирования рассмотрен набирающий все большую популярность язык Python. Для решения этой задачи построены несколько вариантов глубоких нейронных сетей, две лучшие выбраны для экспериментирования. Точнее всего справилась модель нейронной сети, основанная на рекуррентных слоях. Эта модель правильно определяет название функции, которая не участвовала в обучении, с вероятностью 98,8 %. Однако она обучается дольше, чем модель, основанная на сверточных слоях. Реализованная модель нейронной сети может выдавать лучшие результаты, если использовать больший набор данных и лучше обработать данные для обучения. В статье был использован набор данных, имеющий длину 300. При работе с ним модель показала наилучший результат, что согласуется с результатом, полученным в [12]. Одно из главных преимуществ модели в том, что она быстро обучается. И она не привязана к конкретному языку про-

граммирования: можно определять названия функций других языков, если обучить модель на абстрактных синтаксических деревьях этих языков. После улучшения модели путем коррекции параметров и использования большего набора данных ее можно использовать в областях суммаризации программного кода, машинного обучения, коррекции кода.

Литература

1. A Suitable AST Node Granularity and Multi-Kernel Transfer Convolutional Neural Network for Cross-Project Defect Prediction / J. Deng, L. Lu, S. Qui, Y. Ou. // IEEE Access. 2020. Vol. 8. Pp. 66647-66661.

DOI: 10.1109/Access.2020.2985780.

2. code2seq: Generating Sequences from Structured Representations of Code / U. Alon, O. Levy, S. Brody, E. Yahav // Proceeding of Seventh International Conference on Learning Representations (ICLR'2019), (New Orlean, May 6-9, 2019) / ArXiv. 2019. Vol. abs/1808.01400. 22 p.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

3. code2vec: Learning Distributed Representations of Code / U. Alon, M. Zilberstein, O. Levy, E. Yahav // Proceedings of the ACM on Programming Languages. Article 40 (January 2019). 29 p. DOI: 10.1145/3290353.

4. Опалева Э. А. Языки программирования и методы трансляции: Учебное пособие / Э. А. Опалева, В. П. Са-мойленко. — СПб.: БХВ-Петербург, 2005. — 480 с.

5. A Novel Neural Source Code Representation Based on Abstract Syntax Tree / J. Zhang, X. Wang, H. Zhang, et al. // Proceedings of IEEE/ACM 41st International Conference on Software Engineering (ICSE'2019), (Montreal, Canada, May 25-31, 2019). — Pp. 783-794.

DOI: 10.1109/ICSE.2019.00086.

6. Transfer Convolutional Neural Network for Cross-Project Defect Prediction / S. Qiu, X. Hu, J. Deng, et al. // Applied Science. 2019. Vol. 9, No. 13. Article 2660. 17 p. DOI: 10.3390/App9132660.

7. Николенко С. Глубокое обучение. Погружение в мир нейронных сетей / С. Николенко, А. Кадурин, Е. Ар-

хангельская. — СПб.: Питер, 2018. — 480 с. — (Библиотека программиста).

8. Moolayil J. Learn Keras for Deep Neural Networks: A FastTrack Approach to Modern Deep Learning with Python. — Apress, 2019. — 197 p.

9. Методы и модели исследования сложных систем и обработки больших данных: Монография / И. Ю. Парамонов, В. А. Смагин, Н. Е. Косых, А. Д. Хомоненко; под ред. В. А. Смагина, А. Д. Хомоненко. — СПб.: Лань, 2020. — 236 с. — (Учебники для вузов. Специальная литература).

10. Python Deep Learning: Exploring deep learning techniques and neural network architectures with PyTorch, Keras, and TensorFlow / I. Vasilev, D. Slater, G. Spacagna, et al. — Second Edition. — Packt Publishing, 2019. — 386 p.

11. Aggarwal C. C. Neural Networks and Deep Learning: A Textbook. — Springer International Publishing, 2018. — 520 p.

12. Алексеев А. С. Распознавание зашумленных текстовых символов с помощью обучаемой нейронной сети / А. С. Алексеев, А. В. Красновидов // Интеллектуальные технологии на транспорте. 2018. № 2 (14). С. 28-33.

About Determining a Function Name by Abstract Syntactic Tree Using Neural Network

PhD A. V. Krasnovidov, Bachelor P. A. Loginov Emperor Alexander I Petersburg State Transport University Saint Petersburg, Russia alexkrasnovidow@mail.ru

Abstract. High-level programming languages always have grammatical structure, do the algorithms for their parsing are well developed. Mainly they belong to the class of linear algorithms, which allows them to detect most syntax errors in a single scan of the source code of the program. In most cases, almost all errors are guaranteed to be detected. However, there are a number of syntactic analysis task for which linear algorithms do not exist. These are kinds of tasks embrace detecting a copy of the program code, classifying the code, identifying defective modules, etc. However, like tasks can be solved using adaptive algorithms. It is shown the most suitable means of implementing such algorithms is the use of means of neural networks. The task of developing an algorithm to determine the name of a function of the Python programming language according the abstract syntax tree of this function as an example considered. A neural network based on recurrent layers was built and trained.

Keywords: programming languages, syntax tree, adaptive algorithm, neural network, token dictionary, CNN model, LTSN model.

References

1. Deng J., Lu L., Qui S., Ou Y. A Suitable AST Node Granularity and Multi-Kernel Transfer Convolutional Neural Network for Cross-Project Defect Prediction, IEEE Access, 2020, Vol. 8, Pp. 66647-66661.

DOI: 10.1109/Access.2020.2985780.

2. Alon U., Levy O., Brody S., Yahav E. code2seq: Generating Sequences from Structured Representations of Code, Proceeding of Seventh International Conference on Learning Representations (ICLRS2019), New Orlean, May 6-9, 2019. ArXiv, 2019, Vol. abs/1808.01400, 22 p.

3. Alon U., Zilberstein M., Levy O., Yahav E. code2vec: Learning Distributed Representations of Code, Proceedings of the ACM on Programming Languages, Article 40 (January 2019), 29 p. DOI: 10.1145/3290353.

4. Opaleva E. A., Samoylenko V. P. Programming languages and translation methods: Study guide [Yazyki pro-grammirovaniya i metody translyatsii: Uchebnoe posobie], Saint Petersburg, BHV-Petersburg, 2005, 480 p.

5. Zhang J., Wang X., Zhang H., et al. A Novel Neural Source Code Representation Based on Abstract Syntax Tree, Proceedings of IEEE/ACM 41st International Conference on Software Engineering (ICSE'2019), Montreal, Canada, May 25-31, 2019, Pp. 783-794.

DOI: 10.1109/ICSE.2019.00086.

6. Qui S., Hu X., Deng J., et al. Transfer Convolutional Neural Network for Cross-Project Defect Prediction, Applied Science, 2019, Vol. 9, No. 13, article 2660, 17 p.

DOI: 10.3390/App9132660.

7. Nikolenko S., Kadurin A., ArkhangeFskaya E. Deep learning. Dive into the world of neural networks [Glubokoe obuchenie. Pogruzhenie v mir neyronnykh setey], Saint Petersburg, Piter Publishing House, 2018, 480 p.

8. Moolayil J. Learn Keras for Deep Neural Networks: A Fast-Track Approach to Modern Deep Learning with Python. Apress, 2019, 197 p.

9. Paramonov I. Yu., Smagin V. A., Kosykh N. Ye., Kho-monenko A. D. Methods and models for the study of complex systems and processing of big data: Monograph [Metody i modeli issledovaniya slozhnykh sistem i obrabotki bol'shikh dannykh: Monografiya], Saint Petersburg, LAN Publishing House, 2020, 236 p.

10. Vasilev I., Slater D., Spacagna G., et al. Python Deep Learning: Exploring deep learning techniques and neural network architectures with PyTorch, Keras, and TensorFlow. Second Edition. Packt Publishing, 2019, 386 p.

11. Aggarwal C. C. Neural Networks and Deep Learning: A Textbook. Springer International Publishing, 2018, 520 p.

12. Alekseev A. S., Krasnovidov A. V. Identification of Images Using Neural Network Training [Raspoznavanie zashumlennykh tekstovykh simvolov s pomoshch'yu obuchaemoy neyronnoy seti], Intellectual Technologies on Transport [Intellektual'nye tekhnologii na transporte], 2018, No. 2 (14), Pp. 28-33.

HHmmneKmyanbHbie техноnогии Ha mpaHcnopme. 2020. № 2

45

i Надоели баннеры? Вы всегда можете отключить рекламу.