- BrainTools - https://www.braintools.ru -
Где взять пару миллионов документов с разметкой для обучения [1] модели ИИ? Сгенерировать синтетически! Меня зовут Никита, я работаю в ИСП РАН и веду блог по ИИ [2]. Выложил в открытый доступ проект, который поможет дата-саентистам самостоятельно создавать датасеты сканированных документов с разметкой, используя только CPU. Подойдет для предобучения мультимодальных трансформеров, OCR и проч.
Кратко:
Генератор создает синтетические PNG-картинки сканированных документов с разметкой. Ссылка на гитхаб [3]
Язык текста: можно выбрать.
Принцип работы: парсим страницу Википедии, переносим инфу в DOCX, рандомизируем стилизацию, из DOCX рендерим изображения, изображения аугментируем под сканы.
Разметка: bounding box (координаты ограничивающей рамки) каждого слова и само слово. Можно обучать модели VrDU, OCR и проч.
Содержание документа: абзацы текста, заголовки, таблицы. Есть различные форматирования: жирный, подчеркивание, курсив. Одна или две колонки. Рандомизация шрифтов, настроек форматирования.
Требуемое железо: только CPU.




Требования к датасету просты:
Нужны изображения сканов документов, достаточно реалистичные и разнообразные;
В документах должен содержаться осмысленный текст с разным форматированием, требуется поддержка русского языка;
В разметке нужны слова и координаты их bounding box.
Текст на любом языке можно спарсить с интернета и получить форматирование через HTML, а затем разместить текст в DOCX. А там и рандомизировать стили и зарендерить изображение несложно. Однако тут встает вопрос – а как получить разметку? Можно воспользоваться OCR, но тогда неизбежно будут получаться ошибки [4] распознавания. Хотелось бы как-то доставать координаты из DOCX напрямую, однако из коробки для этого способа нет. Пришлось изобретать!)
Идею подсказали коллеги Андрей Перминов [5] и Настя Зыкина [6], которые создавали таким образом датасет документов для обучения детектора абзацев. Я улучшил алгоритм для детекции каждого слова и сделал из этого open-source систему.
Итак, в ворде есть инструмент “Заливка”. Он создает цветной фон вокруг слова.
А еще есть инструмент “Цвет шрифта”. Что если выбрать и там, и там одинаковый цвет? Получатся вот такие веселые прямоугольники вместо слов.
А вот веселые цветные прямоугольники на идеально белом фоне можно быстро находить классическим компьютерным зрением [7]. Ставим границы всех таблиц в белый цвет, чтобы не мешали. Переводим DOCX в PNG, с помощью OpenCV бинаризуем изображение, находим контуры и извлекаем из них координаты прямоугольников.
Проблем быть не должно, так как документ не содержит ничего, кроме закрашенных прямоугольников на белом фоне, а изображение не содержит никаких помех.
Осталось сопоставить к каждому bbox’y текстовое слово. Сделать это несложно. Красить каждое слово будем в уникальный цвет. Затем сохраним соотношение HEX_код_цвета -> текст_слова в хэш-таблице. Тогда после детекции bbox’a сможем достать из хэш-таблицы слово, используя цвет прямоугольника. При глубине цвета 8 бит можно закодировать слов (вычитаем белый цвет, так как он сольется с фоном). PNG сжимает изображения без потерь, RGB-значения в каждом пикселе будут точно соответствовать цвету прямоугольника в DOCX документе. Поэтому способ сработает и для близких оттенков.
Пока что генератор поддерживает в качестве источника текстов Википедию. Полный алгоритм генерации одного скана представлен на блок-схеме ниже:
Теперь о технической реализации. Сначала инициализируется класс Manager и создает список ссылок. Парсинг ссылок работает аналогично алгоритму обхода графа в ширину. Сначала сканируются все ссылки на стартовой странице, затем их дочерние ссылки и так далее, а для хранения непросмотренных URL используется очередь. Начальная страница задается пользователем. По умолчанию стоит начальная страница английской Википедии, но можно поставить страницу любого языка.
Затем создаются несколько DocumentGenerator – по одному на каждый процесс. Каждый экземпляр получает подмножество из списка URL и для каждой ссылки запускает приведенный выше алгоритм.
Вся работа с ворд-документом ведется через python-docx [8]. На данный момент бутылочное горлышко всего проекта – перевод DOCX в PNG. Я использую Unoserver [9] для перевода в PDF, а затем pdf2image [10] для рендера PNG, что достаточно затратно. Если кто знает, как можно это сделать проще – пишите!
Для ускорения поднимаются несколько экземляров Unoserver’a в разных процессах. Внутри каждого DocumentGenerator зашит мультитрединг, который не позволяет простаивать системе, пока Unoserver рендерит PDF. Так удалось добиться генерации одного скана в среднем за 0.5 секунды на Intel(R) Xeon(R) Gold 6338.
Алгоритм поиска контуров работает на OpenCV:
thr = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
thr = cv2.threshold(thr, 254, 255, cv2.THRESH_BINARY_INV)[1]
cnts = cv2.findContours(thr, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.015 * peri, True)
if len(approx) == 4:
x, y, w, h = cv2.boundingRect(approx)
rgb_color = image_pil.getpixel((x+1, y+1))
color = '#%02x%02x%02x' % (rgb_color)
Для аугментаций используется библиотека Augraphy [11], которая заточена под реалистичные “скановые” аугментации. Пришлось даже сделать мердж реквест, чтобы поправить там баг. Также для ускорения операций с изображениями используется Pillow-SIMD [12].
Так и получился DOcument GEnerator – DoGe.
Надеюсь, DoGe поможет вам в обучении ваших моделей. Код системы можно найти в открытом репозитории [13]. Я открыт для идей по улучшению генератора, а также помощи в их реализации. По плану:
Добавление парсинга и разметки изображений
Добавление разметки заголовкам, таблицам, абзацам
Добавление новых форматов вывода (например, Parquet)
Добавление дополнительной информации в разметку через языковые модели
Повышение производительности: узким местом является преобразование Docx -> Pdf -> Png.
Подписывайтесь на мой телеграм канал про ИИ [2], где я делюсь своим опытом [14] в сфере глубокого обучения. Минимум репостов новостей, только свой опыт и мысли.
Автор: Travvy
Источник [15]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/16447
URLs in this post:
[1] обучения: http://www.braintools.ru/article/5125
[2] блог по ИИ: https://t.me/shevtsov_dl
[3] Ссылка на гитхаб: https://github.com/Travvy88/DocumentGenerator_DoGe/
[4] ошибки: http://www.braintools.ru/article/4192
[5] Андрей Перминов: https://habr.com/ru/users/dronperminov/
[6] Настя Зыкина: https://github.com/NastyBoget
[7] зрением: http://www.braintools.ru/article/6238
[8] python-docx: https://python-docx.readthedocs.io/en/latest/
[9] Unoserver: https://github.com/unoconv/unoserver
[10] pdf2image: https://pypi.org/project/pdf2image/
[11] Augraphy: https://github.com/sparkfish/augraphy
[12] Pillow-SIMD: https://github.com/uploadcare/pillow-simd
[13] открытом репозитории: https://github.com/Travvy88/DocumentGenerator_DoGe
[14] опытом: http://www.braintools.ru/article/6952
[15] Источник: https://habr.com/ru/companies/isp_ras/articles/920346/?utm_campaign=920346&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.