Преобразуя естественные английские предложения в код виджетов Flutter с помощью Transformers и PyTorch

Можем ли мы преобразовать наши простые английские предложения в некоторый код пользовательского интерфейса? действительно ли мы можем получить рабочий код, не зная его?

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

Если вы хотите узнать больше о Transformers и Seq2sqe, вы можете взглянуть на Внимание - все, что вам нужно и эту красивую статью.

Перед тем, как мы начнем. Цель этого эксперимента исключительно исследовательская. Мы не собираемся поддерживать все виджеты Flutter на текущем этапе, а также используем некоторые пользовательские виджеты вместо встроенных. виджет, чтобы упростить задачу.

Данные обучения

У нас есть около 175000 пар предложений и код виджетов Flutter. Эти обучающие данные генерируются полностью автоматически. он охватывает некоторые из основных виджетов Flutter.

Образец пары:

Английское предложение: « создать контейнер со значением ширины»

Код флаттера:

Container(width:value,)

Предложение будет входом нашей модели, а код Flutter - выходом.

Но почему у нас есть «значение» вместо чисел, если свойство - «Ширина»?
Поскольку у нас есть много значений динамических свойств, таких как цвета, ширина, высота, отступы, выравнивание и т. д.…
Мы собираемся выполнить некоторую предварительную обработку для нашего ввода, чтобы изменить все эти значения с помощью ключевого слова «Value» и выполнит постобработку выходных данных модели, чтобы вернуть реальные значения.
Это будет примерно так:
« Создайте контейнер с width 24.0 ”=› « создать контейнер со значением ширины».

Токенизация

Для предложений на английском языке мы будем использовать Spacy в качестве входного токенизатора. Для выходного токенизатора мы создадим собственный токенизатор. Мы не нашли подходящего токенизатора для Dart / Flutter, поэтому мы будем использовать Python по умолчанию tokenize, а позже он будет изменен.

Мы будем использовать torchtext.data.Field PyTorch:
Для ввода мы будем использовать Spacy, как уже упоминалось, который по умолчанию реализован в data.Field.

Input = Field(tokenize = 'spacy',
            init_token = '<sos>', 
            eos_token = '<eos>', 
            lower = True)

Для вывода мы должны сначала создать метод токенизации Python.

from tokenize import tokenize, untokenize
import io
def tokenize_flutter_code(str_code):
    tokens = list(tokenize(io.BytesIO(str_code.encode('utf-8')).readline))
    return [it.string for it in flutter_tokens]

И мы назовем это throw Полем вывода:

Output = Field(tokeniz = tokenize_flutter_code ,
               init_token = '<sos>',
               eos_token = '<eos>',
               lower = False)

Создание словаря с помощью torchtext

fields = [('Input', Input),('Output', Output)]
Input.build_vocab(train_data, max_size=10000, min_freq=2)
Output.build_vocab(train_data, max_size=10000, min_freq=2)

Модель трансформатора

Перед тренировочным процессом

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

Мы разделим наш набор данных на данные для обучения, проверки и тестирования.

После того, как все наши компоненты будут готовы, мы можем приступить к тренировочному процессу.

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

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

Просмотреть образцы результатов:

Входные данные: «Построить контейнер шириной 33 и высотой 44»
. Результат:

Container(width:33,height:44)

Ввод: «Напишите текст со словом« Hello »и размером текста 22 внутри строки»
, вывод:

Row(children:[ CustomText("Hello", textSize: 22)],)

Входные данные: «Создать изображение с помощью« my_img.jpg »и подогнать под BoxFit. fill»
Выходные данные:

Image.asset("my_img.jpg", fit: BoxFit.fill)

Больше примеров вы можете найти в моем репозитории Github.

Мы создали простой конвертер кода виджетов с английского языка в интерфейс Flutter UI из ограниченного набора данных. и мы получили действительно хорошие результаты.

использованная литература