<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>DeepAPI#: Синтез цепочки вызовов API CLR/С# по текстовому запросу</article-title>
      </title-group>
      <abstract>
        <p>Аннотация Разработчики часто ищут способы реализовать стандартную функциональность с помощью библиотечных функций (например, создать кнопку в UI или получить данные из формата JSON). Обычно источником такой информации является Интернет. Альтернатива - различные статистические инструменты, которые, обучившись на большом объеме кода, по текстовому запросу могут предоставлять пользователю набор вызовов функций, решающих задачу. Мы рассматриваем один из таких инструментов DeepAPI. Этот современный алгоритм основывается на глубоком обучении, и, согласно его авторам, работает лучше аналогов. Мы пытаемся воспроизвести этот результат, взяв целевым языком не Java, как оригинальный DeepAPI, а C#. В данной статье мы рассказываем о возникающих проблемах сбора данных для обучения, сложностях в построения и обучения модели, а также обсуждаем возможные модификации алгоритма.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        Последние несколько десятков лет предпринимаются
попытки анализировать исходный код для разных
целей: генерация имени метода по его телу [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ], анализ
качества кода [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ], генерация кода по текстовому
запросу [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ], [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]. Последнее особенно интересно, поскольку
позволяет разработчикам избежать долгого изучения
программных библиотек в поисках нужной
функциональности, что является значимой проблемой [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
      </p>
      <p>
        Обычно разработчики ищут способы реализовать
стандартную функциональность с помощью поисковых
движков в сети Интернет, для чего те не
оптимизированы [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. Исследователями предлагались разные замены
им, в том числе инструменты, основывающиеся на
статистическом анализе большой кодовой базы. Яркие
представители:
      </p>
      <p>
        MAPO[
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] генерирует по имени функции наиболее
релевантные шаблоны её использования;
UP-Miner [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] улучшенная версия MAPO,
достигающая лучших результатов в генерации
благодаря более сложному алгоритму;
      </p>
      <p>
        SWIM[
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] генерирует код по текстовому запросу.
      </p>
      <p>
        Одним из самых свежих алгоритмов в этой области
является DeepAPI [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ] алгоритм из статьи строит
последовательность вызовов функций по текстовому
запросу, достигая лучших результатов, чем SWIM,
за счёт использования моделей глубокого машинного
обучения из области обработки естественных языков.
Глубокое обучение успешно используется для перевода
между натуральными языками, DeepAPI пользуется
результатами последних исследований в этой области.
Задача генерации кода по тексту здесь
рассматривается как задача перевода с английского языка на язык
вызовов функций (слова в таком языке функции
языка программирования, предложения упорядоченные
наборы слов).
      </p>
      <p>
        Результаты, представленные в статье об алгоритме
DeepAPI, привлекли наше внимание, и мы решили
повторить этот опыт и расширить его. В результате
работы оригинального алгоритма DeepAPI получается
линейная последовательность вызовов функций, код
с их применением программисту приходится писать
самостоятельно. Хотелось бы облегчить ему этот этап,
предлагая не список функций, а сниппет кода то есть
отрывок кода на языке программирования, в котором
нужно модифицировать минимальное количество
деталей для того, чтобы он заработал. Для реализации
этого может оказаться полезным алгоритм T2API [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ],
который так же является достаточно свежим
исследованием возможности генерации кода по текстовому
запросу. В первой части алгоритма по текстовому запросу
выбираются некоторые релевантные элементы API, во
второй из них генерируются граф управления и
код. Теоретически, замена первой части алгоритма на
DeepAPI позволит сделать итоговые результаты более
точными, так как модель, используемая на первом
шаге T2API, более старая, а также не упорядочивает
элементы API на выходе.
      </p>
      <p>На текущий момент мы пытаемся повторить
эксперимент из статьи DeepAPI и реализовать алгоритм
из неё на базе другого языка программирования. В
оригинальной статье авторы работают с элементами
API и кодовой базой языка Java и упоминают, что
одна из угроз действительности эксперимента работа
только с одним языком. Мы желаем нивелировать эту
угрозу, а потому работаем с языком C#.</p>
      <p>
        Наш текущий вклад в исследования можно описать
следующими тезисами:
cобран набор тренировочных данных, реализован
инструментарий для сбора данных; Для увеличения точности работы алгоритма
вводитпроведено исследование использования в качестве ся еще одно улучшения новая функция потерь,
вклютренировочных данных данные, отличные от рас- чающая в себя наказание за использование чересчур
смотренных в оригинальной статье; частых элементов API. Ведь если функция часто
испостроена аппроксимация алгоритма DeepAPI; пользуется, то скорее всего, она не связана с
реализаципоставлен частично успешный первичный экспери- ей конкретной функциональности, а потому считается
мент. шумом. Оценка важности элемента API основывается
на tf–idf [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ], и выглядит так:
      </p>
      <p>
        II. DeepAPI
Модель DeepAPI основывается на современных
техниках глубокого обучения и машинного перевода.
Ключевая техника обучение Sequence-to-Sequence [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ],
суть которой по входной строке генерировать
выходную. При этом обычно первая строка принадлежит
одному естественному языку, вторая другому. В
случае DeepAPI исходный язык английский, выходной
язык элементов API.
      </p>
      <p>Техника Sequence-to-Sequence включает в себя две
рекуррентные нейронные сети (рекуррентная
нейронная сеть (RNN) один из подвидов моделей глубокого
обучения). Кодер первая из этих сетей
поэлементно считывает вход и обновляет свои параметры в
текущем скрытом состоянии. После окончания
считывания последнее состояние предполагается, что в нём
заключена суть входного предложения берётся в
качестве вектора контекста, и передаётся в качестве входа
второй RNN декодеру. Декодер на каждом шаге,
сверяясь с вектором контекста, генерирует очередной
элемент выходной последовательности, и обновляет
своё состояние. Работа декодера прекращается, когда
он генерирует слово, означающее окончание строки
&lt;EOS&gt;.</p>
      <p>Пример работы модели представлен на рисунке 2.
Входной поток “generate random number”,
выходной “Random.new Random.nextInt”.</p>
      <p>На рисунке для простоты понимания состояния
расширены по времени: поскольку нейронная сеть
рекуррентная, переход из состояния должен вести в него же.
То есть здесь h1, h2, h3 одно и то же состояние в
моменты времени 1, 2, 3.</p>
      <p>В модели DeepAPI также используется
улучшение техники Sequence-to-Sequence: механизм внимания.
Вместо использования лишь последнего состояния
кодера в качестве вектора контекста для генерации
целого предложения, на каждом шаге работы декодера
используется свой вектор контекста, получаемый как
взвешенная сумма всех состояний кодера</p>
      <p>T
cj = X ajtht</p>
      <p>t=1
где cj вектор контекста для шага j; ht
исторические состояния кодера, ajt веса этих состояний для
шага j (моделируются при помощи отдельной заранее
натренированной нейронной сети).
где N
боре, nyt
yt.</p>
      <p>widf (yt) = log(N=nyt)
общее число экземпляров в тренировочном
на</p>
      <p>число экземпляров, в которых встречается
Так как DeepAPI должен переводить запросы на
английском языке в цепочки вызовов функций, она
должна тренироваться на примерах того, какие
английские предложения каким цепочкам вызовов функций
соответствуют. Такие примеры авторы оригинальной
статьи извлекают из открытого исходного кода, а
именно из методов с комментариями. Так как целевым
языком программирования выбрана Java, имеющая
зафиксированную структуру комментария для
документации Javadoc, авторы пользуются этим, и берут первое
предложение комментария в качестве описания метода
на английском языке (по определению Javadoc, именно
это написано в первом предложении). Чтобы получить
список вызовов функций, код метода анализируется
компилятором Eclipse JDT. Выводятся классы
каждой переменной, вызовы методов записываются вместе
с именем класса, которому этот метод принадлежит.
Пример вычленения информации из кода представлен
на рисунке 1.</p>
      <p>Рис. 1: Пример получения данных из кода
После обучения, во время генерации результата по
запросу, авторами используется лучевой поиск
вместо того, чтобы генерировать самое вероятное слово
на каждом шаге, поддерживается список из n текущих
самых вероятных слов, и генерация продолжается для
Рис. 2: Пример работы RNN Кодер-Декодера
Отдельное внимание стоит уделить процессу сбора
данных для исследования и тренировки модели. Для
получения большего количества данных, мы
использовали не только скачивание кода открытых проектов
с Github, но и обработку скомпилированных сборок
проектов, полученных из репозитория NuGet. В
следующих двух секциях мы рассматриваем эти способы
подробнее.</p>
      <p>A. NuGet</p>
      <p>Первый подход заключался в извлечении
нужных данных из скомпилированных библиотек,
котоПомимо последовательностей вызовов необходимо
было также собрать комментарии к методам. На этом
этапе мы столкнулись с проблемой: количество методов
с комментариями в скачанных нами пакетах составляет
лишь 11.21% от числа всех методов. Были собраны все
доступные комментарии из xml-файлов, а для
оставшихся методов мы генерировали описания, используя
имя данного метода и имя содержащего его класса.</p>
      <p>Как показала практика, описанный метод сбора
данных оказался достаточно эффективным. Было скачано
4,100 пакетов, содержащих в общей сложности 4,278
библиотек. Итоговое количество собранных методов
составило 611,945, из них 68,585 с комментариями.</p>
      <p>B. Github</p>
      <p>
        GitHub [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] популярный хостинг проектов с
открытым исходным кодом. Именно отсюда авторы
оригинальной статьи скачали 442,928 проектов на Java. Для
фильтрации проектов авторы выставили условие, что
у каждого из них должна быть хотя бы одна звезда.
      </p>
      <p>По подобному запросу для языка C# выдаётся
121,672 репозитория (https://github.com/search?utf8=
%E2%9C%93&amp;q=language%3AC%23+stars%3A%3E0&amp;
type=Repositories&amp;ref=searchresults).</p>
      <p>Таким образом, по сравнению с Java, репозиториев,
с которыми можно потенциально работать, примерно в
4 раза меньше. Однако судя по имеющимся у нас
данным, кажется возможным собрать количество данных
того же порядка. Авторы в итоге получили 7,519,907
пар “описание на естественном языке список вызовов
API”. После обработки 48,789 репозиториев мы
получаем 870,008 пар.</p>
      <p>Помимо количества репозиториев, возникает
проблема из-за выбранного целевого языка. В Java из
исходного кода можно легко получить тип (или надтип)
переменной из её объявления. Однако в языке C#,
начиная с версии 3.0, переменные могут иметь неявный
тип var, поэтому для выведения явного типа таких
переменных требуется компиляция всего проекта. Это
ограничивает количество репозиториев, которые мы
можем обработать. Кроме этого, мы сталкиваемся и
с другими сложностями со стороны языка, например,
динамический тип данных dynamic, о котором во время
компиляции мы ничего не знаем. Но такие проблемы по
сравнению с проблемой неявных типов несущественны:
мы провели небольшой эксперимент, запустив поиск в
исходном коде 470 случайно выбранных репозиториев
слова "dynamic"и "var и получив всего 4,856
результатов для первого, и 176,561 результатов для второго.
Поэтому пока что мы не исследуем способы решения
подобных неприоритетных проблем, оставляя это на
будущее.</p>
      <p>В качестве компилятора мы используем Roslyn
компилятор C# с открытым исходным кодом,
разработанный Microsoft. Чтобы собирать проекты в
автоматическом режиме, необходимо, чтобы:
1) не надо было предпринимать никаких
дополнительных действий (например, запускать
индивидуальные для каждого проекта скрипты);
2) проект содержал файл с расширением .sln</p>
      <p>именно с ним может работать Roslyn.</p>
      <p>Из 100 самых популярных результатов поиска таким
