Обучение ESRGAN

Материал из wolfram
Перейти к навигации Перейти к поиску

Обучения силами BasicSR от Xintao.

За основу взята версия релиз 1.2

Интересно то, что все будет запускаться нативно в Windows. Без каких либо прослоек. С использование аппаратного ускорения CUDA.

Подготовка

Скрин скачивания с сайта python.org

Python

Устанавливаем Python, в моем случае 3.8.10 с официального сайта.

При установке обязательно поставить галочку на против Add Python 3.8.10 to Path - это нужно чтобы он прописался как команды в Windows, что позволит выполнять команды Python из любого терминала.

После инсталляции открыть PowerShell и ввести:

Python

Получим ответ по типу:

Python 3.8.5 (default, Sep  3 2020, 21:29:08)

Значит все Ок, все установлено верно и будет работать.

Скрин скачивания с сайта PyTorch

PyTorch

фреймворк машинного обучения для языка Python с открытым исходным кодом.

Без него не будет работать BasicSR.

Берем опять же от официалов

В моем случае это версия 1.8.1, для Windows, устанавливаться будет через pip3, Работать будет с CUDA11.1.

Будет сгенерирован код.

Выполняем через PowerShell от администратора:

pip3 install torch==1.8.1+cu111 torchvision==0.9.1+cu111 torchaudio===0.8.1 -f https://download.pytorch.org/whl/torch_stable.html

Начнется небыстрая установка компонентов.

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

NVDIA драйвер

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

Скрин скачивания CUDA Toolkit

CUDA Toolkit

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

Конечно же брать с официального сайта. Выбрать Windows, архитектуру x86_64, версия Windows конечно же 10, ну и тип установщика: автономный или локальный, в челом без разницы.

Устанавливает как обычно, практически также как драйвер.

Так что ждем установки и радуемся успешному окончанию.

Git

Тоже мало кто будет ставить это на Windows, но разработчики это делают по умолчанию. Потому что, а как еще взаимодействовать с GitHab. Интересно, что MS давно уже приобрели GitHab, но какого мелкомягкого человека Git не встроен в Windows до сих пор!?

Ладно... Скачиваем с официального сайта. Естественно под x64, в каком веке мы живем?

Ничего сложного, далее, далее, далее, готово.

Теперь мы можем получать с Githab и подобных файлы напрямую, через PowerShell.

Пункт для установки Microsoft C++ Build Tools

Microsoft C++ Build Tools

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

Конечно скачать с официального сайта.

При установке, отметить галкой C++ Build Tools. Как показано на картинке.

Как получить нужную версию BasicSR

BasicSR

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

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

Важно!

В инструкции написано:

git clone https://github.com/xinntao/BasicSR.git

Но так как мы берем не последнюю версию, то нужно просто получить архив, на картинке:

Скачиваем архив, помещаем содержимое куда надо. Вообще не важно куда.


Теперь запускаем PowerShell от админа.

Переходим в папку BasicSR - у меня это выглядит так:

cd D:\test\AI\BasicSR

Выполняем команды:

pip install -r requirements.txt
python setup.py develop

Произойдет не мало всего, и очень надеюсь что без ошибок.


Настройка

Под настройкой подразумевается прописывание в конфигах нужных путей, настроек.

Мы хотим обучать сеть, алгоритм будем брать ESRGAN.

Открываем текстовым редактором файл:

.\BasicSR\options\train\ESRGAN\train_ESRGAN_x4.yml

name: указываем имя паки в которую будут складываться результаты.

name: Manga_set2

Далее по документу:

datasets:
 train:
  name: DIV2K
  type: PairedImageDataset
  dataroot_gt: datasets/Manga_set2/GT   # тут папка в корой лежат файлы к которым сеть будет стремиться.
  dataroot_lq: datasets/Manga_set2/LQ   # тут файлы которые сеть будет пытаться превратить в то к чему нужно стремится.

