AI-Based Photo Restoration / Хабр
Всем привет! Я инженер-исследователь в команде компьютерного зрения Mail.ru Group. В этой статье я расскажу историю о том, как мы создали проект фотореставрации старых военных фотографий на основе искусственного интеллекта. Что такое «реставрация фото»? Он состоит из трех шагов:
- находим все дефекты изображения: трещины, потертости, дыры;
- закрашиваем обнаруженные дефекты, основываясь на значениях пикселей вокруг них;
- раскрашиваем изображение.
Затем нам нужно было собрать тренировочный набор. Обучающая выборка для задачи сегментации представляет собой изображение и маску, на которой отмечены все дефекты. Самый простой способ сделать это — позволить оценщикам создать маски сегментации. Конечно, люди очень хорошо умеют находить дефекты, но это заняло бы слишком много времени.
Отметка дефектных пикселей на одной фотографии может занять час или целый рабочий день. Поэтому собрать обучающую выборку из более чем 100 изображений за несколько недель непросто. Поэтому мы попытались дополнить наши данные и создали свои собственные дефекты: мы сделали хорошее фото, добавили дефекты с помощью случайных блужданий по изображению и в итоге получили маску, показывающую части изображения с дефектами. Без дополнений у нас есть 68 фотографий, помеченных вручную, в обучающем наборе и 11 фотографий в проверочном наборе.
Самый популярный подход к сегментации: возьмите Unet с предварительно обученным кодировщиком и минимизируйте сумму BCE (бинарная кросс-энтропия) и DICE (коэффициент Серенсена-Дайса).
Какие проблемы возникают, когда мы используем этот подход сегментации для нашей задачи?
- Даже если кажется, что на фото куча дефектов, что оно очень старое и потрепанное, площадь с дефектами все равно намного меньше неповрежденной. Чтобы решить эту проблему, мы можем увеличить положительный вес класса в BCE; оптимальным весом будет отношение чистых пикселей к дефектным.
- Вторая проблема заключается в том, что если мы используем готовый Unet с предварительно обученным энкодером (например, Albunet-18), мы теряем много позиционных данных. Первый слой Албунет-18 состоит из свертки с ядром 5 и шагом, равным двум. Это позволяет сети работать быстро. Мы пожертвовали чистым временем работы, чтобы лучше локализовать дефекты: убрали максимальный пул после первого слоя, уменьшили шаг до 1 и уменьшили ядро свертки до 3.
- Если работать с небольшими изображениями, сжимая их, например, до 256 х 256 или 512 х 512 пикселей, то мелкие дефекты исчезнут из-за интерполяции. Поэтому нам нужно работать с большими изображениями. В настоящее время мы сегментируем дефекты на фотографиях размером 1024 x 1024, находящихся в производстве. Вот почему нам пришлось тренировать сеть на больших изображениях. Однако это вызывает проблемы с небольшим размером пакета на одном GPU.
- Во время обучения мы можем разместить около 20 изображений на одном графическом процессоре. Из-за этого мы получаем неточные значения среднего и стандартного отклонения в слоях BatchNorm. Мы можем решить эту проблему с помощью In-place BatchNorm, который, с одной стороны, экономит место в памяти, а с другой стороны, имеет версию Synchronized BatchNorm, синхронизирующую статистику по всем графическим процессорам. Теперь мы вычисляем значения среднего и стандартного отклонения не для 20 изображений на одном GPU, а для 80 изображений с 4 GPU. Это улучшает сходимость сети.
Сеть сходится за 18 часов на четырех GeForce 1080Ti. Вывод занимает 290 мс. Это довольно долго, но это цена нашей производительности лучше, чем по умолчанию. Валидация DICE равна 0,35, а ROCAUC — 0,9.3.
То же самое с задачей сегментации, которую мы использовали Unet. Для закрашивания мы загружали исходное изображение и маску, где отмечали единицами всю чистую область, а нулями — все пиксели, которые хотим закрасить. Вот как мы собирали данные: к любой фотографии из набора данных изображений с открытым исходным кодом, например, OpenImagesV4, мы добавляем дефекты, похожие на те, которые мы видим в реальной жизни. Затем мы обучили сеть восстанавливать недостающие части.Как мы можем изменить Unet для этой задачи?
Мы можем использовать частичную свертку вместо оригинальной. Идея состоит в том, что когда мы сворачиваем область с каким-то ядром, мы не учитываем значения дефектных пикселей. Это делает прорисовку более точной. Мы покажем вам пример из недавней статьи NVIDIA. Они использовали Unet с двумерной сверткой по умолчанию на среднем снимке и частичной сверткой — на снимке справа.
Мы тренировали сеть пять дней. В последний день мы заморозили BatchNorms, чтобы границы окрашиваемой части были менее заметны.
Сети требуется 50 мс для обработки одного изображения 512 x 512. Валидационный PSNR равен 26,4. Однако полностью полагаться на метрики в этой задаче нельзя. Чтобы выбрать лучшую модель, мы запускаем несколько хороших моделей на оценочных изображениях, анонимизируем результаты, а затем голосуем за те, которые нам понравились больше всего. Вот так мы выбрали нашу последнюю модель.
Ранее я упоминал, что мы искусственно добавили некоторые дефекты в чистые изображения. При обучении всегда следует отслеживать максимальный размер добавляемых дефектов; в случае, когда вы подаете в сеть изображение с очень большим дефектом, с которым никогда не сталкивались на этапе обучения, сеть будет разбегаться и давать неприемлемый результат. Поэтому, если вам нужно исправить большие дефекты, дополните ими свою обучающую выборку.
Вот пример работы нашего алгоритма:
Мы сегментировали дефекты и закрасили их; третий шаг — цветовая реконструкция. Как я уже говорил, среди фотографий «Бессмертного полка» много индивидуальных и групповых портретов. Мы хотели, чтобы наша сеть хорошо работала с ними. Мы решили придумать свою раскраску, так как ни один из существующих сервисов не мог раскрашивать портреты быстро и качественно. Мы хотим, чтобы наши раскрашенные фотографии выглядели более правдоподобно.На GitHub есть популярный репозиторий для раскрашивания фотографий.
Это делает хорошую работу, но все еще имеет некоторые проблемы. Например, он склонен красить одежду в синий цвет. Вот почему мы также отказались от него.Итак, мы решили создать алгоритм раскрашивания изображения. Самая очевидная идея: взять черно-белое изображение и предсказать три канала: красный, зеленый и синий. Однако мы можем упростить себе задачу: работать не с цветовым представлением RGB, а с цветовым представлением YCbCr. Компонент Y — это яркость (яркость). Загруженное черно-белое изображение — это канал Y, и мы собираемся использовать его повторно. Теперь нам нужно предсказать Cb и Cr: Cb — разница синего цвета и яркости, а Cr — разница красного цвета и яркости.
Почему мы выбрали представление YCbCr? Человеческий глаз более чувствителен к изменению яркости, чем к изменению цвета. Вот почему мы повторно используем компонент Y (яркость), к которому человеческий глаз наиболее чувствителен, и предсказываем Cb и Cr, с которыми мы можем ошибиться, поскольку мы не очень хорошо замечаем искажение цвета.
Где взять раскрашенные фотографии людей в военной форме? В Интернете есть люди, которые раскрашивают старые фотографии в качестве хобби или за плату. Они делают это очень осторожно, стараясь быть очень точными. Когда они раскрашивают форму, погоны и медали, то ссылаются на архивные материалы, поэтому результаты их работы вызывают доверие. Всего мы использовали 200 раскрашенных вручную картинок с людьми в военной форме.
Другим полезным источником данных является сайт Рабоче-Крестьянской Красной Армии. Один из ее основателей сфотографировался практически в каждой доступной советской форме времен Второй мировой войны.
На некоторых снимках он имитировал позы людей с известных архивных фотографий. Хорошо, что у его фотографий белый фон: это позволило нам очень хорошо дополнить данные, добавив на задний план различные природные объекты. Также мы использовали некоторые обычные портреты, дополнив их знаками различия и прочей атрибутикой военного времени.
Мы обучили AlbuNet-50 — это Unet, который использует предварительно обученный ResNet-50 в качестве кодировщика. Сеть начала давать адекватные результаты: кожа стала розовой, глаза — серо-голубыми, погоны — желтоватыми. Однако проблема заключалась в том, что он оставляет некоторые области на фотографии нетронутыми. Это было вызвано тем, что по ошибке L1 находится такой оптимум, при котором лучше ничего не делать, чем пытаться предсказать какой-то цвет.
Мы сравниваем наш результат с фотографией Ground Truth — ручной раскраской, сделанной Klimbim
Как мы можем решить эту проблему? Нам нужен дискриминатор: нейронная сеть, которая получит изображение и скажет нам, выглядит оно реалистично или нет. Одна из картинок ниже раскрашена вручную, а другая — нашим генератором AlbuNet-50. Как человек различает раскрашенные вручную и автоматически раскрашенные фотографии? Глядя на детали. Можете ли вы сказать, где находится фотография, автоматически раскрашенная нашим базовым решением?
Ответитькартинка слева раскрашивается вручную, справа — автоматически.
Мы используем дискриминатор из статьи Self-Attention GAN. Это небольшая сверточная сеть с так называемым самостоятельным вниманием, встроенным в верхние слои. Это позволяет нам «уделить больше внимания» деталям изображения. Мы также используем спектральную нормализацию. Более подробную информацию вы можете найти в вышеупомянутой газете. Мы обучили сеть с комбинацией потерь L1 и потерь от дискриминатора. Теперь сетка лучше прокрашивает детали изображения, а фон выглядит более цельным. Еще один пример: слева работа сети, обученной только с потерями L1; справа — с комбинацией потерь дискриминатора L1.Процесс обучения занял два дня на четырех GeForce 1080Ti. Сети требуется 30 мс для обработки изображения размером 512 x 512. Валидация MSE — 34,4. Как и в случае с рисованием, вы не хотите полагаться на показатели. Вот почему мы выбрали шесть моделей с лучшими показателями проверки и слепо проголосовали за лучшую модель.
Когда мы уже создали производственную систему и запустили веб-сайт, мы продолжили эксперименты и пришли к выводу, что лучше минимизировать не попиксельные потери L1, а потери восприятия. Чтобы рассчитать его, мы передаем прогнозы сети и реальную фотографию в сеть VGG-16, берем карты признаков на нижних слоях и сравниваем их с MSE. Этот подход закрашивает больше областей и дает более красочные результаты.
Unet — довольно крутая модель. На первом задании по сегментации мы столкнулись с проблемой при обучении работе с изображениями высокого разрешения и поэтому используем In-Place BatchNorm. Во второй задаче (Inpainting) мы использовали Partial Convolution вместо дефолтной, что позволило нам получить лучшие результаты. При работе над раскраской мы добавили небольшую сетку-дискриминатор, которая штрафовала генератор за нереалистичные изображения. Мы также использовали потерю восприятия.Второй вывод — необходимы оценщики. И не только на этапе создания масок сегментации, но и для проверки конечного результата. В итоге мы отдаем пользователю три фотографии: исходное изображение с закрашенными дефектами, раскрашенное фото с закрашенными дефектами и просто раскрашенное на случай, если алгоритм поиска дефектов и закрашивания ошибся.
Мы взяли несколько снимков из проекта «Военный альбом» и обработали их в этих нейросетях. Вот какие у нас получились результаты:
Кроме того, здесь вы можете более подробно ознакомиться с исходными изображениями и всеми этапами обработки.
funky town gore vk|TikTok Search
TikTok
Загрузитьpotybacon
Крис П. Бэкон
funky town goreобъяснение 9 0139 #foryoupage #fyp #roblox #capcut
132,7 тыс. лайков, 5,1 тыс. комментариев. Видео TikTok от Криса П. Бэкона (@poorybacon): «Веселая городская кровь объяснила #foryoupage #fyp #roblox #capcut». оригинальный звук — FuryBacon — Chris P. Bacon.
5,5 млн просмотров|
original sound — FuryBacon — Chris P. Bacon
the_flying_lamp29
ThatOneFlyingLamp
⚠️ALL FAKE⚠️ #gore #funkytown #funkytowngorevid
6,1 тыс. лайков, 430 комментариев. Видео в TikTok от ThatOneFlyingLamp (@the_flying_lamp29)): «⚠️ALL FAKE⚠️#gore #funkytown #funkytowngorevid». g0re | Фанкитаун | часть 1 | … Funkytown — Lipps Inc..
426,9 тыс. просмотров|
Funkytown — Lipps Inc.
kingtjay1113
TikTok
8,3 тыс. лайков, 1,8 тыс. комментариев. Видео в TikTok от ⠀ ⠀ ⠀ ⠀ ⠀ ⠀ (@kingtjay1113). оригинальный звук — ⠀ ⠀ ⠀ ⠀ ⠀ ⠀.
524,2 тыс. просмотров|
оригинальный звук — ⠀ ⠀ ⠀ ⠀ ⠀ ⠀ ⠀
liberandoaudiosgo
liberando audios gore
#gore #funktowngore #audio #foyou
1,1 тыс. лайков, 151 комментарий. Видео TikTok от liberando audios gore (@liberandoaudiosgo): «#gore#funktowngore#audio#foyou». либерандо аудио запекшаяся кровь funktown gore как оригинальный — liberando audios gore.
47,7 тыс. просмотров|
сом оригинал — liberando audios gore
hunterkoellerlove_999
Hunterxdusten😩😩
#fypシ #fypage #страшный #gore
8,8 тыс. лайков, 531 комментарий. Видео TikTok от Hunterxdusten😩😩 (@hunterkoellerlove_999): «#fypシ #fypage #scary #gore». оригинальный звук — Hunterxdusten😩😩.
660,6 тыс. просмотров|
original sound — Hunterxdusten😩😩
goreredtk
GoreFuck:
Parte 3 funky town gore🌚➡️ #fakebodyy⚠️ #funkytown #viraltiktok #fyp
18,6 тыс. лайков, 1,2 тыс. комментариев. Видео TikTok от GoreFuck: (@goreredtk): «Parte 3 funky town gore🌚➡️#fakebodyy⚠️ #funkytown #viraltiktok #fyp». оригинальный звук — GoreFuck:.
435,5 тыс. просмотров|
sonido original — GoreFuck:
goreboxbeta00
Gorebox player
Gorebox player (@goreboxbeta00) видео с 0-секундным звуком — randomguyfr | TikTok
25 лайков, видео TikTok от плеера Gorebox (@goreboxbeta00).