ограничениям удовлетворяет 51 проект, в среднем по
всем результатам поиска 11.2%.</p>
      <p>Код из подходящих репозиториев мы обрабатываем
аналогично оригинальной статье.</p>
      <p>IV. Эксперимент
наказывающую генерацию слишком частых функций.
Это изменение не было приоритетным, т.к. влияет на
оценку BLEU не больше, чем на 2 очка, увеличивая её
с 52.49 до 54.42, а для нас более интересно получить
первичный результат примерно того же порядка, что и
52.49.</p>
      <p>A. Первый эксперимент</p>
      <p>
        В качестве функции потерь в модели DeepAPI
берётся условная логарифмическая функция
правдоподобия. Модель тренируется максимизировать её с
помощью стохастического градиентного спуска [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ] в
комбинации с оптимизатором AdaDelta [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ]. Авторы
реализуют модель на базе библиотеки GroundHog. Однако
он устарел и более не поддерживается, поэтому мы
реализуем нашу первую модель на основе TensorFlow
популярной библиотеки для машинного обучения с
открытым кодом.
      </p>
      <p>Надо упомянуть, что обучение рекуррентных
нейронных сетей очень ресурсоёмко, а потому ведётся на
видеокартах. В то время как авторы для тренировки
пользовались видеокартой Nvidia K20, у нас имеется
гораздо менее мощная Nvidia GTX 660. В связи с этим
нам пришлось уменьшить параметры тренировки до
менее оптимальных. Например, авторы обнаружили,
что оптимальное количество нейронов в скрытом слое
кодера и декодера 1000. Мы выставляем их
количество в 700. Авторы не обсуждают влияние размера
пакета (batch) на модель, выставляя его значение в 200.
Мы делаем его размер равным 32.</p>
      <p>Мы вводим дополнительное улучшение в виде