Следующий блок:

val:
 name: Set14
 type: PairedImageDataset
 dataroot_gt: datasets/Manga_set2/GT_V # это файлы валидности, чрез некий промежуток времени будет делаться создание среза в виде результата обработки, то что как бы должно быть.
 dataroot_lq: datasets/Manga_set2/LQ_V # из этого она попытается сделать конечный результат, который мы увидим, своего рода срезы обучения.

Следующий блок отвечает за местоположение файла предварительно обученной модели.

path:
 pretrain_network_g: experiments/pretrained_models/ESRGAN_PSNR_SRx4_DF2K_official-150ff491.pth # путь до файла модели, обучение запускается именно отсюда
 strict_load_g: true
 resume_state: ~ # в начале обучения тут ничего не должно быть, но в какой то момент, захочется остановить обучение, и продолжить позже, для этого ниже создаются срезы модели. Вот этими срезами и можно будет воспользоваться для возобновления обучения. Просто будет указан путь до среза.

Данный блок отвечает за то как часто будет создаваться изображения валидности, из срезов.

val:
 val_freq: !!float 1e2 # может указываться как в научном виде, так и простом, например 200. Каждые 200 итераций, будет выполнено создание изображения с использованием текущего состояния модели.
 save_img: true

Данные блоки отвечают за частоту отображения состоянии итераций и сохранении срезов модели.

logger:
  print_freq: 10 # частота отображения результатов в командной строке.
  save_checkpoint_freq: !!float 1e3 # частота создания срезов модели. В данном случае раз в 1000 итераций. Не забываем что каждый такой срез занимает 256 мегабайт, и таких срезом будет порядка 400, в итоге это будет занимать очень много места.

В общем с настройками train_ESRGAN_x4.yml можно закончить.

Следующим этапом будет подготовка датасетов.

Датасет

Введение

Для начала нам нужно понять что мы хотим получать на выходе.

Пример того что нужно получить Зерно в Полутона

В моем случае, и случае который я буду описывать, мне нужно:

Задача восстановление качества графических изображений, а именно манги.

К чему стремимся

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

Изображение 02. Результат работы уже обученной модели не учитывающей превращение зерна в градиенты

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

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

На "Изображении 02" пример, видно что модель закрасила тени, потому что на исходнике не было четкого контраста, такое бывает редко, в большинстве случав фон будет белым, а точки мелкие и черные. Это сильно бьёт по глазам, и в итоговой отрисовке, кажется менее темным чем должно быть, также исчезает эффект перехода от светлого к темному.

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


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


Посмотрим что получится. На момент написания статьи я сам не знаю результата, получится у меня или нет.

О чем нужно позаботится

Пример Градиент и текстура

Я предполагаю еще до обучения, это то как объяснить модели, где реально зерно для создания градиента, а еде например вот такая вот текстура как на картинке.

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

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

Тип модели

Нужно определиться с моделью. Я использую модели от самого Xintao, они находятся в описании и на них есть ссылка.

Самыми эффективными являются ESRGAN, их два вида у Xintao: ESRGAN_SRx4 и ESRGAN_PSNR_SRx4, Если честно я не знаю чем они отличаются, слишком мало я разобрался в этой теме. Но одно известно точно, ESRGAN_PSNR_SRx4 обучается в двое быстрее. Почему мне не известно.

Также из их названия можно увидеть, то что присудcвует x4. Это уровень масштабирования. Вообще все конфиги по умолчанию настроены на абскеил в четыре раза. И к сожалению просто поменять 4 на 2 или 1 не получится. Нужна специальная модель имеющая матрицу под этот масштаб. Опять же я пока не знаю как сделать самостоятельно модель, а не использовать уже переобученную.

Также нужно рассказать о том, что Xintao раньше выпускал BasicSR версии до 1.0. Эти версии используют другие несовместимые модели.

