Министерство науки и высшего образования Российской Федерации
Федеральное государственное бюджетное образовательное учреждение
высшего образования
«Владимирский государственный университет
имени Александра Григорьевича и Николая Григорьевича Столетовых»
(ВлГУ)
ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ
РАБОТА
Студент
Рыжкова Мария Николаевна
Институт
прикладной математики, физики и информатики
Направление 02.03.01 – математика и компьютерные науки
Тема выпускной квалификационной работы:
Исследование нейросетевых методов для улучшения
качества изображений
Руководитель ВКР:
Абрахин С.И.
Студент:
Рыжкова М.Н.
Допустить выпускную квалификационную работу к защите
в государственной экзаменационной комиссии
Заведующий кафедрой:
« » июня 2020 г.
Бурков В.Д.
Министерство науки и высшего образования Российской Федерации
Федеральное государственное бюджетное образовательное учреждение
высшего образования
«Владимирский государственный университет
имени Александра Григорьевича и Николая Григорьевича Столетовых»
(ВлГУ)
УТВЕРЖДАЮ:
Зав. кафедрой
ЗАДАНИЕ
НА ВЫПУСКНУЮ КВАЛИФИКАЦИОННУЮ РАБОТУ
Студенту Рыжковой Марии Николаевне
1. Тема работы Исследование нейросетевых методов для улучшения качества
изображений.
утверждена приказом по университету № 151/4 от 02.03.2020 года.
2. Срок сдачи студентом законченной работы 11.06.2020
3. Исходные данные к работе Сверточная нейронная сеть Progressive Face
Super-Resolution, алгоритмы обучения нейронной сети, обучающая выборка
изображений, набор изображение для улучшения качества.
4. Содержание расчетно-пояснительной записки (перечень подлежащих
разработке вопросов):
Введение
1) Анализ предметной области
2) Проектирование и разработка нейронной сети
3) Анализ результатов ____________________________________
Заключение
Список использованных источников
5. Перечень графического материала (с указанием обязательных чертежей):
1) Исследование нейросетевых методов для улучшения качества
изоражений
2) Постановка задачи.
3) Обзор и обучение нейронной сети нейронной сети.
5) Формирование обучающей выборки.
__6)_Алгоритм обучения_____________________________________________________
__7) Разработка приложения________________________________________________
__8) Результаты исследования______________________________________________
9) Выводы.
6. Консультанты Кастэн Ю.А (нормоконтроль)
Дата выдачи задания
03.03.2020 года
Руководитель
(подпись)
Задание принял к исполнению
(подпись студента)
АННОТАЦИЯ
Целью выпускной квалификационной работы являлось исследование
нейронных сетей и разработка нейронной сети, позволяющей улучшать
качество изображений, на основе существующей нейросети. В процессе
работы проводились экспериментальные исследования по уменьшению
функций потерь и в следствии чего увеличения оценочных метрик. Основные
результаты работы показали, что изображение может быть улучшено на 3,8%.
Практическая значимость работы заключена в том, что данные разработки
можно использовать в определении лица человека.
Пояснительная записка содержит 73 с., 26 рис., 3 табл., 15 источников,
1 приложение.
SUMMARY
The purpose of the final qualification work was to study neural networks and
develop a neural network that allows improving the quality of images, based on the
existing neural network. In the course of the work, experimental studies were
conducted to reduce the loss functions and, as a result, increase the estimated
metrics. The main results showed that the image can be improved by 3.8%. The
practical significance of the work is that these developments can be used in
determining the person's face.
The explanatory note contains 73 pages, 26 figures, 3 tables, 15 sources, 1
Appendix.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
3
СОДЕРЖАНИЕ
Введение ........................................................................................................................... 6
1
Анализ предметной области .................................................................................... 8
1.1
1.1.1
Биологическая и математическая модель нейрона ................................... 8
1.1.2
Функции потерь и методы оптимизации ................................................. 15
1.1.3
Нейронная сеть ........................................................................................... 18
1.1.4
Сверточные нейронные сети ..................................................................... 21
1.2
Применение нейронных сетей для обработки изображений ....................... 25
1.2.1
Задача сегментации .................................................................................... 25
1.2.2
Задача сегментации .................................................................................... 26
1.2.3
Задача сжатия размерности ....................................................................... 26
1.2.4
Задача улучшения изображения ............................................................... 27
1.3
2
Понятия нейронной сети .................................................................................... 8
Обзор методов улучшения изображений ....................................................... 27
Проектирование и разработка нейронной сети для улучшения качества
изображений................................................................................................................... 30
2.1
Постановка задачи ............................................................................................ 30
2.2
Проектирование нейронной сети для улучшения качества изображений .. 31
2.2.1
Выбор и обоснование структуры сети ..................................................... 31
2.2.2
Нейронная сеть Progressive Face Super-Resolution.................................. 31
2.2.3
Нейронная сеть Very-Deep Super-Resolution ........................................... 34
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Разраб.
Рыжкова М.Н.
Пров.
Абрахин С.И..
Н. контр. Кастэн Ю.А.
Утв.
Бурков В.Д.
Подп.
Дата
11.06.20
11.06.20
Исследование нейросетевых
методов для улучшения качества
изображений.
11.06.20
Пояснительная
записка.
11.06.20
Литера
У
Лист
4
МКН-116
Листов
73
2.3
Показатели качества обучения нейронной сети ............................................ 36
2.4
Формирование обучающей выборки .............................................................. 39
2.5
Разработка приложения для реализации нейронной сети для повышения
качества изображений ............................................................................................... 41
2.5.1
Выбор и обоснование средств реализации нейронной сети .................. 41
2.5.2
Алгоритм приложения для улучшения качества изображений с
применением нейронной сети................................................................................ 41
2.5.3
Описание интерфейса приложения .......................................................... 43
3 Анализ результатов ............................................................................................. 45
3.1 Исследование изображения высокого качества......................................... 45
3.2 Исследование изображения среднего качества ......................................... 49
3.3 Исследование изображения низкого качества ........................................... 51
Заключение .................................................................................................................... 55
Список использованных источников .......................................................................... 56
Приложение А ............................................................................................................... 58
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Разраб.
Рыжкова М.Н.
Пров.
Абрахин С.И..
Н. контр. Кастэн Ю.А.
Утв.
Бурков В.Д.
Подп.
Дата
11.06.20
11.06.20
Исследование нейросетевых
методов для улучшения качества
изображений.
11.06.20
Пояснительная
записка.
11.06.20
Литера
У
Лист
5
МКН-116
Листов
73
ВВЕДЕНИЕ
В современном мире активно развивается новая область прикладной
математики, которая специализируется на нейронных сетях.
С помощью
нейросетей улучшаются программы, изображения, текст, создаются системы,
которые способны ускорять работу процессов и помогать в работе человеку. Их
основной целью является обучение системы самостоятельного принятия решений.
В чем особенно сильны нейронные сети, так это в обработке изображений.
При помощи них можно восстанавливать изображение лица в высоком разрешении
из его копий с низким разрешением. Это фундаментальная проблема в анализе
лица, которая может значительно облегчить задачи, которые связанны с
распознаванием людей по нечетким изображениям.
На данный момент изучение нейронных сетей, позволяющих улучшить
качество изображений является довольно актуальным. Существует огромное
количество
статей,
публикаций,
книг,
посвященных
изучению
способов
увеличения качества изображений. Авторами данных работ являются Subhasis
Chaudhuri, Yifan Wang, Yu Chen, Deokyun Kim, Чернявский А. В., Спицын В. Г. и
множество других ученых и разработчиков. По моему мнению, данные ученые
внесли большой вклад в разработку и продвижение нейросетевых методов,
позволяющих улучшать качество изображений.
На практике, нейронные сети, улучшающие качество изображения, могут
использоваться для обработки данных, получаемых в приборах и устройствах
медицинской диагностики, в определении лица человека, распознавании
движущихся объектов, дефектоскопии и в других аспектах жизни человека.
Целью моей выпускной квалификационной работы является исследование и
разработка нейронной сети, позволяющей улучшать качество изображений, на
основе существующей нейросети.
Для достижения поставленной цели было необходимо решить следующие
задачи:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
6
1)
Изучить общую структуру нейронных сетей, дать определение
функции потерь, изучить ее виды.
2)
Исследовать нейросети основанные на методе Super-Resolution (супер-
разрешения).
3)
Провести сравнительный анализ данных нейронных сетей.
4)
Выбрать некоторую структуру нейронной сети.
5)
Скомпоновать обучающую выборку.
6)
Рассмотреть возможность минимизации функции потерь без потери
качества изображения.
Объектом
данной
выпускной
квалификационной
работы
выступает
нейронная сеть Progressive Face Super-Resolution и компьютерной зрение.
Предметом исследования являются алгоритмы и математические модели,
позволяющие улучшать качество изображений. В работе использовались методы
компьютерного зрения, теории искусственных нейронных сетей и теория
планирования эксперимента.
Данная работа состоит из введения, основной части, заключения и
библиографического списка. Основная часть состоит из трех глав.
В первой главе, разделенной на несколько подпунктов, дается подробная
теория
про
нейронные
сети,
методы,
позволяющие
улучшать
качество
изображений и использование этих методов на практике.
Во второй главе описывается процесс разработки и улучшения нейронной
сети.
В третьей главе предоставляются результаты тестирования полученной
нейронной сети.
В заключении кратко сформулированы результаты, полученные в ходе
выполнения выпускной квалификационной работы.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
7
1
АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ
1.1 Понятия нейронной сети
1.1.1 Биологическая и математическая модель нейрона
Термин нейронные сети пришел в математику и компьютерные науки из
биологии.
Самым большим обработчик информации в человеке является нервная
система. Нервная система человека состоит из нескольких компонентов:
Мозг, который отвечает за обработку информации и принятии
1)
решений.
2)
Органы чувств, которые подают сигналы к мозгу.
3)
Мышцы, которые получают обработанные сигналы от мозга.
Все компоненты нервной системы, состоят из некоторого набора клеток,
называемые нейронами.
Нейроны имеют ядро или же тело, в котором накапливается электрический
заряд, от тела нейрона отходят небольшие отростки, называемые дендритами,
которые получают сигнал от других нейронов.
Так же есть большой отросток – аксон, по аксону нейрон передает сигнал к
другим нейронам.
Место где аксон нейрона соединяется с дендритом называется синапсом.
Синапс подразделяется на сильный и слабый. Если синапс сильный, то сигнал
переданный по аксону нейрона практически полностью перейдет к нейрону, на
который был подан сигнал, если же синапс слабый, то практически никакой заряд
не перетечет от аксона одного нейрона к другому.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
8
Синапс может изменяться со временем, в зависимости от обстоятельств,
может усиливаться, либо ослабляться. Именно с настройкой синапса связана
тренировка биологической нейросети.
Из определения биологического нейрона логически вытекает понятие
математической модели нейрона.
В математической модели нейрона, тело нейрона, где накапливается заряд,
заменяется на сумматор.
Добавляются входы в сумматор, которые заменяют дендриты.
Аксоном, в математической модели, служит выход, по которому нейрон
будет отправлять сигналы к другим нейронам.
Сила синапсов, то есть, сила соединения одного нейрона с другим
регулируется при помощи весов, которые навешаны на входы в нейрон.
Обозначаются веса буквой w.
Накопителем заряда является функция активации, в которой перед
отправкой сигнала к другим нейронам, нейрон будет обрабатывать этот сигнал,
который выходит из сумматора.
Благодаря функции активации, большое число, полученное на входе в
нейрон, может быть уменьшено до нужного диапазона.
Рассмотрим пример математической модели нейрона и некоторые функции
активации, которые можно использовать для описания нейрона.
Рисунок 1 – Математическая модель нейрона
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
9
Итак, пусть имеется три входа x0, x1, x2. Они приходят в сумматор, где
суммируются, и в итоге получается некоторый суммарный сигнал z.
Далее этот сигнал обрабатывается в функции активации f, и в итоге получаем
выход из нейрона y.
Функция активации принимает следующий математический вид:
y=f(z)=f(x0+x1+x2).
Однако, нужно учесть, что есть еще веса на входах в нейрон.
Поскольку синапс изменяется и обучение биологической нейронной сети
сводится к тому, что настраиваются синапсы, то, следовательно, введем
настраиваемые веса w0, w1, w2, которые навесим на входы в нейрон.
Тогда формула выхода у принимает вид:
y=f(z)=f(w0∙x0+w1∙x1+w2∙x2).
Данная функция является линейной, но не полной. Для того чтобы описать
все линейные функции добавим смещение b, которое так же является одним из
настраиваемых параметров в нейроне.
Так же, функцию y можно записать как:
y=f(z)=f(∑𝑁−1
𝑖=0 𝑤𝑖 ∙ 𝑥𝑖 + 𝑏),
или же y можно записать через скалярное произведение векторов:
y=f(z)=f(〈𝑤
⃗⃗ , 𝑥 〉 + 𝑏).
Функция активации в данном примере – пороговая. Эта функция имеет два
отличающихся друг от друга значения: 0 и 1.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
10
Разделяющая поверхность находится там, где аргумент функции активации
равен нулю. Именно в этом месте происходит смена значений функции активации.
1.1.1 Функции активации
Рассмотрим более подробно пороговую функцию активации. Данная
функция задает некоторую линейную операцию с двумя параметрами.
Из определения разделяющейся поверхности следует, что:
〈𝑤
⃗⃗ , 𝑥 〉 + 𝑏 = 0
(1)
Уравнение (1) задает некоторую прямую.
С одной стороны, от прямой, функция активации равна единицы, а с другой
стороны, функция равна нулю.
Функция активации равна единицы с той стороны от разделяющей
поверхности, в которую показывает вектор w.
Соответственно, с другой стороны, функция активации равна нулю. Таким
образом, разделяющая поверхность – это некоторая плоскость, которая задается
вектором w и смещением b.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
11
Рисунок 2 – Пороговая функция активации
Пороговая функция активации далеко не единственная и не самая лучшая
функция активации, которая встречается в нейронных сетях.
Для того, чтобы улучшить некоторые характеристики пороговой функции,
используют другую функция, у которой нет разрыва в точке 0. Эта функция
называется сигмоидой и задается следующей формулой:
𝜎(𝑥) =
1
1+𝑒 −𝑥
.
Рассмотрим случай, когда аргумент этой функции стремится к «плюс
бесконечности», то есть 𝑥 → +∞. Получаем, что значение сигмоиды стремится к
следующему. Когда x очень большой, то 𝑒 −∞ - это почти ноль. Соответственно,
𝜎(𝑥) → 1.
Рассмотрим другой случай, когда 𝑥 → −∞. В этом случае 𝑒 −(−∞) – это очень
большое положительное число, что означает, что сигмоида принимает значение
единица поделить на «очень большое положительное число» , то есть сигмоида –
это «очень маленькое число». Следовательно 𝜎(𝑥) → 0.
Сигмоида является всегда положительным числом, так как, во-первых,
функция экспоненты – это положительное число и, во-вторых, помимо экспоненты
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
12
присутствуют еще два положительных числа. Из этого следует, что в данной
функции никак не может возникнуть отрицательное число.
Кроме того, сигмоида не может быть больше единицы, так как 𝑒 −𝑥 – это
всегда положительное число и соответственно знаменатель никак не может быть
меньше единицы.
Когда x равен нулю, то сигмоида равна 0.5. Это достаточно просто проверить,
подставив в функцию значение 0, а так как 𝑒 0 = 1, то соответственно
𝜎(𝑥) =
1
1+1
1
= .
2
Рисунок 3 – Сигмоидная функция активации
Еще одной интересной функцией активации является гиперболический
тангенс:
f(x) =
𝑒 2𝑥 −1
.
𝑒 2𝑥 +1
Данная функция используется только в том случае, если имеются и
положительные и отрицательные значения.
Диапазон этой функции находится в пределах [−1, 1]. Эту функцию,
несколько нецелесообразно использовать только с положительными значениями,
так как это может очень сильно ухудшить результаты работы.[1]
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
13
Рисунок 4 – Функция активации гиперболический тангенс
Рассмотрим функцию активации softmax, которая задана следующим
образом:
𝑒 𝑦𝑖
𝑆𝑀𝑖 (𝑦) = ∑𝑁
𝑗=1 𝑒
𝑦𝑗
.
Берутся все выходы из сети и в эти степени возводится экспонента. После
этого, для того чтобы получить вероятность какого-то класса, берется экспонента,
которая соответствует этому классу и делится на сумму всех экспонент.
Рисунок 5 – Функция активации Softmax
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
14
Одним из главных свойств softmax функции является то, что она всегда
больше ноля и в то же время меньше единицы и сумма софтмаксов для всех классов
будет равна единицы. Это следует из того, что после суммирование в числителе и
знаменателе появляется общий множитель, который можно вынести за скобку.
1.1.2 Функции потерь и методы оптимизации
Для обучения нейрона используют функцию потерь или же, как ее еще
называют, loss-функцию. Данная функция дифференцируема и показывает
насколько хорошо проходит решение предоставленной задачи.
Одной из популярных и простых функций потерь является «средний квадрат
ошибки», по-английски – «mean squared error» или же просто MSE.
1
Функция выглядит следующим образом: MSE= ∑𝑁
̃𝑖 − 𝑦𝑖 )2 . Где 𝑦̃𝑖 - это
𝑖=1(𝑦
𝑁
то, что выдала нейронная сеть, и 𝑦𝑖 – это целевое значение, а (𝑦̃𝑖 − 𝑦𝑖 ) – это то,
насколько отклоняется результат.
Чем
меньше
будет
отклонение,
тем
меньше
будет
значение
среднеквадратичной ошибки, то есть значение функции потерь должно быть, как
можно меньше.
Не во всех задачах, решаемых нейросетями, можно использовать
среднеквадратичную ошибку. Например, в задаче бинарной классификации, где
нужно определить, что изображено на картинке.
В задаче с двумя классами и с сигмоидной функцией активации,
используется функция потерь, которая носит название «бинарная кросс-энтропия»
и имеет вид:
BCE(p, t) = −𝑡 log 𝑝 − (1 − 𝑡) log(1 − 𝑝), где p – это 𝜎(𝑦).
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
15
Бинарная кросс-энтропия – это функция потерь, которой хорошо оценивать
вероятности и любые значения, которые находятся в интервале от 0 до 1.
Не всегда в задаче бинарной классификации может быть только два класса
(«0» и «1»), иногда их достаточно много. Для решения этой задачи делается
несколько различных входов для каждого из классов.
Для задачи бинарной классификации с количеством классов больше двух
вводится функция потерь, которая называется «кросс-энтропия».
Кросс-энтропия имеет вид:
CE(p, t) = ∑𝑁
𝑐=1 𝑡𝑐 log 𝑝𝑐 ,
где
𝑡𝑐 - таргетное значение для класса,
𝑝𝑐 - вероятность этого класса.
То есть вероятность класса это софтмакс от выходов из нейронной сети, а
таргетное значение для класса – это ноль для почти всех классов кроме одного,
который присутствует на картинке.
Loss-функция нужна для того, чтобы нейронная сеть могла понимать, в
какую сторону ей нужно двигаться, чтобы улучшать свои результаты. Но для того
чтобы производить эти движения, нужны оптимизаторы или как их еще называют
методы оптимизации.
Наиболее распространенным и наиболее простым оптимизатором является
градиентный спуск.
Градиент функции – это вектор, который, составлен из производных по всем
направлениям, просчитанных в текущей точке. Он имеет вид:
𝜕𝑓
∇𝑓 =
𝜕𝑤0
𝜕𝑓
𝜕𝑤1
…
.
𝜕𝑓
[𝜕𝑤𝑛 ]
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
16
Градиентный спуск ищет точки минимума или максимума в сложных
функциях.
Для того, чтобы улучшить нейронную сеть с помощью градиентного спуска,
рассчитывается градиент в некоторой выбранной точке, а затем делается шаг в
направлении, которое противоположно направлению градиента.
Например, в точке w0, которая является некоторым большим вектором, в
который сложены параметры нейросети, считаем производную loss-функции по
всем параметрам и складываем ее в вектор.
Получаем вектор и из него делаем шаг – изменяем параметры следующим
образом: 𝑤 1 = 𝑤 0 − 𝛼∇𝑓(𝑤 0 ), то есть берем имеющийся параметр 𝑤 0 и вычитаем
из него параметр 𝛼, который называется «скоростью обучения», умноженный на
градиент от функции потерь в точке текущих параметров.
Таким образом получается новая точка и новые параметры 𝑤 1 .
Точка, в которой оказались, так же не идеальна, то есть ее можно тоже
улучшить. Для этого нужно посчитать градиент в данной точке и опять же сделать
шаг в противоположном градиенту направлении. И таким образом можно
продолжать делать расчеты много раз.
В результате получается последовательность параметров, каждый из которых
немного
улучшает
предыдущий
параметр
и,
в
конце
концов,
эта
последовательность сойдется к некоторому параметру 𝑤 𝑡+1 = 𝑤 𝑡 − 𝛼∇𝑓(𝑤 𝑡 ), в
котором градиент будет достаточно маленьким.
Это будет означать, что нейросеть достаточно хорошо выучилась и может
хорошо решать поставленную задачу.
Одним из недостатков градиентного спуска является то, что для того чтобы
посчитать направление, в котором нужно производить спуск, нужно посчитать
значение и градиент loss-функции по всем обучающим примерам.
Для того, чтобы схождение было быстрым и при этом не тратилось много
времени для подсчета следующего шага, применяются модификации градиентного
спуска:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
17
a)
𝐸𝑀𝐴𝑝 (𝑓)𝑡 = (1 − 𝑝)𝑓 𝑡 + 𝑝𝐸𝑀𝐴𝑝 (𝑓)𝑡−1
–
экспоненциальное
скользящее среднее (англ. Exponential Moving Average)
b)
𝑅𝑃𝑟𝑜𝑝 – метод, который учитывает знак градиента. Данный метод
имеет вид 𝑤𝑖𝑡+1 = 𝑤𝑖𝑡 − 𝛼𝑖𝑡 𝑠𝑖𝑔𝑛(∇𝑓𝑖 (𝑤 𝑡 )).
c)
Алгоритм RProp плохо работает батчами. Для решения данной
проблемы используется алгоритм 𝑅𝑀𝑆𝑃𝑟𝑜𝑝. Данный алгоритм имеет вид 𝑤𝑖𝑡+1 =
𝑤𝑖𝑡 − 𝛼
d)
∇𝑓(𝑤 𝑡 )
√𝐸𝑀𝐴𝛾 (∇𝑓2 )𝑡
.
Алгоритм Adam (англ. Adaptive moment estimation) – это такой
алгоритм, в котором не нужно подбирать параметры.
e)
Данный алгоритм имеет следующий математический вид:
𝑤𝑖𝑡+1 = 𝑤𝑖𝑡 − 𝛼
f)
𝐸𝑀𝐴𝛽1 (∇𝑓)𝑡
√𝐸𝑀𝐴𝛽2 (∇𝑓2 )𝑡 +𝜀
.
Параметры оптимальные, как правило – следующие: скорость
обучения равна 3 ∙ 10−4 , параметр скользящего среднего в числителе – 𝛽1 =
0.9, 𝛽2 = 0.999.
1.1.3 Нейронная сеть
Связка из большого количества нейронов, организованная слоями и
соединенная синапсами, называется нейронной сетью.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
18
Нейросети могут иметь в своей структуре от одного до нескольких слоев и
соответственно классифицируются как однослойная или многослойная сеть.
Однослойная нейронная сеть (англ. single layer network) состоит из входного
слоя нейронов (input layer) и выходного слоя нейронов (output layer).
Задачей входного слоя является передача сигнала из внешней среды в
нейронную сеть.
Нейроны входного слоя не выполняют никаких вычислений, поэтому, при
подсчете количества слоев, нейроны входного слоя игнорируются.
Все вычисления нейронной сети обычно выполняются в нейронах выходного
слоя, благодаря чему они также называются вычислительными узлами сети.
Однослойная нейронная сеть относится к сетям с прямым распространением
сигнала (feedforward), так как сигнал проходит от входного слоя к выходному без
обратных связей. [2]
Рисунок 6 – Структура однослойной сети
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
19
Многослойная нейронная сеть состоит из входного слоя нейронов (input
layer), выходного слоя нейронов (output layer) и одного или нескольких скрытых
слоев (hidden layer) между ними.
Скрытый слой нейронов выполняет функцию посредника между входным и
выходным слоем нейронов.
Узлы входного слоя формируют входной сигнал, поступающий на нейроны
второго слоя (т.е. первого скрытого слоя). Выходные сигналы второго слоя
используются в качестве входных для третьего слоя и т.д.
Набор выходных сигналов последнего слоя нейронов определяют общий
отклик сети на заданный входной образ, сформированный узлами первого
(входного) слоя. [2]
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
20
Рисунок 7 – Структура многослойной сети
1.1.4 Сверточные нейронные сети
Сигмоидные нейронные сети – полны, то есть можно приблизить любую
функцию при помощи обыкновенных сигмоидных нейронных сете.
Несмотря на то, что сигмоидные нейросети могут подогнать любую
функцию, которая удовлетворяет некоторому списку требований (ограниченность,
конечное число разрывов, и т.д.), у обыкновенных нейронных сетей возникают
большие трудности со структурированными данными, например, с изображениями.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
21
При помощи свертки решается проблема ограниченности вычислительных
ресурсов.
Свертка так же решает задачу учета дополнительной информации о
структуре данных, то есть она учитывает, какие пиксели находятся рядом с какими.
Сверточными сети называются из-за операции свертки.
Рассмотрим некоторое изображение. Оно будет состоять из одного канала,
будет размером 5×5 и будет состоять из некоторых целых чисел. Запишем это
изображение, результат представлен на рисунке:
5
3
6
4
3
2
1
2
7
6
3
1
1
2
2
1
0
0
1
2
-2
4
-1
0
1
Рисунок 8 – Изображение, представленное в виде чисел
Свертка изображения проводится следующим образом: берем некоторую
маску, например, с цифрами (1 0 -1); (0 1 0); (-1 0 1), но, в целом, числа могут быть
любыми. Данная маска называется - «ядро свертки».
Далее над изображением производится следующая операция: к исходному
изображению добавляются нули. Представленные нули называются - «паддинг»
(padding), или отступ. Если этот падиннг не делать, то максимальное изображение,
которое можно получить в результате операции свертки, будет 3 на 3.
0
0
0
0
0
0
0
0
5
2
3
1
-2 0
0
3
1
1
0
4
0
6
2
1
0
-1 0
0
4
7
2
1
0
0
0
3
6
2
2
1
0
0
0
0
0
0
0
0
0
Рисунок 9 – Отступ в матрице чисел изображения
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
22
Берем маску и прикладываем ее к некоторой позиции в изображении.
Пермножаем коэффициенты из маски со значениями пикселей на изображении, и
получаем некоторый результат. Дальше мы так же поступаем со следующей
позицией, то есть передвигаем маску на один пиксель вправо и так далее.
В
итоге
преобразований
мы
получим
следующие
результаты,
представленные на рисунке 10. (Цветными линиями отмечены положения на
разных шагах).
0
0
0
0
0
0
0
0
5
2
3
1
-2
0
0
3
1
1
0
4
0
0
6
2
1
0
-1
0
0
4
7
2
1
0
0
0
3
6
2
2
1
0
0
0
0
0
0
0
0
1
0
-1
0
1
0
-1
0
1
6
0
2
4
-2
3
-2
0
3
5
12
1
-4
-5
-2
8
11
0
2
-2
-4
8
8
4
-2
Рисунок 10 – Свертка изображения
Получившийся результат не совпадает с исходным изображением, но, при
этом, у него такой же размер.
Как правило, изображение является трехканальным, то есть, там есть
красный, синий и зеленый цвет. Для каждого из этих цветов есть некоторая
матрица, которая описывает, сколько зеленого, красного и синего цвета в каждом
пикселе.
В случае с трехканальными изображениями, ядро свертки - это трехмерная
табличка, а не двумерная, как в предыдущем случае. Для каждого канала это такая
же табличка, как в прошлом примере и для каждого канала эти различные таблички
продублированы. Стоит отметить, что все эти таблички для каждого канала могут
быть разными. Соответственно, для каждого цвета маски могут отличаться.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
23
Мы берем трехмерную табличку и прикладываем к какому-то месту
изображения. И дальше берем значение изображения, перемножаем поэлементно
со значения в фильтре и складываем.
В нейронных сетях к получившемуся значению прибавляется некоторое
значение, которое называется «bias» - смещение. И записываем в соседнюю ячейку.
И вот таким образом заполняется результат, строка за строкой.
Так как в сверточном слое может быть много фильтров, то в этом случае мы
берем тот же вход, но теперь совсем другой фильтр и какое-то значение смещения.
Прикладываем этот фильтр в каждое положение, считаем произведение
поэлементное, складываем результаты и прибавляем смещение.
И вот таким образом, получаем следующий канал на выходе. Каналов на
выходе может быть достаточно много – столько, сколько фильтров применяется к
входному изображение.
В сверточных нейронных сетях применяются два типа элементов. Первый
элемент был уже рассмотрен – это сверточный слой. А второй элемент – это
«pooling» слой.
Рассмотрим, что такое pooling слой.
Pooling работает следующим образом.
Рассмотрим pooling размером 2×2, со страйдом 2×2. Что означает pooling
размером два на два? Это означает, что мы выбираем из изображения четыре
пикселя, которые расположены внутри прямоугольника размером 2 на 2. Из этого
изображения выбираем максимальное значение.
Пример:
5
2
3
1
3
1
1
0
6
2
1
0
4
7
2
1
5
7
3
2
Рисунок 11 – Свертка Pooling
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
24
По умолчанию, размер пулинга совпадает со страйдом, то есть не берется
pooling из пересекающихся областей.
Max pooling – это не единственный pooling, который используется в глубоком
обучении.
Так же использутся несколько других. Например, с тем же успехом можно
использовать minimum pooling и, например, можно использовать average pooling,
который будет просто усреднять то, что находится внутри рамочки.
Стоит отметить, что если у входа несколько каналов, то max pooling делается
по каждому каналу независимо. То есть, мы берем один канал, применяем к нему
max pooling, получаем какой-то результат. Берем следующий канал, опять же
применяем к нему max pooling, получаем следующий результат.
Вот таким образом работает pooling, это довольно простая операция, но она
позволяет сильно экономить память, а также это очень важный слой для глубокого
обучения.
1.2 Применение нейронных сетей для обработки изображений
Наиболее часто изучаемыми и используемыми в обработке изображений
являются нейронные сети, решающие задачи локализации, сегментации, сжатия
размерности и улучшения качества изображения.
1.2.1 Задача локализации
Дано какое-либо изображение и на этом изображении где-то есть объект,
который нужно найти. Для того чтобы решить данную задачу нужно построить
нейросеть, которая будет принимать на вход изображение и выдавать пять
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
25
выходов: первый выход должен соответствовать вероятности найти нужный объект
на представленном изображении, второй и третий выходы должны обозначать
центр, где находится объект на изображении, четвертый и пятый выход должны
обозначать, какого размера нужный объект.
1.2.2 Задача сегментации
Следующая интересная задача – это задача сегментации. Допустим, имеется
какое-то изображение, на этом изображение присутствует определенный объект и
нужно отделит те пиксели, на которых присутствует этот объект, от пикселей, на
которых его нет, то есть отделить объект от фона.
Что должна выдавать такая нейросеть? Эта сеть выдает изображение, которое
состоит из «скоров» (score) того, что в каждом из пикселей есть ил нет объекта.
Для решения этой задачи можно использовать сигмоидную функцию
активации, которая будет просто переводить действительные значения, которые
предсказывает нейросеть, в интервал от нуля до единицы, и соответственно для
каждого
пикселя
будет
предсказываться
вероятность
что
этот
пиксель
принадлежит объекту.
Следовательно, при такой функции активации самым оптимальным
вариантом будет использовать loss-функцию – бинарная кросс-энтропия 𝐿 =
𝐵𝐶𝐸(𝜎(𝑦𝑗 ), 𝑡𝑗 ). И эта бинарная кросс-энтропия будет считаться в каждом пикселе
и складываться по всей картинке.
1.2.3 Задача сжатия размерности
Рассмотрим задачу сжатия размерности. Сжатие размерности – это задача,
которая попадает в разряд задач, которые называют «задачи обучения без учителя».
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
26
Имеется некое изображение, на котором очень много информации. Нужно
сделать так, чтобы эта информация содержалась в каком-то небольшом количестве
чисел. Как это можно сделать?
Предлагается сделать так: сделать сеть, которая будет называться
«кодировщиком», которая будет выдавать сжатое представление картинки, которое
по некоторым историческим причинам называется «эмбеддингом» (embedding).
Это сжатое представление позже будет расшифровываться при помощи сети,
которая называется «декодировщик». [3]
В результате, должна получиться точно такое же изображение, что было на
входе.
1.2.4 Задача улучшения изображения
Следующая задача – это задача улучшения качества изображения. Задача
улучшения изображения заключается том, чтобы из изображения с очень низким
разрешением, с помощью нейронной сети, получилось изображение с высоким
качеством. Она основывается на методе Super-Resolution, который будет описан в
следующем пункте.
1.3 Обзор методов улучшения изображений
Существует достаточно много нейросетевых методов, позволяющих
улучшать изображения.
Например, нейронные сети, которые получая на вход изображение, внутри
себя с помощью попиксельной коррекции света, тени, яркости и контраста, заметно
повышают качество изображения. Но существуют и более глубокие, сложные
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
27
методы, позволяющие улучшать изображения, они основываются на сверточных
нейронных сетях.
Рассмотрим один из таких методов. Данный метод называется SuperResolution, что в переводе с английского, означает супер-разрешение.
Супер-разрешение
–
это
процесс
улучшения
и
масштабирования
изображения. Он заключается в следующем: имеется на входе какое-то
изображение с очень низким разрешением и это изображение масштабируется до
более высокого разрешения, которое является выходным. То есть полученное на
выходе изображение становится более детализировано [4].
Проблема, которую пытается решить Super-Resolution на основе глубокого
обучения, заключается в том, что в традиционных методах масштабирования,
отсутствуют мелкие детали и они не могут удалять артефакты и дефекты сжатия.
Для людей, которые выполняют данные алгоритмы масштабирования вручную, это
довольно долгий и трудоемкий процесс.
Преимущество метода Super-Resolution, заключается в получении более
высокого качества изображения из того, где высокое качество никогда не
существовало или было потеряно, это может быть полезным во многих областях
жизни, а также в спасении жизни в медицинских приложениях.
Для того, чтобы получить высокое разрешение, берется математическая
функция от изображения с низким разрешение, в котором отсутствуют детали, и
галлюцинирует эти детали и особенности, то есть добавляет детали, которые
потенциально не записываются камерой.
Эта математическая функция известна как модель, а увеличенное
изображение является предсказанием модели.
Целью
задачи
с
использованием
метода
Super-Resolution
является
минимизация функции потерь при реконструкции изображения, но в результате
улучшения качества часто теряется точность воспроизведения. Чаще всего в этом
методе используются попиксельные функции потерь, например, такие, как
улучшенные среднеквадратичные ошибки.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
28
Большинство нейронных сетей, основанных на глубоком обучении моделей
супер-разрешения, обучаются с использованием порождающих состязательных
сетей (GAN)
Но одним из ограничений GAN является то, что они несколько «ленивы», то
есть, их функция потери, обучается как часть процесса и не предназначена
специально для этой цели. Это может быть одной из причин того, что многие
модели хороши только с супер-разрешением, а не с исправлением изображения.
Так же многие методы Super-Resolution глубокого обучения нельзя
применять универсально ко всем типам изображений, и почти у всех есть свои
недостатки. Например, модель, обученная для супер-разрешения животных, может
не подходить для супер-разрешения человеческих лиц.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
29
ПРОЕКТИРОВАНИЕ И РАЗРАБОТКА НЕЙРОННОЙ СЕТИ ДЛЯ
2
УЛУЧШЕНИЯ КАЧЕСТВА ИЗОБРАЖЕНИЙ
2.1 Постановка задачи
Целью
данной
выпускной
квалификационной
работы
является
проектирование разработка и обучение нейронной сети, позволяющей улучшать
качество изображений.
Исходными данными к работе являются: сверточная нейронная сеть
Progressive Face Super-Resolution, алгоритмы обучения нейронной сети, обучающая
выборка изображений, на основе существующей нейросети, а также сравнение
эффективности с другими моделями.
В ходе работы необходимо провести исследование параметров нейронной
сети (функции активации, алгоритм обучения и матрица нормализации) влияющих
на качество улучшения изображений и подобрать их оптимальное соотношение для
повышения качества изображений.
Для достижения поставленной цели необходимо решить следующие задачи:
1)
Провести анализ предметной области.
2)
Провести выбор и обоснование структуры нейронной сети для
улучшения качества изображений.
3)
Сформировать показатели качества обучения нейронной сети для
улучшения качества изображений.
4)
Сформировать обучающую выборку для обучения нейронной сети для
улучшения качества изображений.
5)
Разработать приложение для реализации нейронной сети для
повышения качества изображений.
6)
Провести исследование параметров нейронной сети для повышения
качества улучшения изображений.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
30
7)
Провести анализ полученных результатов.
2.2 Проектирование нейронной сети для улучшения качества изображений
2.2.1 Выбор и обоснование структуры сети
Рассмотрим нейронные сети, позволяющие улучшать качество изображений.
2.2.2 Нейронная сеть Progressive Face Super-Resolution
Одной из таких нейросетей является сеть, которая носит название Progressive
Face Super-Resolution. Данная сеть основана на методе Super-Resolution.
Progressive Face Super-Resolution или же сокращенно PFSR является
сверточной нейронной сетью, которая позволяет улучшать качество изображения
лица в восемь раз.
Изучим ее более подробно.
Итак, данная нейронная сеть основывается на прогрессивном методе
обучения, который растет как генератор или дискриминатор постепенно. Так же
ограничиваются входные данные, путем применения потери внимания на каждом
шаге, что позволяет выходным изображениям каждого шага отражают более
точные детали лица. Для того, чтобы получить потерю внимания, используются
тепловые карты, которые извлекаются из предварительно обученной сети для
выравнивания лица. Следовательно, извлеченные тепловые карты используются в
качестве весов разности пикселей смежных областей с ориентирами.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
31
Для оценки измеряется производительность метода, как на выровненных, так
и на не выровненных изображениях лиц. И чтобы сравнить качество полученных
результатов вычисляется измерение среднего пикового отношения сигнал/шум
(PSNR), структурное сходство (SSIM) и многомасштабное структурное сходство
(MS-SSIM).
Рассмотрим функции потерь, использованные в данной нейронной сети.
Первая функция потерь – поточечная среднеквадратичная ошибка MSE,
которая используется для минимизации расстояния между целевым изображением
и сверхразрешенным. Она задана следующим уравнением:
Lpixel =
1
𝑟 2 𝐻𝑊
𝑟𝐻
𝐻𝑅
𝐿𝑅
2
∑𝑟𝑊
𝑥=1 ∑𝑦=1(𝐼𝑥,𝑦 − 𝐺(𝐼 )𝑥,𝑦 ) .
Следующая функция потерь – это потеря восприятия. Она предлагается для
предотвращения создания размытых и нереалистичных изображений лица. Потери
на данном слое i определяются как:
𝐿𝑓𝑒𝑎𝑡/𝑖 =
1
𝑊𝑖 𝐻𝑖
𝐻𝑖
𝑖
𝐻𝑅 )
𝐿𝑅
2
∑𝑊
𝑥,𝑦 − 𝜑𝑖 (𝐺(𝐼 ))𝑥,𝑦 ) .
𝑥=1 ∑𝑦=1(𝜑𝑖 (𝐼
Третья функция потерь – потеря состязательности. Она используется для
стабилизации тренировочного процесса. Данная функция потерь определяется как
расстояние Вассерштейна между распределением исходных и распределением
сгенерированных изображений. Так же для повышения стабильности обучения в
данной
функции
применяется
термин
«градиентный
штраф»,
который
обеспечивает условие Липшица и является случайно выбранным изображением.
Следовательно, функция потерь выглядит следующим образом:
2
𝐿𝑊𝐺𝐴𝑁 = 𝔼𝐼𝐻𝑅~𝑃𝑟 [𝐷(𝐼 𝐻𝑅 )] − 𝔼ℸ~𝑃𝑔 [𝐷(𝐼̃)] + 𝜆𝔼𝐼̂~𝑃𝐼̂ [‖∇𝐼̂ 𝐷(𝐼̂)2 − 1‖ ].
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
32
И четвертая, последняя функция потерь – это потеря тепловой карты. Потеря
тепловой карты улучшает структурную согласованность изображения лица, сводя
к минимуму расстояние между тепловыми картами как сгенерированных
изображений, так и целевых. Функция потери тепловой карты описывается как:
𝐿ℎ𝑒𝑎𝑡𝑚𝑎𝑝 =
где
1
𝑟 2 𝑁𝑊𝐻
𝑟𝑊
𝑟𝐻
𝑛
̃𝑛 2
∑𝑁
𝑛=1 ∑𝑥=1 ∑𝑦=1(𝑀𝑥,𝑦 − 𝑀𝑥,𝑦 ) ,
N - количество ориентиров,
̃ рассчитываются, как 𝑀 = 𝐹𝑑 (𝐼 𝐻𝑅 ), а 𝑀
̃ = 𝐹𝑑 (𝐺 (𝐼 𝐿𝑅 )).
Mи𝑀
Суммарные потери обучения выглядят следующим образом:
𝐿𝑜𝑢𝑟𝑠 = 𝛼𝐿𝑝𝑖𝑥𝑒𝑙 + 𝛽𝐿𝑓𝑒𝑎𝑡 + 𝛾𝐿𝑊𝐺𝐴𝑁 ,
для первого выхода.
И для второго и третьего выхода суммарная функция потерь:
𝐿𝑜𝑢𝑟𝑠 = 𝛼𝐿𝑝𝑖𝑥𝑒𝑙 + 𝛽𝐿𝑓𝑒𝑎𝑡 + 𝛾𝐿𝑊𝐺𝐴𝑁 + 𝜆𝐿ℎ𝑒𝑎𝑡𝑚𝑎𝑝 + 𝜂𝐿𝑎𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛 .
Для того чтобы наблюдать эффекты изменения каждого элемента данной
нейронной сети, проводится исследование абляции, использую обычные
измерения среднего PSNR, SSIM и MS-SSIM. Минимизация среднеквадратичной
ошибки максимизирует PSNR, который обычно используется для оценки
результатов Super-Resolution. Поскольку PSNR определяется только на основе
пиксельных различий, значение PSNR имеет ряд ограничения для представления
воспринимаемых значимых различий. Поэтому дополнительно измеряется SSIM и
MS-SSIM.
Если сравнить результаты работы данной модели с state-of-the-art
решениями, получается, что данная нейронная сеть почти по всем метрикам выдает
более точные результаты. [5]
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
33
2.2.3 Нейронная сеть Very-Deep Super-Resolution
Рассмотрим еще одну нейросеть. Она называется Very-Deep Super-Resolution
(VDSR). В отличии от предыдущей данная нейронная сеть улучшает изображения
в целом, а не только изображения лиц.
VDSR является сверточной нейронной сетью, которая была спроектирована
для улучшения одного изображения методом Super-Resolution. Она так же
обучается отображению между изображениями с низким разрешением и
изображениями с высоким разрешением. Такое отображение возможно, потому что
изображения с высокой и низкой разрешающей способностью имеют похожее
содержимое изображения и если и отличаются то, в основном, по высокочастотным
деталям.
В VDSR используется остаточная стратегию обучения, это означает, что сеть
учится оценивать остаточное изображение.
В контексте Super-Resolution остаточное изображение - это различие между
ссылочным изображением с высоким разрешением и изображением с низкой
разрешающей способностью, в котором был увеличен масштаб с помощью
бикубической интерполяции, для того, чтобы изображение с низкой разрешающей
способностью совпадало с размером ссылочного изображения. В остаточном
изображении содержится информацию о высокочастотных деталях изображения.
Обучение данной сети проходит с помощью оптимизатора, который
представлен в виде стохастического градиентного спуска с импульсом
оптимизации (SGDM).
VDSR имеет лучшие метрические данные, чем та же бикубическая
интерполяция для каждого масштабного коэффициента, но если сравнивать
данную сеть с предыдущей, учитывая то, что данная нейросеть так же может
улучшать лицевые изображения, так как, она является универсальной, то по
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
34
многим параметрам эта сеть несколько проигрывает предыдущей нейронной сети
PFSR.
В результате данного обзора аналогов в качестве опытного образца была
выбрана сеть Progressive Face Super-Resolution.
Данная модель почти по всем метрикам выдает более точные результаты,
также она основана на методе Super-Resolution и базируется на методе
прогрессивного обучения, который позволяет стабильно обучать модель и делить
ее на части: генератор и дискриминатор.
Генератор и дискриминатор обучается стабильно, благодаря шагам обучения.
Генератор
состоит
из
3-х
residual
блоков
с
batch
нормализацией,
транспонированных сверточных слоев и активационной функцией ReLU.
Дискриминатор имеет схожую с генератором архитектуру: сверточные слои, слой
average pooling слои и функция активации Leaky ReLU.
Каждая из частей принимает на вход результат предыдущей нейросети, и
выдает
еще
более
точную
реконструкцию
лица.
Так,
изображение
реконструируется постепенно. На вход подаются два вида изображений:
выровненные изображения лица и изображения без обработки.
Сетевая структура нейросети отображена на рисунке 12.
Рисунок 12 – Сетевая структура нейросети Progressive Face Super-Resolution
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
35
2.3 Показатели качества обучения нейронной сети
Рассмотрим
объективные
техники
измерения,
которые
моделируют
результаты субъективной оценки качества.
Итак, первая метрика – это пиковое отношение сигнала к шуму (англ. peak
signal-to-noise ratio) или же, как она еще обозначается, аббревиатурой PSNR.
Данная метрика означает соотношение между максимумом значения сигнала
и мощностью шума, который искажает этот сигнал. PSNR измеряется в
логарифмической шкале в децибелах.
Чаще всего она используется для измерения искажений при сжатии
изображения.
Определяется через среднеквадратичное отклонение (MSE), которое
вычисляется, для двух монохромных изображений I и K размера m на n, причем
одно из данных изображений считается зашумленным приближением другого,
следующим образом:
𝑚−1 𝑛−1
1
𝑀𝑆𝐸 =
∑ ∑ |𝐼(𝑖, 𝑗) − 𝐾(𝑖, 𝑗)|2
𝑚𝑛
𝑖=0 𝑗=0
Следовательно, PSNR вычисляется следующим образом:
𝑃𝑆𝑁𝑅 = 10 log10 (
𝑀𝐴𝑋𝐼2
√𝑀𝑆𝐸
) = 20 log10
𝑀𝐴𝑋𝐼
√𝑀𝑆𝐸
,
где MAXI – максимальное значение, которое может быть принято пикселем
изображения.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
36
В том случае, когда пиксели будут иметь разрядность 8 бит, максимальное
значение MAXI будет равно 255.
В общем же случае, когда значение сигнала будет представлено линейно с N
битами на значении, то максимально возможное значение MAXI будет иметь вид
2N-1.
Для изображений в цвете с тремя компонентами RGB на пиксель будет
применяться так же PSNR, но MSE будет считаться по всем трем компонентам и
делиться на утроенное изображение. [6]
Теперь рассмотрим метрику структурного сходства (англ. Structural
SIMilarity) или же SSIM.
Данная метрика является более сложной и точной альтернативой PSNR. Она
может лучше коррелироваться с ощущаемым качеством сжатого изображения.
Берем i-ый кадр с некоторым размером P на R и значением компонент
(𝑖)
1
1
𝑃
𝑅
яркости 𝑌𝑝,𝑟 𝑃 = и 𝑅 = .
Выбираем окно W и веса wj нормируются на единицу, то есть ∑ 𝑤𝑗 = 1.
Обычно выбирается квадратное окно, в котором веса распределены
симметрично относительно некоторого центра по Гауссу.
По следующим формулам вычисляются средневзвешенные значения
компоненты
яркости
начального
и
закодированного
(𝑖)
окна 𝑌 𝐴𝑉𝐺𝑝,𝑟 ,
средневзвешенные дисперсии компоненты яркости начального и закодированного
(𝑖)
окна 𝑌 𝑉𝐴𝑅𝑝,𝑟 и средневзвешенная ковариация между компонентами яркости
(𝑖)
начального и закодированного окон 𝑌 𝐶𝑂𝑉𝑝,𝑟 :
(𝑖)
|𝑖|
𝐽
𝑌 𝐴𝑉𝐺𝑝,𝑟 = ∑𝑗=1 𝑤𝑗 ∗ 𝑌𝑝,𝑟(𝑗) ,
(𝑖) 2
𝐽
|𝑖|
(𝑖)
𝑌 𝑉𝐴𝑅𝑝,𝑟 = ∑𝑗=1 𝑤𝑗 ∗ (𝑌𝑝,𝑟(𝑗) − 𝑌 𝐴𝑉𝐺𝑝,𝑟 )2 ,
(𝑖)
(𝑖)
(𝑖)
|𝑖|
|𝑖|
𝐽
𝑌 𝐶𝑂𝑉𝑝,𝑟 = ∑𝑗=1 𝑤𝑗 ∗∗ (𝑌𝑝,𝑟(𝑗) − 𝑌 𝐴𝑉𝐺𝑝,𝑟 ) ∗ 𝑖(𝑌𝑝,𝑟(𝑗) ′ − 𝑌 𝐴𝑉𝐺𝑝,𝑟 ′),
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
37
|𝑖|
где 𝑌𝑝,𝑟(𝑗) - значение компоненты яркости в j-ой точке окна, центр у которого
расположен в точке с координатами (p, r) i-го кадра.
Рассчитаем значение метрики SSIM в точке:
(𝑖) ′
(𝑖)
(2∗ 𝑌 𝐴𝑉𝐺𝑝,𝑟 ∗ 𝑌 𝐴𝑉𝐺𝑝,𝑟 +𝑐1 )
𝑌
где
(𝑖)
𝑆𝑆𝐼𝑀𝑝,𝑟
(𝑖)
∗(2∗𝑌 𝐶𝑂𝑉𝑝,𝑟 +𝑐2 )
=
(𝑖) 2
(𝑖)′ 2
(𝑖) 2
(𝑖) ′ 2
,
( 𝑌 𝐴𝑉𝐺𝑝,𝑟 + 𝑌 𝐴𝑉𝐺𝑝,𝑟 +𝑐1 )∗(𝑌 𝑉𝐴𝑅𝑝,𝑟 + 𝑌 𝑉𝐴𝑅𝑝,𝑟 +𝑐2 )
𝑐1 = (𝑝1 ∗ 𝑀𝐴𝑋𝑌 )2 ,
𝑐2 = (𝑝2 ∗ 𝑀𝐴𝑋𝑌 )2 ,
𝑀𝐴𝑋𝑌 – это максимально возможное значение компоненты Y.
Метрика MS-SSIM (Multi-Scale SSIM) – модификация SSIM. Она оценивает
не только исходное значение, но и его уменьшенные варианты.
Значение метрики рассчитывается следующим образом:
𝑀𝑆 − 𝑆𝑆𝐼𝑀(𝑥, 𝑦) = [𝑙𝑀 (𝑥, 𝑦)]𝛼𝑀 ∗ ∏𝑀
𝑗=1[𝑐𝑗 (𝑥, 𝑦)]
где
𝛽𝑗
𝛾𝑗
∗ [𝑠𝑗 (𝑥, 𝑦)] ,
𝑗 ∈ [1, 𝑀] – это порядковый индекс текущего масштаба, что означает
уменьшение изображения по вертикали и горизонтали по сравнению с
исходным в 2j-1 раз,
𝛼𝑀 , 𝛽𝑗 , 𝛾𝑗 – весовые показатели для каждой из компонент.
С целью упрощения выбора параметров принято считать, что 𝛼𝑀 = 𝛽𝑗 = 𝛾𝑗
и ∑𝑀
𝑗=1 𝛾𝑗 .
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
38
2.4 Формирование обучающей выборки
Для того чтобы получить качественные результаты при обучении нейронной
сети необходимо подобрать репрезентативные данные для обучения, то есть
выборка должна обладать достаточным количеством разнообразных данных для
обучения.
К обучающим данным выдвигаются следующие требования:
a)
Достаточность, то есть количество данных должно быть достаточно,
чтобы нейронная сеть смогла достигнуть обобщающей способности. Если данных
будет недостаточно, то сеть может переобучиться, т.е. запомнить данные, в
результате чего на обучающей выборки будет высокий процент улучшений, а на
тестовой низкий.
b)
Разнообразие, таким образом в обучающей выборки должно быть
большое разнообразие данных для каждого класса. Если все данные будут
однообразны, то у нейронной сети не получится достичь обобщающей
способности.
Сформируем обучающую выборку.
Создание обучающей выборки в задачах такого типа является сложным и
долгим мероприятием.
Необходимо большое количество времени и помощь большого количества
людей (асессоров) для того, чтобы создать и разметить даже небольшую выборку.
Поэтому была использованы готовая выборка, которая называется CelebA,
состоящая приблизительно из 205 тысяч изображений.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
39
Рисунок 13 – Обучающая выборка
Изображения в данном наборе данных охватывают большие вариации поз и
фоновый беспорядок. CelebA имеет большое разнообразие и богатые аннотации, в
том числе:
1) 10177 количество идентичностей,
2)
202 599 количество изображений лица,
3)
ориентиров, 40 бинарных атрибутов на изображение.
Данные изображения сохраняем в папку dataset.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
40
2.5 Разработка приложения для реализации нейронной сети для повышения
качества изображений
2.5.1 Выбор и обоснование средств реализации нейронной сети
Для того, чтобы разработать и запустить нейронную сеть нам понадобятся
следующие атрибуты:
1) Python версии не ниже 3.6
2)
Библиотека PyTorch версии не ниже 1.0.0. Данная библиотека
используется
для
масштабируемой
распределенной
тренировки
и
оптимизированию представления в исследованиях в области компьютерного
зрения, НЛП и многого другого.
3)
предназначена
CUDA
для
увеличения
вычислительной
производительности за счет графических процессоров. Работает на графическом
ускорителе NVIDIA.
2.5.2 Алгоритм приложения для улучшения качества изображений с
применением нейронной сети
Алгоритм работы приложения для улучшения качества изображений с
применением нейронной сети представлен на рисунке 14.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
41
Начало
Формирование
обучающей
выборки
Обучение
нейронной сети
Изменение параметров
нейронной сети для
повышения качества
Достигнуты требуемые
параметры качества
обучения сети
Нет
Да
Ввод изображения
для повышения
качества
Обработка изображения
обученной нейронной сетью
Вывод обработанного изображения
Конец
Рисунок 14 – Алгоритм работы нейронной сети
Основные этапы алгоритма:
1) На вход идет обучающая выборка из большого количества изображений.
2)
Далее эти изображения обрабатываются внутри нейросети, происходит
обучение нейросети. Рассчитываются loss – функция, PSNR, SSIM и MS-SSIM.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
42
3)
Если метрики PSNR, SSIM и MS-SSIM увеличились, то сеть обучилась
оптимально.
4)
Если же метрики уменьшились, то данную нейросеть стоит несколько
оптимизировать, изменив веса, функции активации и метод оптимизации. И далее
опять обучить.
2.5.3 Описание интерфейса приложения
Нейронная сеть для повышения качества изображений реализовано как
консольное приложение.
Запуск приложения проходит в командной строке.
Для демонстрации одного изображения используется следующая команда:
1) «имя исполняемого файла» --(путь к изображению) --(путь к контрольной
точке) --(путь вывода),
2)
python demo.py --image-path ./figure/eval_target_image.jpeg --checkpoint-
path
chekpoints/generator_checkpoint_singleGPU.ckpt
--output-path
./result/OUTPUT_NAME.jpeg.
Чтобы протестировать модель нейронной сети, нужно выполнить в
командной строке следующие команды:
a)
Испытание натренированной модели:
«имя исполняемого файла» --(путь к выборке изображений) --(путь к
контрольной точке);
python
eval.py
--data-path
./dataset
--checkpoint-path
checkpoints/
generator_checkpoint_singleGPU.ckpt.
b)
Тест распределенной обучаемой модели:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
43
запуск
модуля
используемых
«факел
распределенного
запуска»
--(количество
графических процессов) «имя исполняемого
файла» \ --
(распределенный) \ --(путь к выборке) \ --(путь к контрольной точке);
python -m torch.distributed.launch --nproc_per_node=number_of_used_GPUs
eval.py
\
--distributed
\
--data-path
'
./dataset'
\
--checkpoint-path
checkpoints/generator_checkpoint.ckpt.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
44
3
АНАЛИЗ РЕЗУЛЬТАТОВ
3.1 Исследование изображения высокого качества
Изначально, нейросеть имеет функцию активации – ReLU и метод
оптимизации Adam.
Матрица нормализации выглядит следующим образом:
0,5 0,5 0,5
(
).
0,5 0,5 0,5
В ходе обучения получаются следующие числовые результаты: PSNR =
22.66, SSIM = 0.685, MS-SSIM = 0.902.
Изображение размером 3.39×3.39 и dpi = 108 после обработки выглядит
следующим образом:
Рисунок 15 – Оригинал и изображение (3.39×3.39) обработанное нейросетью
Рассмотрим, что произойдет с изображением, если в качестве функции
активации взять Softmax, который выглядит следующим образом:
𝑒 𝑦𝑖
𝑆𝑀𝑖 (𝑦) = 𝑁 𝑦𝑗
∑𝑗=1 𝑒
Функции потерь оставим прежними.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
45
В качестве метода оптимизации, возьмем модифицированный градиентный
спуск – RMSprop. Он задан следующей формулой:
𝑤 𝑡+1 = 𝑤 𝑡 − 𝛼
∇𝑓(𝑤 𝑡 )
√𝐸𝑀𝐴𝛾 (∇𝑓2 )𝑡
.
Таким образом, получается, что новые параметры равны старым параметрам
минус learning rate умноженный на градиент функции потерь при текущих
параметрах деленый на корень квадратный из экспоненциального скользящего
среднего с некоторым параметром от квадрата градиента функции потерь.
И первым вариантом матрицы нормалиизации:
0,788 0,788 0,788
(
)
0,788 0,788 0,788
В этом случае мы получаем, что оценочные метрики для изображения
среднего качества размером 3.39×3.39 увеличились на 3.8%.
Численные результаты отображены в таблице 1.
Таблица 1 – Результаты работы первых данных для изображения 3.39×3.39
Обозначение
PSNR
SSIM
MS-SSIM
Было
22.66
0.685
0.902
Стало
23.75
0.712
0.935
Рассмотрим, полученное в ходе работы нейросети изображение, рисунок 18.
Для наглядности будем сравнивать его с результатами работы начальных
данных.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
46
Рисунок 16 – Изображение, обработанное нач.данными и изображение обработанное первым вариантом
данных
Второй вариант матрицы выглядит так:
0,2 0,2 0,2
(
).
0,2 0,2 0,2
Обучение нейронной сети со вторыми представленными параметрами
привело к ухудшению изображения среднего качества размера 3.39×3.39, в 93,8%.
То есть метрики PSNR, SSIM, MS-SSIM многократно уменьшились по
сравнению с результатами работы с начальными данными. Численный результат
представлен в таблице 2.
Таблица 2 – Результаты работы вторых данных для изображения 3.39×3.39
Обозначение
PSNR
SSIM
MS-SSIM
Было
22.66
0.685
0.902
Стало
1.405
0,043
0.056
Изображение имеет следующий вид, рисунок 17.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
47
Рисунок 17 – Изображение, обработанное нач.данными и изображение обработанное вторым вариантом
данных
И третий вариант матрицы нормализации – это:
2 2
(
2 2
В
третьем
варианте
изображение
2
).
2
размером
3.39×3.39
ухудшилось
приблизительно на 58%. Из чего следуют следующие данные метрик:
Таблица 3 – Результат работы третьего варианта данных
Обозначение
PSNR
SSIM
MS-SSIM
Было
22.66
0.685
0.902
Стало
9.51
0.290
0.385
Полученное изображение можно посмотреть на рисунке 18.
Рисунок 18 – Изображение, обработанное нач.данными и изображение обработанное вторым вариантом
данных
Таким образом, получаем, что оптимальным вариантом для обработки
изображений размером 3.39×3.39 и dpi 108, является первый вариант, где матрица
нормализации имеет вид:
0,788 0,788 0,788
(
).
0,788 0,788 0,788
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
48
Другие же матрицы нормализации не являются оптимальными, качество
изображений в этих случаях по сравнению с исходными данными теряется.
3.2 Исследование изображения среднего качества
Работа нейросети с начальными данными, где матрица нормализации
выглядит следующим образом:
0,5 0,5 0,5
(
),
0,5 0,5 0,5
приводит к числовым результатам, как и в первом пункте: PSNR = 22.66,
SSIM = 0.685, MS-SSIM = 0.902.
На рисунке 19, оригинал и изображение с dpi = 96 и размером 5.77×4.71,
обработанное начальными данными.
Рисунок 19 – Оригинал и изображение обработанное нейросетью
Теперь возьмем функцию активации Softmax и метод оптимизации RMSprop.
Первая матрица нормализации также имеет вид:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
49
0,788 0,788 0,788
(
)
0,788 0,788 0,788
Изображение размером 5.77×4.71 и dpi = 96 ухудшило свои показатели по
сравнению с начальными данными приблизительно на 37%. Таким образом
метрики стали: PSNR = 14.27, SSIM = 0.434, MS-SSIM = 0.565. Полученное
изображение выглядит следующим образом, рисунок 20.
Рисунок 20 – Изображение, обработанное нач.данными и изображение (5.77×4.71) обработанное первым
вариантом данных
Второй вариант матрицы
0,2 0,2 0,2
(
).
0,2 0,2 0,2
В этом случае мы также получаем довольно большое ухудшение результатов,
идет полная потеря изображения Полученное изображение выглядит следующим
образом, рисунок 21.
Рисунок 21 – Изображение с нач.данными и изображение (5.77×4.71) обработанное вторым вариантом
данных
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
50
И третий вариант матрицы нормализации – это:
2 2
(
2 2
2
).
2
Изображение ухудшилось приблизительно на 69%. Метрики приняли
следующие значения: PSNR = 6.7, SSIM = 0.205, MS-SSIM = 0.274.
Рисунок 22 – Изображение с нач.данными и изображение обработанное третьим вариантом данных
Таким образом, получаем, что самыми оптимальными данными для
представленного изображения, являются начальные. В остальных же случаях
необходимо заново подбирать параметры оптимизации.
3.3 Исследование изображения низкого качества
Так же нейросеть с начальными данными улучшила изображение низкого
качества размером 6.06×4.84 и dpi = 77.
В ходе обучения получаются следующие числовые результаты: PSNR =
22.66, SSIM = 0.685, MS-SSIM = 0.902.
Изображение представлено на рисунке 23.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
51
Рисунок 23 – Оригинал и изображение(6.06×4.84) обработанное нейросетью
Далее также рассмотрим, что произойдет с нейронной сетью, с функцией
активации Softmax и методом оптимизации – RMSprop.
Первая матрица нормализации:
0,788 0,788 0,788
(
)
0,788 0,788 0,788
В этом случае мы получаем, что некоторые показатели улучшились, а
некоторые, наоборот, ухудшились.
Таким образом, получаем, что метрики равны следующим значениям: PSNR
= 22.84, SSIM = 0.664, MS-SSIM = 0.757.
Полученное изображение выглядит следующим образом, рисунок 24.
Рисунок 24 – Изображение, обработанное нач.данными и изображение (6.06×4.84) обработанное первым
вариантом данных
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
52
Второй вариант матрицы:
0,2 0,2 0,2
(
).
0,2 0,2 0,2
Второй вариант обработки изображения, приводит к потере результата
приблизительно на 80%. Таким образом, метрики принимают следующие
результаты: PSNR = 4.532, SSIM = 0.138, MS-SSIM = 0.176. Изображения имеет
вид, рисунок 25.
Рисунок 25 – Предыдущее изображение и изображение (6.06×4.84) обработанное вторым вариантом
данных
И третий вариант матрицы нормализации – это:
2 2
(
2 2
2
).
2
Работа нейросети с низкокачественным изображением,
привело к
ухудшению приблизительно на 53%. Метрики приняли следующие результаты:
PSNR = 10.65, SSIM = 0.308, MS-SSIM = 0.442.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
53
Рисунок 26 – Изображение с нач.данными и изображение (6.06×4.84) обработанное вторым вариантом
данных
Таким образом, получаем, что в данном пункте оптимальным является только
начальная обработка, попытки нормализации и улучшения не привели к
качественному результату. Конечно можно использовать первый вариант
нормализации, так как некоторые метрики увеличились, но результаты все равно
не будут удовлетворительными, то есть будут некоторые потери.
Следовательно, на основе вышеизложенного можно сделать вывод, что
представленная нейронная сеть, неплохо работает с изображениями среднего
качества, размера 3.39×3.39 и матрицей нормализации:
0,788 0,788 0,788
(
).
0,788 0,788 0,788
Для улучшения последующих результатов необходимо заново подбирать
функцию активации и метод оптимизации, а также матрицу нормализации для
данных параметров.
А также необходимо повысить технические данные компьютера, так как в
ходе испытания модели имелись некоторые технические ограничения и сбои, что
приводило к потере некоторых результатов.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
54
ЗАКЛЮЧЕНИЕ
В соответствие с поставленной целью - разработка нейронной сети,
позволяющей улучшать качество изображений, на основе существующей
нейросети - была реализована архитектура сверточной нейронной сети с
использованием метода super-resolution.
В ходе теоретических и экспериментальных исследований были получены
следующие результаты:
a)
В работе были изучены некоторые теоретические аспекты нейронной
сети, как биологической, так и математической, метод Super-Resolution,
позволяющий улучшать качество изображений.
b)
Проведен сравнительный анализ двух нейронных сетей улучшающих
качество изображений. На основе данного анализа в качестве основы для
разработки была выбрана нейросеть Progressive Face Super-Resolution.
c)
В среде Python с использованием библиотеки PyTorch была проведена
разработка нейросети. В ходе тестирования улучшились результаты работы
нейросети с изображением 3.39×3.39 и dpi = 108, на 3.8%, что повлияло на
улучшение качества изображения.
На основе рассмотренных данных, можно сделать вывод, что благодаря
современным исследованиям, нейронные сети для улучшения изображений могут
быть улучшены и использованы во многих сферах.
Для этого необходимо изменить функцию активации и вместо Softmax,
использовать, например, сигмоидную функцию активации. Так же, можно
изменить метод оптимизации, и вместо RMSProp использовать с данной функцией
активации исходный метод – Adam. И стоит поработать с матрицей нормализации,
подобрать для нее оптимальные параметры для вышеизложенного случая.
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
55
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1)
Aggelos Katsaggelos - Super Resolution of Images (Synthesis Lectures on
Image, Video, and Multimedia Processing), 2006 г. [Электронный ресурс] Режим
доступа:
https://eknigi.org/programmirovanie/97192-super-resolution-of-imagessynthesis-lectures-on.html.
2)
Статья: Структура нейронной сети. [Электронный ресурс] Режим
доступа: https://compurik.com/neural_network_structure#h1
3)
Гудфеллоу Я., Бенджио И., Курвилль А. − Глубокое обучение, 2017 г.
[Электронный ресурс] Режим доступа: https://ru.pdfdrive.com/Глубокое-обучениеe191950186.html.
4)
Рутковская М., Плинский Л. - Нейронные сети, генетические
алгоритмы и нечеткие системы, 2007 г. [Электронный ресурс] Режим доступа:
https://ru.pdfdrive.com/Нейронные-сети-генетические-алгоритмы-и-нечеткиесистемы-e158090178.html
Deokyun Kim, Minseon Kim, Gihyun Kwon, Dae-Shik Kim – Progressive
Face Super-Resolution via Attention to Facial Landmark. [Электронный ресурс] Режим
доступа: https://arxiv.org/abs/1908.08239
5)
6)
Википедия – Пиковое отношение сигнала к шуму. [Электронный
ресурс]
Режим
доступа:
https://ru.wikipedia.org/wiki/Пиковое_отношение_сигнала_к_шуму
7)
Адриан Роузброк − Deep Learning for Computer Vision with Python, 2017
г. [Электронный ресурс] Режим доступа: https://b-ok.cc/book/3561346/c4e0b8.
8)
Каллан Р. - Основные концепции нейронных сетей, 2001 г.
[Электронный ресурс] Режим доступа: https://ru.pdfdrive.com/Основныеконцепции-нейронных-сетей-e156899800.html.
9)
Bengio, Yoshua, Courville, Aaron, Goodfellow, Ian J - Deep learning:
adaptive computation and machine learning, 2016 г. [Электронный ресурс] Режим
доступа:
https://www.researchgate.net/publication/320703571_Ian_Goodfellow_Yoshua_Beng
io_and_Aaron_Courville_Deep_learning_The_MIT_Press_2016_800_pp_ISBN_026
2035618
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
56
10) Konstantin Ostrovsky - Принципы построения нейронных сетей.
Пишем простую нейросеть на JavaScript. [Электронный ресурс] Режим доступа:
https://web-panda.ru/post/brainjs-simple
11) Peyman Milanfar - Super-Resolution Imaging, 2017 г. — Bosa Roca,
United States
12) Subhasis Chaudhuri - Super-Resolution Imaging, 2001 г. [Электронный
ресурс] Режим доступа: https://b-ok.cc/book/2093971/e0843e
13) Haohan Wang, Bhiksha Raj – On the Origin of Deep Learning.
[Электронный ресурс] Режим доступа: https://arxiv.org/pdf/1702.07800.pdf
14) Brandon Amos – Image Completion with Deep Learning in TensorFlow.
[Электронный ресурс] Режим доступа: https://bamos.github.io/2016/08/09/deepcompletion/
15) Nguyen A, Yosinski J, Clune J – Deep Neural Networks are Easily Fooled:
High Confidence Predictions for Unrecognizable Images. [Электронный ресурс] Режим
доступа: https://arxiv.org/pdf/1412.1897.pdf
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
57
ПРИЛОЖЕНИЕ А
Листинг программы
demo.py
import torch
import argparse
from model import Generator
from PIL import Image
import torchvision.transforms as transforms
from torchvision import utils
if __name__ == '__main__':
parser = argparse.ArgumentParser('Demo of Progressive Face Super-Resolution')
parser.add_argument('--image-path', type=str)
parser.add_argument('--checkpoint-path',
default='./checkpoints/generator_checkpoint_singleGPU.ckpt')
parser.add_argument('--output-path', type=str)
args = parser.parse_args()
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
with torch.no_grad():
generator = Generator().to(device)
generator.eval()
g_checkpoint = torch.load(args.checkpoint_path)
generator.load_state_dict(g_checkpoint['model_state_dict'], strict=False)
step = g_checkpoint['step']
alpha = g_checkpoint['alpha']
iteration = g_checkpoint['iteration']
print('pre-trained model is loaded step:%d, alpha:%d iteration:%d'%(step, alpha, iteration))
input_image = Image.open(args.image_path).convert('RGB')
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
58
_16x16_down_sampling = transforms.Resize((16,16))
_64x64_down_sampling = transforms.Resize((64, 64))
_32x32_down_sampling = transforms.Resize((32, 32))
totensor = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
])
#Note: Our netowork is trained by progressively downsampled images.
transformed_image
_16x16_down_sampling(_32x32_down_sampling(_64x64_down_sampling(input_image)))
=
transformed_image = totensor(transformed_image).unsqueeze(0).to(device)
output_image = generator(transformed_image, step, alpha)
utils.save_image(0.5*output_image+0.5, args.output_path)
model.py
import torch
import torch.nn as nn
from torch.nn import functional as F
from math import sqrt
"""Original EqualConv2d code is at
https://github.com/rosinality/style-based-gan-pytorch/blob/master/model.py
"""
class EqualLR:
def __init__(self, name):
self.name = name
def compute_weight(self, module):
weight = getattr(module, self.name+'_orig')
fan_in = weight.data.size(1) * weight.data[0][0].numel()
return weight * sqrt(2/fan_in)
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
59
@staticmethod
def apply(module, name):
fn = EqualLR(name)
weight = getattr(module, name)
del module._parameters[name]
module.register_parameter(name + '_orig', nn.Parameter(weight.data))
module.register_forward_pre_hook(fn)
return fn
def __call__(self, module, input):
weight = self.compute_weight(module)
setattr(module, self.name, weight)
def equal_lr(module, name='weight'):
EqualLR.apply(module, name)
return module
class EqualConv2d(nn.Module):
def __init__(self, *args, **kwargs):
super(EqualConv2d, self).__init__()
conv = nn.Conv2d(*args, **kwargs)
conv.weight.data.normal_()
conv.bias.data.zero_()
self.conv = equal_lr(conv)
def forward(self, input):
return self.conv(input)
class ResBlock(nn.Module):
def __init__(self, dim, kernel_size=3, padding=1, stride=1):
super(ResBlock, self).__init__()
self.conv = nn.Sequential(
EqualConv2d(dim, dim, kernel_size=3, padding=1, stride=1),
nn.BatchNorm2d(dim),
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
60
nn.ReLU(),
EqualConv2d(dim, dim, kernel_size=3, padding=1, stride=1),
nn.BatchNorm2d(dim),
nn.ReLU()
)
def forward(self, x):
return self.conv(x) + x
class ConvBlock(nn.Module):
def __init__(self, in_plane, out_plane, kernel_size=3, padding=1, stride=1):
super(ConvBlock, self).__init__()
self.conv = nn.Sequential(
EqualConv2d(in_plane, out_plane, kernel_size=3, padding=1, stride=1),
nn.LeakyReLU(0.2),
EqualConv2d(out_plane, out_plane, kernel_size=3, padding=1, stride=1),
nn.LeakyReLU(0.2))
def forward(self, x):
return self.conv(x)
class Generator(nn.Module):
def __init__(self, ):
super(Generator, self).__init__()
step1 = [nn.Conv2d(3, 512, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(512),
nn.ReLU()]
step1 += [ResBlock(dim=512, kernel_size=3, stride=1, padding=1),
nn.ConvTranspose2d(512, 256, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(256),
nn.ReLU()
]
step2 = [ResBlock(dim=256, kernel_size=3, stride=1, padding=1),
nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(128),
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
61
nn.ReLU()
]
step3 = [ResBlock(dim=128, kernel_size=3, stride=1, padding=1),
nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU()]
self.to_rgb = nn.ModuleList([nn.Conv2d(256, 3, kernel_size=1, stride=1, padding=0),
nn.Conv2d(128, 3, kernel_size=1, stride=1, padding=0),
nn.Conv2d(64, 3, kernel_size=1, stride=1, padding=0)])
self.step1 = nn.Sequential(*step1)
self.step2 = nn.Sequential(*step2)
self.step3 = nn.Sequential(*step3)
#self.model = nn.Sequential(self.step1, self.step2, self.step3)
def forward(self, input, step=1, alpha=-1):
"""Progressive generator forward"""
if step == 1:
out = self.step1(input)
out = self.to_rgb[step-1](out)
elif step == 2:
if 0 <= alpha < 1:
prev = self.step1(input)
skip_rgb = F.interpolate(self.to_rgb[step-2](prev), scale_factor=2, mode='nearest')
out = self.step2(prev)
out = (1-alpha)*skip_rgb + alpha*self.to_rgb[step-1](out)
else:
out = self.step2(self.step1(input))
out = self.to_rgb[step-1](out)
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
62
else:
if 0 <= alpha < 1:
prev = self.step2(self.step1(input))
skip_rgb = F.interpolate(self.to_rgb[step-2](prev), scale_factor=2, mode='nearest')
out = self.step3(prev)
out = (1-alpha)*skip_rgb + alpha*self.to_rgb[step-1](out)
else:
out = self.step3(self.step2(self.step1(input)))
out = self.to_rgb[step-1](out)
return out
class Discriminator(nn.Module):
"""Discriminator"""
def __init__(self,):
super(Discriminator, self).__init__()
self.from_rgb = nn.ModuleList([
nn.Conv2d(3, 256, kernel_size=1, stride=1, padding=0),
nn.Conv2d(3, 128, kernel_size=1, stride=1, padding=0),
nn.Conv2d(3, 64, kernel_size=1, stride=1, padding=0)])
step1 = [ConvBlock(256, 512, kernel_size=3, padding=1, stride=1), nn.AvgPool2d(kernel_size=2,
stride=2)]
step2 = [ConvBlock(128, 256, kernel_size=3, padding=1, stride=1), nn.AvgPool2d(kernel_size=2,
stride=2)]
step3 = [ConvBlock(64, 128, kernel_size=3, padding=1, stride=1), nn.AvgPool2d(kernel_size=2,
stride=2)]
self.step1 = nn.Sequential(*step1)
self.step2 = nn.Sequential(*step2)
self.step3 = nn.Sequential(*step3)
#for last layer
self.equal_conv = EqualConv2d(513, 512, kernel_size=3, stride=1, padding=1)
self.linear = nn.Linear(512, 2048)
self.linear2 = nn.Linear(2048, 1)
def forward(self, input, step=1, alpha=-1):
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
63
"""Progressive discriminator forward Each step's output(generator output) is mixed with previous
genertor output stacked from step1 to step3.
| step1 -----> step2 ------> step3 |
"""
if step == 1:#32x32
out = self.from_rgb[step-1](input)
out = self.step1(out)
if step ==2:#64x64
out = self.from_rgb[step-1](input)#128x64x64
out = self.step2(out) #256x32x32
if 0 <= alpha < 1:
skip_rgb = F.avg_pool2d(input, kernel_size=2,stride=2)#F.interpolate(input, size=(32, 32),
mode='nearest') #3x32x32
skip_rgb = self.from_rgb[step-2](skip_rgb) #256x32x32
out = (1-alpha)*skip_rgb + alpha * out
out = self.step1(out) #256x16x16
elif step ==3:#128x128
out = self.from_rgb[step-1](input) #64x128x128
out = self.step3(out) #128x64x64
if 0 <= alpha < 1:
skip_rgb = F.avg_pool2d(input, kernel_size=2,stride=2) #F.interpolate(input, size=(64, 64),
mode='nearest') #3x64x64
skip_rgb = self.from_rgb[step-2](skip_rgb) #128x64x64
out = (1-alpha)*skip_rgb + alpha * out #128x64x64
out = self.step2(out) #256x32x32
out = self.step1(out) #512x16x16
mean_std = input.std(0).mean()
mean_std = mean_std.expand(input.size(0), 1, 16, 16)
out = torch.cat([out, mean_std], dim=1)
out = self.equal_conv(out)
out = F.avg_pool2d(out, 16, stride=1)
out = out.view(input.size(0), -1)
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
64
out = self.linear(out)
out = self.linear2(out)
out = out.squeeze_(dim=1)
return out
dataloader.py
from torch.utils.data.dataset import Dataset
import torchvision.transforms as transforms
from os.path import join
from PIL import Image
class CelebDataSet(Dataset):
"""CelebA dataset
Parameters:
data_path (str)
state (str)
-- CelebA dataset main directory(inculduing '/Img' and '/Anno') path
-- dataset phase 'train' | 'val' | 'test'
Center crop the alingned celeb dataset to 178x178 to include the face area and then downsample to
128x128(Step3).
In addition, for progressive training, the target image for each step is resized to 32x32(Step1) and
64x64(Step2).
"""
def __init__(self, data_path = './dataset/', state = 'train', data_augmentation=None):
self.main_path = data_path
self.state = state
self.data_augmentation = data_augmentation
self.img_path = join(self.main_path, 'CelebA/Img/img_align_celeba')
self.eval_partition_path = join(self.main_path, 'Anno/list_eval_partition.txt')
train_img_list = []
val_img_list = []
test_img_list = []
f = open(self.eval_partition_path, mode='r')
while True:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
65
line = f.readline().split()
if not line: break
if line[1] == '0':
train_img_list.append(line)
elif line[1] =='1':
val_img_list.append(line)
else:
test_img_list.append(line)
f.close()
if state=='train':
train_img_list.sort()
self.image_list = train_img_list
elif state=='val':
val_img_list.sort()
self.image_list = val_img_list
else:
test_img_list.sort()
self.image_list = test_img_list
if state=='train' and self.data_augmentation:
self.pre_process = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.CenterCrop((178, 178)),
transforms.Resize((128, 128)),
transforms.RandomRotation(20, resample=Image.BILINEAR),
transforms.ColorJitter(brightness=0.4,
contrast=0.4,
saturation=0.4,
hue=0.1)
])
else:
self.pre_process = transforms.Compose([
transforms.CenterCrop((178, 178)),
transforms.Resize((128,128)),
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
66
])
self.totensor = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
])
self._64x64_down_sampling = transforms.Resize((64, 64))
self._32x32_down_sampling = transforms.Resize((32, 32))
self._16x16_down_sampling = transforms.Resize((16,16))
def __getitem__(self, index):
image_path = join(self.img_path, self.image_list[index][0])
target_image = Image.open(image_path).convert('RGB')
target_image = self.pre_process(target_image)
x4_target_image = self._64x64_down_sampling(target_image)
x2_target_image = self._32x32_down_sampling(x4_target_image)
input_image = self._16x16_down_sampling(x2_target_image)
x2_target_image = self.totensor(x2_target_image)
x4_target_image = self.totensor(x4_target_image)
target_image = self.totensor(target_image)
input_image = self.totensor(input_image)
return x2_target_image, x4_target_image, target_image, input_image
def __len__(self):
return len(self.image_list)
ssim.py
mport torch
import torch.nn.functional as F
from math import exp
import numpy as np
def gaussian(window_size, sigma):
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
67
gauss = torch.Tensor([exp(-(x
range(window_size)]).double()
-
window_size//2)**2/float(2*sigma**2))
for
x
in
# gauss.requires_grad = True
return gauss/gauss.sum()
def create_window(window_size):
_1D_window = gaussian(window_size, 1.5).unsqueeze(1)
_2D_window = _1D_window.mm(_1D_window.t()).double().unsqueeze(0).unsqueeze(0)
window = _2D_window.expand(1, 1, window_size, window_size).contiguous()
return window.cuda()
def ssim(img1, img2, window_size=11, size_average=True, full=False, val_range=None):
# Value range can be different from 255. Other common ranges are 1 (sigmoid) and 2 (tanh).
if val_range is None:
if torch.max(img1) > 128:
max_val = 255
else:
max_val = 1
if torch.min(img1) < -0.5:
min_val = -1
else:
min_val = 0
L = max_val - min_val
else:
L = val_range
padd = 0
(_, channels, height, width) = img1.size()
real_size = min(window_size, height, width)
window = create_window(real_size)
ret_channels = []
cs_channels = []
for ch in range(channels): # loop over channels, then average
img1_ch = torch.unsqueeze(img1[:, ch, :, :], 1)
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
68
img2_ch = torch.unsqueeze(img2[:, ch, :, :], 1)
mu1 = F.conv2d(img1_ch, window, padding=padd)
mu2 = F.conv2d(img2_ch, window, padding=padd)
mu1_sq = mu1.pow(2)
mu2_sq = mu2.pow(2)
mu1_mu2 = mu1 * mu2
sigma1_sq = F.conv2d(img1_ch * img1_ch, window, padding=padd) - mu1_sq
sigma2_sq = F.conv2d(img2_ch * img2_ch, window, padding=padd) - mu2_sq
sigma12 = F.conv2d(img1_ch * img2_ch, window, padding=padd) - mu1_mu2
C1 = (0.01 * L) ** 2
C2 = (0.03 * L) ** 2
ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq
+ sigma2_sq + C2))
v1 = 2.0 * sigma12 + C2
v2 = sigma1_sq + sigma2_sq + C2
cs = torch.mean(v1 / v2) # contrast sensitivity
if size_average:
ret = ssim_map.mean()
else:
ret = ssim_map.mean(1).mean(1).mean(1)
cs_channels.append(cs)
ret_channels.append(ret)
cs_mean = torch.mean(torch.stack(cs_channels), dim=-1)
ret_mean = torch.mean(torch.stack(ret_channels), dim=-1)
if full:
return ret_mean, cs_mean
return ret_mean
def msssim(img1, img2, window_size=11, size_average=True, val_range=None):
device = img1.device
weights = torch.FloatTensor([0.0448, 0.2856, 0.3001, 0.2363, 0.1333]).to(device)
levels = weights.size()[0]
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
69
mssim = []
mcs = []
for _ in range(levels):
sim, cs = ssim(img1, img2, window_size=window_size, size_average=size_average, full=True,
val_range=val_range)
mssim.append(sim)
mcs.append(cs)
img1 = F.avg_pool2d(img1, (2, 2))
img2 = F.avg_pool2d(img2, (2, 2))
mssim = torch.stack(mssim)
mcs = torch.stack(mcs)
# # Normalize (to avoid NaNs)
#
# mssim = (mssim + 1) / 2
# mcs = (mcs + 1) / 2
pow1 = mcs ** weights
pow2 = mssim ** weights
# output = torch.prod(pow1 * pow2)
# From Matlab implementation https://ece.uwaterloo.ca/~z70wang/research/iwssim/
output = torch.prod(pow1[:-1] * pow2[-1])
return output
eval.py
import torch
from torch import optim, nn
import argparse
from dataloader import CelebDataSet
from torch.utils.data import DataLoader
from model import Generator
import os
from torch.autograd import Variable, grad
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
70
import sys
from torchvision import utils
from math import log10
from ssim import ssim, msssim
def test(dataloader, generator, MSE_Loss, step, alpha):
avg_psnr = 0
avg_ssim = 0
avg_msssim = 0
for i, (x2_target_image, x4_target_image, target_image, input_image) in enumerate(dataloader):
input_image = input_image.to(device)
if step==1:
target_image = x2_target_image.to(device)
elif step==2:
target_image = x4_target_image.to(device)
else:
target_image = target_image.to(device)
input_image = input_image.to(device)
predicted_image = generator(input_image, step, alpha)
predicted_image = predicted_image.double()
target_image = target_image.double()
mse_loss = MSE_Loss(0.5*predicted_image+0.5, 0.5*target_image+0.5)
psnr = 10*log10(1./mse_loss.item())
avg_psnr += psnr
_ssim = ssim(0.5*predicted_image+0.5, 0.5*target_image+0.5)
avg_ssim += _ssim.item()
ms_ssim = msssim(0.5*predicted_image+0.5, 0.5*target_image+0.5)
avg_msssim += ms_ssim.item()
sys.stdout.write('\r [%d/%d] Test progress... PSNR: %6.4f'%(i, len(dataloader), psnr))
save_image = torch.cat([predicted_image, target_image], dim=0)
if args.local_rank==0:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
71
utils.save_image(0.5*save_image+0.5, os.path.join(args.result_path, '%d_results.jpg'%i))
print('Test done, Average PSNR:%6.4f, Average SSIM:%6.4f, Average MS-SSIM:%6.4f
'%(avg_psnr/len(dataloader),avg_ssim/len(dataloader), avg_msssim/len(dataloader)))
if __name__ == '__main__':
parser = argparse.ArgumentParser('Implemnetation of Progressive Face Super-Resolution Attention
to Face Landmarks')
parser.add_argument('--batch-size', default=16, type=int)
parser.add_argument('--checkpoint-path', default='./checkpoints/', type=str)
parser.add_argument('--data-path', default='./dataset/', type=str)
parser.add_argument('--result-path', default='./result/', type=str)
parser.add_argument('--workers', default=4, type=int)
parser.add_argument('--local_rank', default=0, type=int, help='node rank for distributed training')
parser.add_argument('--distributed', action='store_true')
args = parser.parse_args()
if args.local_rank == 0:
if not os.path.exists(args.result_path):
os.mkdir(args.result_path)
print('===>make directory', args.result_path)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
args.gpu = 0
args.world_size = 1
dataset = CelebDataSet(data_path=args.data_path, state='test')
if args.distributed:
import apex.parallel as parallel
args.gpu = args.local_rank
torch.cuda.set_device(args.gpu)
torch.distributed.init_process_group(backend='nccl', init_method='env://')
args.world_size = torch.distributed.get_world_size()
train_sampler = torch.utils.data.distributed.DistributedSampler(dataset)
dataloader
=
DataLoader(dataset,
batch_size=args.batch_size,
num_workers=args.workers, pin_memory=True, sampler=train_sampler)
shuffle=False,
else:
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
72
dataloader
=
DataLoader(dataset=dataset,
num_workers=args.workers, pin_memory=True)
batch_size=args.batch_size,
shuffle=False,
generator = Generator().to(device)
if args.distributed:
g_checkpoint = torch.load(args.checkpoint_path, map_location = lambda storage, loc:
storage.cuda(args.local_rank))
generator = parallel.DistributedDataParallel(generator)
generator = parallel.convert_syncbn_model(generator)
else:
g_checkpoint = torch.load(args.checkpoint_path)
generator.load_state_dict(g_checkpoint['model_state_dict'], strict=False)
step = g_checkpoint['step']
alpha = g_checkpoint['alpha']
iteration = g_checkpoint['iteration']
print('pre-trained model is loaded step:%d, alpha:%d iteration:%d'%(step, alpha, iteration))
MSE_Loss = nn.MSELoss()
generator.eval()
test(dataloader, generator, MSE_Loss, step, alpha)
ВлГУ.02.03.01.МКН-116.10.00 ПЗ
Изм. Лист
№ докум.
Подп.
Дата
Лист
73
Отзывы:
Авторизуйтесь, чтобы оставить отзыв