bucketing разделения исходных предложений на
классы по длине, и тренировки внутри этих классов.
Дело в том, что для быстрого обучения нам нужны
вектора фиксированной длины а предложения имеют
длину разную. Можно их все дополнять до
максимальной длины (с помощью специального слова), а можно
разделить на категории вида длина &lt; 10, длина &lt; 20,
и т.д., и дополнять до максимума в этой категории,
тренируя категории отдельно. Чем меньше дополняем
пустыми словами, тем меньше шума, и лучше
(теоретически) результат.</p>
      <p>Мы тренируем модель на 605,146 парах данных в
течение 40,000 итераций, ограничив словарь самыми
популярными 10,000 слов в исходном и выходном
языках.</p>
      <p>Итоговая модель умеет верно отвечать на
некоторые запросы, например ’generate random number
System.Random.new System.Random.Next’ или ’replace
part of string with other string System.String.Replace’,
но на большинстве входов выдаёт нерелевантный
результат.</p>
      <p>B. Второй эксперимент
На текущий момент мы не занимались реализаци- Так как хороших результатов получить на модели
ей упомянутой ранее модификации функции потерь, с урезанными параметрами не удалось, мы создаём
Рис. 3: График изменения функции потерь во время
обучения
модель на основе нового фрэймворка от Google -
tfseq2seq, специализирующегося на Sequence-to-Sequence
моделях. С его помощью мы обучаем модель на тех же
значениях параметров, что и в оригинальной статье,
при этом для этого хватает производительности нашей
не мощной видеокарты. Также во время декодирования
мы используем лучевой поиск - улучшение,
предложенное авторами оригинальной статьи и описанное в
секции II; в предыдущей модели мы этот механизм не
реализовывали.</p>
      <p>Модель мы тренируем на 924,593 парах данных в