Если взять с гитхаба версию до 1.0 то можно использовать старые модели. Есть конвертор, но я так же не смог с ним разобраться. Это все работает на Python.

Для старых версий существует немало готовых моделей, всех масштабов и свойств.

После скачивания модель разместить в Папке: \BasicSR\experiments\pretrained_models

Особенности разрешения датасета

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

Теперь определился с типами данных.

GT - это данные к которым модель будет стремиться - наши идеальные изображения.

LQ - это то что мы бы хотели улучшать до GT

Так вот обязательная и максимально важная характеристика GT - это кратность 4 по обоим сторонам разрешения. Это конечно при условии, того что мы получаем LQ из GT по средствам обработки.

Соответственно тоже будет при других масштабах.

Размер изображений

Нет смысла скармливать модели изображения в большом разрешении. Лучше все изображения разбить на множество кусков. Что сильно увеличит итоговое количество изображений.

Лучший вариант использования это файлы с разрешением 480х480 пикселей, и соответственно их пары 120x120 пикселей.

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

Нужно положить в папку GT_F, например изображения в высоком разрешении. В папку LQ_F изображения в низком разрешении. С соблюдением кратности как я описывал выше.

После чего запустить скрипт: extract_subimages.py

Находится он по пути:

BasicSR\scripts\data_preparation

Давайте его настроим, откроем текстовым редактором:

# HR images
opt['input_folder'] = 'datasets/Manga_set2/GT_full' # прописано расположение наших GT_F файлов.
opt['save_folder'] = 'datasets/Manga_set2/GT' # Положение файлов в нарезанном виде.
opt['crop_size'] = 480 # Разрешение по двум сторонам, то которое будет в итоге
opt['step'] = 240 # Шаг смещения. Этот скрипт, идет по исходнику с лева на право, смещаясь на 240 писклей, и сохраняя фрагмент.

Дальше идут блоки:

# LRx2 images
# LRx3 images

На против строк к этим блоков ставим "#", чтобы закомментировать их.

Приходим к блоку:

# LRx4 images
opt['input_folder'] = 'datasets/Manga_set2/LQ_full' # прописано расположение наших LQ_F файлов.
opt['save_folder'] = 'datasets/Manga_set2/LQ' # Положение файлов в нарезанном виде.
opt['crop_size'] = 120 # Разрешение по двум сторонам, то которое будет в итоге
opt['step'] = 60 # Шаг смещения. Этот скрипт, идет по исходнику с лева на право, смещаясь на 60 писклей, и сохраняя фрагмент.

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

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

Теперь его запустим:

Переходим в каталог BasicSR, у меня это:

cd C:\Users\vova\Documents\BasicSR

И выполняем скрипт:

py .\scripts\data_preparation\extract_subimages.py

Прогресс должен пройти без ошибок. На версии PyTorch 1.8.1 у меня процесс нормально не проходит, причем, не зависимо от ОС, на linux такая же картина. Скорее всего с обновлением PyTorch эти проблему уйдут.

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



А это все означает следующее:

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

Совсем не простая задача, как кажется.


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

Первое это найти исходники в двух исполнениях. Мне удалось найти RAW версию и цифровую с переводом.

Пример несоответствия

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

На приведенных картинка показано. То что если использовать "Скан в зерне имеющий аналог в идеальном виде" мы отлично будем чистит только зерно как на этом скане.

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

После чего я начал экспериментировать с "порчей" второго изображения. Сначала фильтры размытия перепробовал много. Остановился на том, что уменьшил Изображение 02 ровно в два раза. И внезапно увидел очень похожую картину с Изображением 01. На Изображении 04 и 05 с большим масштабом это показано. И только этот паттерн который я создал, начал давать результаты по превращению зерна в градиенты, на подобных сканах.

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

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

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

Обучение

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


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

Результаты из примера несоответствия:

Всего через 7000 итераций видно, что шум сильно подавился в сторону заливки.

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

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