Тестирование нейросети ESRGAN для детализации изображений

Software
Test
Making Off
Python
[ 25.09.2020 ]
Update: [ 26.09.2020 ]

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

Установка

Для работы нам понадобится среда исполнения Python, а также набор библиотек PyTorch, OpenCV и сам скрипт ESRGAN с натренированной моделью. Скачиваем с python.org дистрибутив, в моём случае Python версии 3.8.5 x64 под ОС Windows. Установку я произвел для всех пользователей в Program Files.

devstratum - Python

Далее запускаем (Win+R) консоль Сmd. Надо добраться до папки менеджера пакетов Pip питона. В моём случае это C:\Program Files\Python38\Scripts, меняем директорию:

cd C:\Program Files\Python38\Scripts

Теперь можно запустить установку PyTorch. На pytorch.org есть конфигуратор командной строки для инсталляции, выбираем версию, ОС, менеджер пакетов, язык и поддержку CUDA, которой в моём случае не будет, в виду отсутствия видеокарты от компании Nvidia.

devstratum - PyTorch

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

pip install torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html

 И ещё одна установка библиотеки OpenCV:

pip install numpy opencv-python

Осталась пара шагов. На гитхабе забираем проект ESRGAN (Code -> Download ZIP) и скачиваем натренированные модели сети. Проект извлекаем в удобное место. Модели сети распаковываем в папку models проекта. Папка LR предназначена для исходников изображений, результаты соответственно получим в папке results. Для исполнения задачи нужно запустить файл test.py, который я немного модифицировал.

model_path = 'models/RRDB_ESRGAN_x4.pth'  # models/RRDB_ESRGAN_x4.pth OR models/RRDB_PSNR_x4.pth
device = torch.device('cpu')  # if you want to run on CPU, change 'cuda' -> cpu
# device = torch.device('cpu')

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

import os.path as osp
import glob
import cv2
import numpy as np
import torch
import RRDBNet_arch as arch
import time

sec_start = time.time()
print('Start: ', time.ctime(sec_start))

model_path = 'models/RRDB_ESRGAN_x4.pth'  # models/RRDB_ESRGAN_x4.pth OR models/RRDB_PSNR_x4.pth
device = torch.device('cpu')  # if you want to run on CPU, change 'cuda' -> cpu
# device = torch.device('cpu')

test_img_folder = 'LR/*'

model = arch.RRDBNet(3, 3, 64, 23, gc=32)
model.load_state_dict(torch.load(model_path), strict=True)
model.eval()
model = model.to(device)

print('Model path {:s}. \nTesting...'.format(model_path))

idx = 0

for path in glob.glob(test_img_folder):
    idx += 1
    base = osp.splitext(osp.basename(path))[0]
    print(idx, base)
    # read images
    img = cv2.imread(path, cv2.IMREAD_COLOR)
    img = img * 1.0 / 255
    img = torch.from_numpy(np.transpose(img[:, :, [2, 1, 0]], (2, 0, 1))).float()
    img_LR = img.unsqueeze(0)
    img_LR = img_LR.to(device)

    with torch.no_grad():
        output = model(img_LR).data.squeeze().float().cpu().clamp_(0, 1).numpy()
    output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
    output = (output * 255.0).round()
    cv2.imwrite('results/{:s}_rlt.png'.format(base), output)

sec_end = time.time()
print('End: ', time.ctime(sec_end))

sec_final = sec_end - sec_start
print('Total time in seconds: ', round(sec_final))

Тестирование

Для тестирования возьмём три экземпляра изображений разных разрешений: 640x360, 1280x720 и 1920x1080 пикселей. Замерим время выполнения задачи увеличения разрешения в 4 раза и сравним участки картин с стандартной бикубической интерполяцией против обработки нейронной сети. В конфигурации для расчётов использован 16 поточный Xeon E5-2650 v2 и 32 GB оперативной памяти в 4 канальном режиме.

devstratum - ESRGAN

Примерные выводы по времени обработки кадра из графика сделать можно. На выходе получили изображения разрешением: 2560 x 1440, 5120 x 2880 и 7680 x 4320 пикселей. Опытным путём было установлено, что для исходника более 2.6 мегапикселя 32 GB памяти становится недостаточно. Данные сбрасываются в файл подкачки на диск и всё резко тормозит на долгие часы с постоянной передачей данных между памятью и диском.

Обработка данных с помощью нейронных сетей одна из задач, где памяти много не бывает.

Посмотрим относительное сравнение качества участков изображений из эксперимента. Слева привычная бикубическая интерполяция, справа работа алгоритма ESRGAN с текущей натренированной моделью. Для наглядности брались экземпляры 640 x 360 пикселей.

devstratum - Example
devstratum - Example
devstratum - Example

Заключение

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