течение 390,000 итераций, ограничивая словарь в
исходном и выходном языках самыми популярными 10,000
слов.</p>
      <p>Итоговая модель может не только отвечать на
одиночные запросы, как старая, но и показывает
ненулевые результаты на тестовом множестве из 14,000
пар данных. Надо упомянуть, что пары из тестового
множества не используются во время тренировки,
поэтому положительные результаты на них означают, что
модель не просто запомнила данные ей в
тренировочном множестве примеры, а действительно научилась
обобщать знания. Оценка модели по метрике BLEU
растёт от 0.48 после 158,000 итераций до 1.95 после
390,000 итераций. Помимо этого, искусственная
функция потерь, которую модель минимизирует, стабильно
уменьшается (см. рисунок 3).</p>
      <p>Таким образом, из общей положительной динамики
мы можем заключить, что техника имеет право на
существование. Мы считаем, что тренировка на большем
количестве данных позволит получить сравнимый с
оригинальным результат.</p>
      <p>V. Дальнейшая работа
Мы планируем продолжать исследование данного
подхода. В ближайшей перспективе перед нами стоят
следующие цели:
1) собрать набор данных, сопоставимый по размеру</p>
      <p>с набором данных в оригинальной статье;
2) поэкспериментировать с параметрами обучения,</p>
      <p>и найти оптимальные;
