- •Предисловие
- •Благодарности
- •О книге
- •Кому адресована эта книга
- •О примерах кода
- •Об авторе
- •От издательства
- •1.1 Искусственный интеллект, машинное и глубокое обучение
- •1.1.1. Искусственный интеллект
- •1.1.2. Машинное обучение
- •1.1.3. Изучение правил и представлений данных
- •1.1.4. «Глубина» глубокого обучения
- •1.1.5. Принцип действия глубокого обучения в трех картинках
- •1.1.6. Какой ступени развития достигло глубокое обучение
- •1.1.7. Не верьте рекламе
- •1.1.8. Перспективы ИИ
- •1.2. Что было до глубокого обучения: краткая история машинного обучения
- •1.2.1. Вероятностное моделирование
- •1.2.2. Первые нейронные сети
- •1.2.3. Ядерные методы
- •1.2.4. Деревья решений, случайные леса и градиентный бустинг
- •1.2.5. Назад к нейронным сетям
- •1.2.6. Отличительные черты глубокого обучения
- •1.2.7. Современный ландшафт машинного обучения
- •1.3. Почему глубокое обучение? Почему сейчас?
- •1.3.1. Оборудование
- •1.3.2. Данные
- •1.3.3. Алгоритмы
- •1.3.4. Новая волна инвестиций
- •1.3.5. Демократизация глубокого обучения
- •1.3.6. Ждать ли продолжения этой тенденции?
- •2.1. Первое знакомство с нейронной сетью
- •2.2. Представление данных для нейронных сетей
- •2.2.1. Скаляры (тензоры нулевого ранга)
- •2.2.2. Векторы (тензоры первого ранга)
- •2.2.3. Матрицы (тензоры второго ранга)
- •2.2.4. Тензоры третьего и более высоких рангов
- •2.2.5. Ключевые атрибуты
- •2.2.6. Манипулирование тензорами с помощью NumPy
- •2.2.7. Пакеты данных
- •2.2.8. Практические примеры тензоров с данными
- •2.2.9. Векторные данные
- •2.2.10. Временные ряды или последовательности
- •2.2.11. Изображения
- •2.2.12. Видео
- •2.3. Шестеренки нейронных сетей: операции с тензорами
- •2.3.1. Поэлементные операции
- •2.3.2. Расширение
- •2.3.3. Скалярное произведение тензоров
- •2.3.4. Изменение формы тензора
- •2.3.5. Геометрическая интерпретация операций с тензорами
- •2.3.6. Геометрическая интерпретация глубокого обучения
- •2.4. Механизм нейронных сетей: оптимизация на основе градиента
- •2.4.2. Производная операций с тензорами: градиент
- •2.4.3. Стохастический градиентный спуск
- •2.4.4. Объединение производных: алгоритм обратного распространения ошибки
- •2.5. Оглядываясь на первый пример
- •2.5.1. Повторная реализация первого примера в TensorFlow
- •2.5.2. Выполнение одного этапа обучения
- •2.5.3. Полный цикл обучения
- •2.5.4. Оценка модели
- •Краткие итоги главы
- •3.1. Что такое TensorFlow
- •3.2. Что такое Keras
- •3.3. Keras и TensorFlow: краткая история
- •3.4. Настройка окружения для глубокого обучения
- •3.4.1. Jupyter Notebook: предпочтительный способ проведения экспериментов с глубоким обучением
- •3.4.2. Использование Colaboratory
- •3.5. Первые шаги с TensorFlow
- •3.5.1. Тензоры-константы и тензоры-переменные
- •3.5.2. Операции с тензорами: математические действия в TensorFlow
- •3.5.3. Второй взгляд на GradientTape
- •3.5.4. Полный пример: линейный классификатор на TensorFlow
- •3.6. Анатомия нейронной сети: знакомство с основами Keras
- •3.6.1. Слои: строительные блоки глубокого обучения
- •3.6.2. От слоев к моделям
- •3.6.3. Этап «компиляции»: настройка процесса обучения
- •3.6.4. Выбор функции потерь
- •3.6.5. Метод fit()
- •3.6.6. Оценка потерь и метрик на проверочных данных
- •3.6.7. Вывод: использование модели после обучения
- •Краткие итоги главы
- •4.1. Классификация отзывов к фильмам: пример бинарной классификации
- •4.1.1. Набор данных IMDB
- •4.1.2. Подготовка данных
- •4.1.3. Конструирование модели
- •4.1.4. Проверка решения
- •4.1.5. Использование обученной сети для предсказаний на новых данных
- •4.1.6. Дальнейшие эксперименты
- •4.1.7. Подведение итогов
- •4.2.1. Набор данных Reuters
- •4.2.2. Подготовка данных
- •4.2.3. Конструирование модели
- •4.2.4. Проверка решения
- •4.2.5. Предсказания на новых данных
- •4.2.6. Другой способ обработки меток и потерь
- •4.2.7. Важность использования достаточно больших промежуточных слоев
- •4.2.8. Дальнейшие эксперименты
- •4.2.9. Подведение итогов
- •4.3. Предсказание цен на дома: пример регрессии
- •4.3.1. Набор данных с ценами на жилье в Бостоне
- •4.3.2. Подготовка данных
- •4.3.3. Конструирование модели
- •4.3.5. Предсказания на новых данных
- •4.3.6. Подведение итогов
- •Краткие итоги главы
- •5.1. Обобщение: цель машинного обучения
- •5.1.1. Недообучение и переобучение
- •5.1.2. Природа общности в глубоком обучении
- •5.2. Оценка моделей машинного обучения
- •5.2.1. Обучающие, проверочные и контрольные наборы данных
- •5.2.2. Выбор базового уровня
- •5.2.3. Что важно помнить об оценке моделей
- •5.3. Улучшение качества обучения модели
- •5.3.1. Настройка основных параметров градиентного спуска
- •5.3.2. Использование более удачной архитектуры
- •5.3.3. Увеличение емкости модели
- •5.4. Улучшение общности
- •5.4.1. Курирование набора данных
- •5.4.2. Конструирование признаков
- •5.4.3. Ранняя остановка
- •5.4.4. Регуляризация модели
- •Краткие итоги главы
- •6.1. Определение задачи
- •6.1.1. Формулировка задачи
- •6.1.2. Сбор данных
- •6.1.3. Первичный анализ данных
- •6.1.4. Выбор меры успеха
- •6.2. Разработка модели
- •6.2.1. Подготовка данных
- •6.2.2. Выбор протокола оценки
- •6.2.3. Преодоление базового случая
- •6.2.4. Следующий шаг: разработка модели с переобучением
- •6.2.5 Регуляризация и настройка модели
- •6.3. Развертывание модели
- •6.3.1. Объяснение особенностей работы модели заинтересованным сторонам и обозначение границ ожидаемого
- •6.3.2. Предоставление доступа к модели
- •6.3.3. Мониторинг качества работы модели в процессе эксплуатации
- •6.3.4. Обслуживание модели
- •Краткие итоги главы
- •7.1. Спектр рабочих процессов
- •7.2. Разные способы создания моделей Keras
- •7.2.1. Последовательная модель Sequential
- •7.2.2. Функциональный API
- •7.2.3. Создание производных от класса Model
- •7.2.4 Смешивание и согласование различных компонентов
- •7.2.5. Используйте правильный инструмент
- •7.3. Встроенные циклы обучения и оценки
- •7.3.1. Использование собственных метрик
- •7.3.2. Использование обратных вызовов
- •7.3.3. Разработка своего обратного вызова
- •7.3.4. Мониторинг и визуализация с помощью TensorBoard
- •7.4. Разработка своего цикла обучения и оценки
- •7.4.1. Обучение и прогнозирование
- •7.4.2. Низкоуровневое использование метрик
- •7.4.3. Полный цикл обучения и оценки
- •7.4.4. Ускорение вычислений с помощью tf.function
- •7.4.5. Использование fit() с нестандартным циклом обучения
- •Краткие итоги главы
- •8.1. Введение в сверточные нейронные сети
- •8.1.1. Операция свертывания
- •8.1.2. Выбор максимального значения из соседних (max-pooling)
- •8.2. Обучение сверточной нейронной сети с нуля на небольшом наборе данных
- •8.2.1. Целесообразность глубокого обучения для решения задач с небольшими наборами данных
- •8.2.2. Загрузка данных
- •8.2.3. Конструирование сети
- •8.2.4. Предварительная обработка данных
- •8.2.5. Обогащение данных
- •8.3. Использование предварительно обученной модели
- •8.3.1. Выделение признаков
- •8.3.2. Дообучение предварительно обученной модели
- •Краткие итоги главы
- •9.2. Пример сегментации изображения
- •9.3. Современные архитектурные шаблоны сверточных сетей
- •9.3.1. Модульность, иерархия, многократное использование
- •9.3.2. Остаточные связи
- •9.3.3. Пакетная нормализация
- •9.3.4. Раздельная свертка по глубине
- •9.3.5. Собираем все вместе: мини-модель с архитектурой Xception
- •9.4. Интерпретация знаний, заключенных в сверточной нейронной сети
- •9.4.1. Визуализация промежуточных активаций
- •9.4.2. Визуализация фильтров сверточных нейронных сетей
- •9.4.3. Визуализация тепловых карт активации класса
- •Краткие итоги главы
- •Глава 10. Глубокое обучение на временных последовательностях
- •10.1. Разные виды временных последовательностей
- •10.2. Пример прогнозирования температуры
- •10.2.1. Подготовка данных
- •10.2.2. Базовое решение без привлечения машинного обучения
- •10.2.4. Попытка использовать одномерную сверточную модель
- •10.2.5. Первое базовое рекуррентное решение
- •10.3. Рекуррентные нейронные сети
- •10.3.1. Рекуррентный слой в Keras
- •10.4. Улучшенные методы использования рекуррентных нейронных сетей
- •10.4.1. Использование рекуррентного прореживания для борьбы с переобучением
- •10.4.2. Наложение нескольких рекуррентных слоев друг на друга
- •10.4.3. Использование двунаправленных рекуррентных нейронных сетей
- •10.4.4. Что дальше
- •Краткие итоги главы
- •Глава 11. Глубокое обучение для текста
- •11.1. Обработка естественных языков
- •11.2. Подготовка текстовых данных
- •11.2.1. Стандартизация текста
- •11.2.2. Деление текста на единицы (токенизация)
- •11.2.3. Индексирование словаря
- •11.2.4. Использование слоя TextVectorization
- •11.3. Два подхода к представлению групп слов: множества и последовательности
- •11.3.1. Подготовка данных IMDB с отзывами к фильмам
- •11.3.2. Обработка наборов данных: мешки слов
- •11.3.3. Обработка слов как последовательностей: модели последовательностей
- •11.4. Архитектура Transformer
- •11.4.1. Идея внутреннего внимания
- •11.4.2. Многоголовое внимание
- •11.4.3. Кодировщик Transformer
- •11.4.4. Когда использовать модели последовательностей вместо моделей мешка слов
- •11.5. За границами классификации текста: обучение «последовательность в последовательность»
- •11.5.1. Пример машинного перевода
- •11.5.2. Обучение типа «последовательность в последовательность» рекуррентной сети
- •Краткие итоги главы
- •Глава 12. Генеративное глубокое обучение
- •12.1. Генерирование текста
- •12.1.1. Краткая история генеративного глубокого обучения для генерирования последовательностей
- •12.1.3. Важность стратегии выбора
- •12.1.4. Реализация генерации текста в Keras
- •12.1.5. Обратный вызов для генерации текста с разными значениями температуры
- •12.1.6. Подведение итогов
- •12.2. DeepDream
- •12.2.1. Реализация DeepDream в Keras
- •12.2.2. Подведение итогов
- •12.3. Нейронная передача стиля
- •12.3.1. Функция потерь содержимого
- •12.3.2. Функция потерь стиля
- •12.3.3. Нейронная передача стиля в Keras
- •12.3.4. Подведение итогов
- •12.4. Генерирование изображений с вариационными автокодировщиками
- •12.4.1. Выбор шаблонов из скрытых пространств изображений
- •12.4.2. Концептуальные векторы для редактирования изображений
- •12.4.3. Вариационные автокодировщики
- •12.4.4. Реализация VAE в Keras
- •12.4.5. Подведение итогов
- •12.5. Введение в генеративно-состязательные сети
- •12.5.1. Реализация простейшей генеративно-состязательной сети
- •12.5.2. Набор хитростей
- •12.5.3. Получение набора данных CelebA
- •12.5.4. Дискриминатор
- •12.5.5. Генератор
- •12.5.6. Состязательная сеть
- •12.5.7. Подведение итогов
- •Краткие итоги главы
- •Глава 13. Методы и приемы для применения на практике
- •13.1. Получение максимальной отдачи от моделей
- •13.1.1. Оптимизация гиперпараметров
- •13.1.2. Ансамблирование моделей
- •13.2. Масштабирование обучения моделей
- •13.2.1. Ускорение обучения на GPU со смешанной точностью
- •13.2.2. Обучение на нескольких GPU
- •13.2.3. Обучение на TPU
- •Краткие итоги главы
- •Глава 14. Заключение
- •14.1. Краткий обзор ключевых понятий
- •14.1.1. Разные подходы к ИИ
- •14.1.2. Что делает глубокое обучение особенным среди других подходов к машинному обучению
- •14.1.3. Как правильно воспринимать глубокое обучение
- •14.1.4. Ключевые технологии
- •14.1.5. Обобщенный процесс машинного обучения
- •14.1.6. Основные архитектуры сетей
- •14.1.7. Пространство возможностей
- •14.2. Ограничения глубокого обучения
- •14.2.1. Риск очеловечивания моделей глубокого обучения
- •14.2.2 Автоматы и носители интеллекта
- •14.2.3. Локальное и экстремальное обобщение
- •14.2.4. Назначение интеллекта
- •14.2.5. Восхождение по спектру обобщения
- •14.3. Курс на увеличение универсальности в ИИ
- •14.3.2 Новая цель
- •14.4. Реализация интеллекта: недостающие ингредиенты
- •14.4.1. Интеллект как чувствительность к абстрактным аналогиям
- •14.4.2. Два полюса абстракции
- •14.4.3. Недостающая половина картины
- •14.5. Будущее глубокого обучения
- •14.5.1. Модели как программы
- •14.5.2. Сочетание глубокого обучения и синтеза программ
- •14.5.3. Непрерывное обучение и повторное использование модульных подпрограмм
- •14.5.4. Долгосрочная перспектива
- •14.6. Как не отстать от прогресса в быстроразвивающейся области
- •14.6.1. Практические решения реальных задач на сайте Kaggle
- •14.6.2. Знакомство с последними разработками на сайте arXiv
- •14.6.3. Исследование экосистемы Keras
- •Заключительное слово
12.3. Нейронная передача стиля 473
12.3. НЕЙРОННАЯ ПЕРЕДАЧА СТИЛЯ
Кроме.DeepDream,.существует.еще.одна.важная.разработка.в.области.изменения. изображений.с.использованием.глубокого.обучения.—.нейронная передача стиля,.реализованная.Леоном.Гатисом.с.коллегами.летом.2015.года1..После.своего. появления.алгоритм.нейронной.передачи.стиля.претерпел.множество.усовершенствований,.породил.множество.вариаций.и.нашел.применение.во.множестве. приложений.обработки.фотографий.для.смартфонов..Для.простоты.в.этом.разделе. основное.внимание.уделяется.формулировке.из.оригинальной.статьи.
Нейронная.передача.стиля.заключается.в.применении.стиля.изображения-об- разца.к.целевому.изображению.при.сохранении.содержимого.этого.целевого. изображения..Пример.передачи.стиля.изображен.на.рис..12.9.
Рис. 12.9. Пример передачи стиля
В.данном.контексте.под.стилем.в.основном.подразумеваются.текстуры,.цветовая.палитра.и.визуальные.шаблоны.в.различных.пространственных.масштабах;. а.под.содержимым.—.высокоуровневая.макроструктура.изображения..Например,. сине-желтые.круговые.мазки.на.рис..12.9.соответствуют.стилю.(в.качестве.об- разца.использована.картина.Винсента.Ван.Гога.«Звездная.ночь»),.а.здания.на. фотографии,.сделанной.фотографом.Тюбингеном,.—.это.содержимое.
Идея.передачи.стиля,.тесно.связанная.с.созданием.текстур,.давно.вынашивалась.в.сообществе.людей,.увлеченных.обработкой.изображений,.прежде.чем. воплотилась.в.алгоритм.нейронной.передачи.стиля.в.2015.году..Однако,.как. оказалось,.реализации.передачи.стиля,.основанные.на.глубоком.обучении,. не.имеют.аналогов.среди.прежних.достижений,.использовавших.классические. методики.компьютерного.зрения,.и.потому.они.породили.удивительный.бум. в.сфере.художественных.приложений.компьютерного.зрения.
В.основе.реализации.передачи.стиля.лежит.та.же.идея,.которая.занимает.центральное.положение.во.всех.алгоритмах.глубокого.обучения:.вы.задаете.функцию. потерь,.чтобы.определить.цель.для.достижения,.и.минимизируете.ее..Вы.знаете,. чего.хотите:.сохранить.содержимое.исходного.изображения.и.передать.стиль.
1. Gatys L. A., Ecker A. S., Bethge M..A.Neural.Algorithm.of.Artistic.Style.//.arXiv,.2015,. https://arxiv.org/abs/1508.06576.
474 Глава 12. Генеративное глубокое обучение
изображения-образца..Определив.математически.содержимое .и.стиль,.соот- ветствующую.функцию.потерь.для.минимизации.можно.обозначить.так:
loss = (distance(style(reference_image) - style(combination_image)) + distance(content(original_image) - content(combination_image)))
Здесь.distance .—.это.функция.нормы,.такой.как.L2-норма,.content .—.функция,. принимающая.изображение.и.вычисляющая.представление.его.содержимо- го, .а .style .— .функция, .принимающая .изображение .и .вычисляющая .пред- ставление.его.стиля..Минимизация.этой.функции.потерь.приводит.к.тому,. что .style(combination_image) .приближается .к .style(reference_image),. а.content(combination_image) .—.к.content(original_image),.то.есть.достигается. передача.стиля,.как.мы.ее.определили.
Фундаментальное.наблюдение,.сделанное.Гатисом.с.коллегами,.заключается. в.том,.что.глубокие.сверточные.нейронные.сети.дают.возможность.математически.определить.функции.style .и.content..Посмотрим,.как.это.происходит.
12.3.1. Функция потерь содержимого
Как.вы.уже.знаете,.активации.из.нижних.слоев.в.сети.содержат.локальную. информацию.об.изображении,.тогда.как.активации.из.верхних.слоев.содержат. все.более.глобальную,.абстрактную.информацию..Другими.словами,.активации. разных.слоев.сверточной.сети.обеспечивают.разложение.содержимого.изображения.в.разных.пространственных.масштабах..Поэтому.можно.ожидать,.что. содержимое.более.глобального.и.абстрактного.изображения.будет.захватываться. представлениями.верхних.слоев.сети.
Соответственно,.хорошим.кандидатом.на.функцию.потерь.содержимого.явля- ется.L2-норма.между.активациями.верхнего.слоя.в.предварительно.обученной. сверточной.сети,.вычисленными.по.целевому.изображению,.и.активациями. того.же.слоя,.вычисленными.по.сгенерированному.изображению..Это.гарантирует,.как.видно.из.верхнего.слоя,.что.сгенерированное.изображение.будет. выглядеть.подобно.оригинальному.целевому.изображению..Если.допустить,. что.верхние.слои.сверточной.сети.действительно.видят.содержимое.входных. изображений,.тогда.минимизация.этой.функции.может.рассматриваться.как. способ.сохранения.содержимого.изображения.
12.3.2. Функция потерь стиля
Функция.потерь.содержимого.использует.только.один.верхний.слой,.но.функция. потерь.стиля,.согласно.определению.Гатиса.и.его.коллег,.использует.несколько. слоев.сверточной.сети:.ее.цель.—.захватить.внешний.вид.стиля.изображения-об- разца.не.в.одном,.а.во.всех.пространственных.масштабах,.выделяемых.сверточной. сетью..В.качестве.функции.потерь.стиля.Гатис.с.коллегами.использует.матрицу Грама.активаций.слоя:.внутреннее.произведение.карт.признаков.данного.слоя.. Это.внутреннее.произведение.можно.интерпретировать.как.матрицу.корреляций.
12.3. Нейронная передача стиля 475
между.признаками.слоя..Корреляции.фиксируют.статистики.шаблонов.определенного.пространственного.масштаба,.которые.эмпирически.соответствуют. текстурам,.обнаруженным.в.этом.масштабе.
Следовательно,.минимизация.функции.потерь.стиля.направлена.на.сохранение. сходных.внутренних.корреляций.между.активациями.разных.слоев.изображе- ния-образца.и.генерируемого.изображения..Это,.в.свою.очередь,.гарантирует,.что. текстуры,.найденные.в.разных.пространственных.масштабах,.будут.выглядеть. одинаково.в.изображении-образце.и.сгенерированном.изображении.
Проще.говоря,.предварительно.обученную.сверточную.сеть.можно.использовать. для.определения.потерь,.и.она.будет:
.сохранять.содержимое,.поддерживая.сходство.активаций.верхнего.слоя. между.содержимым.целевого.и.сгенерированного.изображений..Сверточная. сеть.должна.«видеть».оба.изображения.—.целевое.и.сгенерированное.—.как. содержащие.одно.и.то.же;
.сохранять .стиль, .поддерживая .сходство .корреляций .в .активациях .всех,. нижних.и.верхних,.слоев..Корреляции.признаков.захватывают.текстуры:. изображение-образец.и.сгенерированное.изображение.должны.обладать. одинаковыми.текстурами.в.разных.пространственных.масштабах.
Теперь.рассмотрим.реализацию.оригинального.алгоритма.нейронной.передачи. стиля.2015.года.с.применением.Keras..Как.вы.увидите.далее,.он.имеет.много. общего.с.реализацией.DeepDream,.представленной.в.предыдущем.разделе.
12.3.3. Нейронная передача стиля в Keras
Нейронную.передачу.стиля.можно.реализовать.с.использованием.любой.обученной.сверточной.сети..Здесь.мы.возьмем.сеть.VGG19,.которую.использовали. Гатис.с.коллегами..VGG19.—.это.упрощенный.вариант.сети.VGG16,.представ- ленной.в.главе.9,.с.тремя.сверточными.слоями.
Вот.как.выглядит.весь.процесс.в.общих.чертах.
.Настройка.сети,.которая.вычисляет.активации.слоя.VGG19.одновременно. для.изображения-образца,.целевого.и.сгенерированного.изображений.
.Активации,.вычисленные.по.всем.трем.изображениям,.используются.для. определения.общей.функции.потерь,.описанной.выше,.которая.будет.минимизироваться.для.достижения.эффекта.передачи.стиля.
.Настройка.процедуры.градиентного.восхождения.для.минимизации.этой. функции.потерь.
Сначала.определим.пути.к.изображению-образцу.и.целевому.изображению..
Чтобы.гарантировать.совместимость.размеров.обрабатываемых.изображений. (сильно.различающиеся.размеры.затрудняют.передачу.стиля),.приведем.их. к.общей.высоте.400.пикселей.
476 Глава 12. Генеративное глубокое обучение
Листинг 12.16. Получение стиля и содержимого изображений from tensorflow import keras
|
|
Путь к изображению, которое |
||||
|
|
|||||
base_image_path = keras.utils.get_file( |
|
будет трансформироваться |
||||
|
|
|
|
|
|
|
"sf.jpg", origin="https://img-datasets.s3.amazonaws.com/sf.jpg") |
||||||
style_reference_image_path = keras.utils.get_file( |
|
|
Путь к изображению |
|||
|
||||||
|
|
|||||
"starry_night.jpg", |
|
|
|
с образцом стиля |
||
origin="https://img-datasets.s3.amazonaws.com/starry_night.jpg") |
||||||
original_width, original_height = keras.utils.load_img(base_image_path).size |
||||||
img_height = 400 |
|
|
|
|
Размеры генерируемого |
|
|
|
|
|
|||
img_width = round(original_width * img_height / original_height) |
изображения |
Изображение,.которое.будет.служить.нам.источником.содержимого,.показано. на.рис..12.10..На.рис..12.11.помещено.изображение.—.образец.стиля.
Рис. 12.10. Изображение с содержимым: Сан-Франциско, район Ноб-Хилл
Рис. 12.11. Образец стиля: картина Ван Гога «Звездная ночь»
12.3. Нейронная передача стиля 477
Нам.понадобится.несколько.вспомогательных.функций.для.загрузки,.а.также. для.предварительной.и.заключительной.обработки.изображений.перед.передачей.изображений.в.сеть.VGG19.и.после.вывода.их.из.сети.
Листинг 12.17. Вспомогательные функции
import numpy as np |
|
|
Открывает изображение, изменяет его размер |
||
|
|
|
|
|
|
def preprocess_image(image_path): |
|
|
и преобразует в соответствующий массив |
||
|
|
||||
img = keras.utils.load_img( |
|
|
|
||
image_path, target_size=(img_height, img_width)) |
|||||
img = keras.utils.img_to_array(img) |
|||||
img = np.expand_dims(img, axis=0) |
|||||
img = keras.applications.vgg19.preprocess_input(img) |
|||||
return img |
|
|
Вспомогательная функция для преобразования |
||
|
|
|
|
|
|
def deprocess_image(img): |
|
|
массива NumPy в допустимое изображение |
||
|
|
|
|||
img = img.reshape((img_height, img_width, 3)) |
|||||
img[:, :, 0] += 103.939 |
|
|
Центрировать относительно нуля путем удаления |
||
|
|||||
img[:, :, 1] += 116.779 |
|
|
среднего значения пикселя из ImageNet. Это отменяет |
||
img[:, :, 2] += 123.68 |
|
|
преобразование, выполненное vgg19.preprocess_input |
img |
= |
img[:, :, ::-1] |
|
Конвертировать изображения из BGR |
|
|
|||||
img |
= |
np.clip(img, 0, 255).astype("uint8") |
|||
в RGB. Также отменяет преобразование, |
|||||
return img |
выполненное vgg19.preprocess_input |
Настроим.сеть.VGG19..По.аналогии.с.реализацией.DeepDream.используем. предварительно.обученную.сверточную.сеть.и.создадим.модель,.извлекающую. признаки.и.возвращающую.активации.промежуточных.слоев.—.на.этот.раз.всех. слоев.
Листинг 12.18. Использование предварительно обученной модели VGG19 для извлечения признаков
Создать модель VGG19 с загруженными весами, полученными в результате обучения на наборе ImageNet
model = keras.applications.vgg19.VGG19(weights="imagenet", include_top=False)
outputs_dict = dict([(layer.name, layer.output) for layer in model.layers]) feature_extractor = keras.Model(inputs=model.inputs, outputs=outputs_dict)
Модель, возвращающая значения активаций всех целевых слоев (в виде словаря)
Теперь.определим.функцию.потерь.содержимого,.которая.позволит.гарантировать.сходство.представлений.целевого.и.сгенерированного.изображений. в.верхнем.слое.сети.VGG19.
Листинг 12.19. Функция потерь содержимого
def content_loss(base_img, combination_img):
return tf.reduce_sum(tf.square(combination_img - base_img))
478 Глава 12. Генеративное глубокое обучение
Далее.приводится.функция.потерь.стиля..Она.использует.вспомогательную. функцию.для.вычисления.матрицы.Грама.из.входной.матрицы:.матрицы.корреляций,.найденных.в.матрице.оригинальных.признаков.
Листинг 12.20. Функция потерь стиля
def gram_matrix(x):
x = tf.transpose(x, (2, 0, 1))
features = tf.reshape(x, (tf.shape(x)[0], -1)) gram = tf.matmul(features, tf.transpose(features)) return gram
def style_loss(style_img, combination_img): S = gram_matrix(style_img)
C = gram_matrix(combination_img) channels = 3
size = img_height * img_width
return tf.reduce_sum(tf.square(S - C)) / (4.0 * (channels ** 2) * (size ** 2))
К.этим.двум.компонентам.потерь.добавляется.третий:.функция.общей потери вариации (total.variation.loss),.которая.оперирует.пикселями.генерируемого. изображения..Она.стимулирует.пространственную.целостность.генерируемого. изображения,.что.позволяет.избежать.появления.мозаичного.эффекта..Ее.можно. интерпретировать.как.регуляризацию.потерь.
Листинг 12.21. Функция общей потери вариации
def total_variation_loss(x): a = tf.square(
x[:, : img_height - 1, : img_width - 1, :] - x[:, 1:, : img_width - 1, :]
)
b = tf.square(
x[:, : img_height - 1, : img_width - 1, :] - x[:, : img_height - 1, 1:, :]
)
return tf.reduce_sum(tf.pow(a + b, 1.25))
Функция.потерь,.которую.мы.должны.минимизировать,.возвращает.среднее. взвешенное.этих.трех.компонентов..Для.вычисления.потери.содержимого.используется.только.один.верхний.слой.block5_conv2,.а.для.вычисления.потери. содержимого.—.список.слоев,.включающий.в.себя.нижние.и.верхние.слои..Общая. потеря.вариации.добавляется.в.конец.
В.зависимости.от.используемых.изображений.с.целевым.содержимым.и.образцом.стиля,.может.появиться.желание.настроить.коэффициент.content_weight . (определяет.вклад.потерь.содержимого.в.общую.величину.потерь)..Большее. значение.content_weight .обеспечит.большее.сходство.сгенерированного.изображения.с.целевым.
12.3. Нейронная передача стиля 479
Листинг 12.22. Функция общей потери вариации, которая будет минимизироваться
style_layer_names = [ |
|
|
Список слоев, участвующих |
||||||||
|
|
||||||||||
"block1_conv1", |
|
||||||||||
|
в вычислении потери стиля |
||||||||||
"block2_conv1", |
|
||||||||||
|
|
|
|
|
|
|
|
|
|
||
"block3_conv1", |
|
|
|
|
|
|
|
|
|
||
"block4_conv1", |
|
|
|
|
|
|
|
|
|
||
"block5_conv1", |
|
|
|
|
|
|
|
|
Слой, используемый для вычисления |
||
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
потерь содержимого |
|
content_layer_name = "block5_conv2" |
|
|
|
||||||||
|
|
|
|
||||||||
total_variation_weight = 1e-6 |
|
|
|
|
|
|
|
Вес вклада общей потери вариации |
|||
|
|
|
|
|
|
|
|||||
style_weight = 1e-6 |
|
|
|
|
|
Вес вклада потери стиля |
|||||
|
|
|
|
|
|||||||
content_weight = 2.5e-8 |
|
|
Вес вклада потери содержимого |
||||||||
|
|
def compute_loss(combination_image, base_image, style_reference_image): input_tensor = tf.concat(
[base_image, style_reference_image, combination_image], axis=0)
features = feature_extractor(input_tensor) |
|
|
Инициализация |
|||||
|
||||||||
loss = tf.zeros(shape=()) |
|
|
|
потери нулями |
||||
|
|
|
||||||
layer_features = features[content_layer_name] |
|
|
|
|
||||
|
|
|
|
|||||
base_image_features = layer_features[0, :, :, :] |
Добавление потери |
|||||||
combination_features = layer_features[2, :, :, :] |
||||||||
содержимого |
||||||||
loss = loss + content_weight * content_loss( |
|
|||||||
|
Добавление |
|
||||||
base_image_features, combination_features |
|
|
||||||
) |
|
|
|
|
потери стиля |
|
||
for layer_name in style_layer_names: |
|
|
|
|
||||
|
|
|
|
|||||
layer_features = features[layer_name] |
|
|
|
|
||||
style_reference_features = layer_features[1, :, :, :] |
|
|
||||||
combination_features = layer_features[2, :, :, :] |
|
|
||||||
|
|
|||||||
style_loss_value = style_loss( |
|
|
|
|
||||
style_reference_features, combination_features) |
|
|
||||||
loss += (style_weight / len(style_layer_names)) * style_loss_value |
|
|
loss += total_variation_weight * total_variation_loss(combination_image)
return loss
Добавление общей потери вариации
Наконец,.настроим.процесс.градиентного.восхождения..В.оригинальной.статье. Гатиса.оптимизация.проводится.с.использованием.алгоритма.L-BFGS,.но.он. недоступен.в.TensorFlow,.поэтому.мы.выполним.обычный.мини-пакетный. градиентный.спуск.с.оптимизатором.SGD..При.этом.мы.будем.использовать.особенность.оптимизатора,.которую.вы.еще.не.видели:.возможность.планирования. скорости.обучения..Мы.воспользуемся.ею,.чтобы.постепенно.снижать.скорость. обучения.с.очень.высокого.значения.(100).до.гораздо.меньшего.конечного. значения.(около.20)..Так.мы.добьемся.быстрого.прогресса.на.ранних.этапах. обучения,.а.затем.будем.действовать.более.осторожно.по.мере.приближения. к.минимуму.потерь.
480 Глава 12. Генеративное глубокое обучение
Листинг 12.23. Настройка процесса градиентного спуска
import tensorflow as tf |
Чтобы ускорить обучение, |
|
|
|
|
|
|
|
@tf.function |
|
скомпилируем его как tf.function |
|
def compute_loss_and_grads(
combination_image, base_image, style_reference_image): with tf.GradientTape() as tape:
loss = compute_loss(
|
combination_image, base_image, style_reference_image) |
|||
grads = |
tape.gradient(loss, combination_image) |
|
|
|
return loss, grads |
|
На первых этапах используем |
||
|
||||
|
|
|
|
скорость обучения 100, а затем |
optimizer = |
keras.optimizers.SGD( |
|
будем уменьшать ее на 4 % |
|
keras.optimizers.schedules.ExponentialDecay( |
|
|
через каждые 100 шагов |
|
|
|
initial_learning_rate=100.0, decay_steps=100, decay_rate=0.96
)
)
base_image = preprocess_image(base_image_path)
style_reference_image = preprocess_image(style_reference_image_path) combination_image = tf.Variable(preprocess_image(base_image_path))
iterations = 4000 |
Используем Variable для хранения |
||||
комбинированного изображения, которое |
|||||
for i in range(1, iterations + 1): |
|||||
будет изменяться в процессе обучения |
|||||
loss, grads = compute_loss_and_grads( |
|||||
|
|
|
|
||
combination_image, base_image, style_reference_image |
|
Обновим |
|||
|
|||||
) |
|
|
|
||
|
|
|
комбинированное |
||
optimizer.apply_gradients([(grads, combination_image)]) |
|
|
|||
|
|
изображение |
|||
|
|
||||
if i % 100 == 0: |
|
|
|
в направлении |
|
print(f"Iteration {i}: loss={loss:.2f}") |
|
|
|
уменьшения потери |
|
img = deprocess_image(combination_image.numpy()) |
|
передачи стиля |
|||
|
fname = f"combination_image_at_iteration_{i}.png" keras.utils.save_img(fname, img)
На.рис..12.12.показано,.что.получается.в.результате..Имейте.в.виду,.что.этот. прием.—.лишь.одна.из.форм.ретекстурирования.изображений,.или.передачи. текстуры..Лучшие.результаты.с.его.применением.получаются,.если.изображения. с.образцами.стилей.сильно.текстурированы.и.самоподобны,.а.целевые.изображения.с.содержимым.не.требуют.различения.мелких.деталей,.чтобы.их.можно. было.опознать..Этот.прием.не.наделен.возможностями.абстрагирования.—.с.его. помощью.едва.ли.получится.перенести.стиль.из.одного.портрета.в.другой..Данный.алгоритм.ближе.к.классической.обработке.сигналов,.чем.к.ИИ,.поэтому. не.нужно.ожидать.от.него.чего-то.сверхъестественного!
Кроме.того,.учтите,.что.этот.алгоритм.передачи.стиля.выполняется.довольно. медленно..Однако.выполняемые.преобразования.достаточно.просты,.чтобы.их. можно.было.исследовать.с.использованием.небольшой.и.быстрой.сверточной. сети.при.наличии.достаточного.объема.обучающих.данных..Быстрой.передачи.