3) исследовать возможность тренировки на не
комментированных методах, используя имена и
классы параметров, имя метода;
4) найти способы решения специфичных для
целе</p>
      <p>вого языка проблем;
5) реализовать алгоритм T2API;
6) объединить алгоритмы DeepAPI и T2API в один,
проанализировать получившийся результат.</p>
      <p>VI. Заключение
В этой статье мы описали нашу частично
успешную попытку повторить результат статьи DeepAPI.
Используя современные методы глубокого обучения и
машинного перевода, мы достигли небольших успехов
в задаче генерации списка вызовов функций по
текстовому запросу.</p>
      <p>Мы считаем, что модель DeepAPI действительно
может быть реализована на базе другого языка, а также
улучшена, что мы и собираемся продемонстрировать по
результатам дальнейшей работы.</p>
      <p>Список литературы</p>
      <p>DeepAPI#: CLR/C# call sequence synthesis</p>
      <p>from text query
Alexander Chebykin, Mikhail Kita, Iakov Kirilenko</p>
      <p>Developers often search for an implementation of typical
features via libraries (for example, how to create a UI
button control, extract data from a JSON-formatted file,
etc.). The Internet is the usual source of the information
on the topic. However, various statistical tools provide an
alternative: after processing large amounts of source code
and learning common patterns, they can convert a user
request to a set of relevant function calls.</p>
      <p>We examine one of those tools DeepAPI. This fresh
deep learning based algorithm outperforms all others
(according to its authors). We attempt to reproduce this
result using different target programming language
C# instead of Java used in the original DeepAPI. In
this paper we report arising problems in the data gathering
for training, difficulties in the model construction and
training, and finally discuss possible modifications of the
algorithm.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>M.</given-names>
            <surname>Allamanis</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Peng</surname>
          </string-name>
          , and
          <string-name>
            <given-names>C.</given-names>
            <surname>Sutton</surname>
          </string-name>
          , “
          <article-title>A convolutional attention network for extreme summarization of source code</article-title>
          .”
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>V.</given-names>
            <surname>Barstad</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Goodwin</surname>
          </string-name>
          , and T. Gjøsaeter, “
          <article-title>Predicting source code quality with static analysis and machine learning</article-title>
          .
          <source>” in NIK</source>
          ,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>M.</given-names>
            <surname>Raghothaman</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Y.</given-names>
            <surname>Wei</surname>
          </string-name>
          , and
          <string-name>
            <given-names>Y.</given-names>
            <surname>Hamadi</surname>
          </string-name>
          , “
          <article-title>Swim: synthesizing what i mean: code search and idiomatic snippet synthesis</article-title>
          ,”
          <source>in Proceedings of the 38th International Conference on Software Engineering. ACM</source>
          ,
          <year>2016</year>
          , pp.
          <fpage>357</fpage>
          -
          <lpage>367</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>T.</given-names>
            <surname>Xie</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Pei</surname>
          </string-name>
          , “Mapo:
          <article-title>Mining api usages from open source repositories</article-title>
          ,”
          <source>in Proceedings of the 2006 international workshop on Mining software repositories. ACM</source>
          ,
          <year>2006</year>
          , pp.
          <fpage>54</fpage>
          -
          <lpage>57</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>M. P.</given-names>
            <surname>Robillard</surname>
          </string-name>
          and
          <string-name>
            <given-names>R.</given-names>
            <surname>Deline</surname>
          </string-name>
          , “
          <article-title>A field study of api learning obstacles,” Empirical Software Engineering</article-title>
          , vol.
          <volume>16</volume>
          , no.
          <issue>6</issue>
          , pp.
          <fpage>703</fpage>
          -
          <lpage>732</lpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>J.</given-names>
            <surname>Stylos</surname>
          </string-name>
          and
          <string-name>
            <given-names>B. A.</given-names>
            <surname>Myers</surname>
          </string-name>
          , “
          <article-title>Mica: A web-search tool for finding api components and examples,” in Visual Languages</article-title>
          and
          <string-name>
            <surname>Human-Centric Computing</surname>
          </string-name>
          ,
          <year>2006</year>
          . VL/
          <article-title>HCC 2006</article-title>
          .
          <article-title>IEEE Symposium on</article-title>
          . IEEE,
          <year>2006</year>
          , pp.
          <fpage>195</fpage>
          -
          <lpage>202</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>J.</given-names>
            <surname>Wang</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Y.</given-names>
            <surname>Dang</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Zhang</surname>
          </string-name>
          , K. Chen,
          <string-name>
            <given-names>T.</given-names>
            <surname>Xie</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Zhang</surname>
          </string-name>
          , “
          <article-title>Mining succinct and high-coverage api usage patterns from source code</article-title>
          ,”
          <source>in Proceedings of the 10th Working Conference on Mining Software Repositories</source>
          . IEEE Press,
          <year>2013</year>
          , pp.
          <fpage>319</fpage>
          -
          <lpage>328</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>X.</given-names>
            <surname>Gu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Zhang</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Zhang</surname>
          </string-name>
          , and S. Kim, “
          <article-title>Deep api learning</article-title>
          ,
          <source>” in Proceedings of the 2016 24th ACM SIGSOFT International Symposium on Foundations of Software Engineering. ACM</source>
          ,
          <year>2016</year>
          , pp.
          <fpage>631</fpage>
          -
          <lpage>642</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>T.</given-names>
            <surname>Nguyen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P. C.</given-names>
            <surname>Rigby</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. T.</given-names>
            <surname>Nguyen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Karanfil</surname>
          </string-name>
          , and
          <string-name>
            <given-names>T. N.</given-names>
            <surname>Nguyen</surname>
          </string-name>
          , “
          <article-title>T2api: synthesizing api code usage templates from english texts with statistical translation,”</article-title>
          <source>in Proceedings of the 2016 24th ACM SIGSOFT International Symposium on Foundations of Software Engineering. ACM</source>
          ,
          <year>2016</year>
          , pp.
          <fpage>1013</fpage>
          -
          <lpage>1017</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>I.</given-names>
            <surname>Sutskever</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Vinyals</surname>
          </string-name>
          , and
          <string-name>
            <given-names>Q. V.</given-names>
            <surname>Le</surname>
          </string-name>
          , “
          <article-title>Sequence to sequence learning with neural networks,”</article-title>
          <source>in Advances in neural information processing systems</source>
          ,
          <year>2014</year>
          , pp.
          <fpage>3104</fpage>
          -
          <lpage>3112</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>G.</given-names>
            <surname>Salton and M. J. McGill</surname>
          </string-name>
          , “
          <article-title>Introduction to modern information retrieval</article-title>
          ,”
          <year>1986</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <surname>H. K</surname>
          </string-name>
          . U. of Science and Technology. (
          <year>2017</year>
          )
          <article-title>Deepapi</article-title>
          . [Online]. Available: http://www.cse.ust.hk/~xguaa/deepapi/
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <surname>Nuget</surname>
            <given-names>gallery.</given-names>
          </string-name>
          [Online]. Available: http://www.nuget.org
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <surname>Github</surname>
          </string-name>
          . [Online]. Available: https://github.com
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>L.</given-names>
            <surname>Bottou</surname>
          </string-name>
          , “
          <article-title>Large-scale machine learning with stochastic gradient descent</article-title>
          ,”
          <source>in Proceedings of COMPSTAT'2010</source>
          . Springer,
          <year>2010</year>
          , pp.
          <fpage>177</fpage>
          -
          <lpage>186</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <surname>M. D. Zeiler</surname>
          </string-name>
          , “
          <article-title>Adadelta: an adaptive learning rate method</article-title>
          ,
          <source>” arXiv preprint arXiv:1212.5701</source>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>