В этом посте я покажу, как создать сеть автокодировщика, которая может сверхразрешить изображение до 4x, а также способы увеличения его до 10x и, возможно, даже больше.
Зачем использовать автоэнкодер?
Есть много причин, по которым вы можете захотеть использовать этот тип сети, один из примеров - передача изображения в приложении чата. Приложения чата, такие как WhatsApp и Instagram, используют этот тип сжатия, хотя они более сложные и обучаемые в течение более длительного времени и с гораздо большим объемом данных, они используют, потому что из-за сжатия изображения объем данных для загрузки уменьшается, что снижает скорость загрузки. увеличиваются, а также уменьшается объем данных для хранения на серверах без потери качества изображения.
Ссылка на блокнот
Связываю Colab Notebook для проекта здесь. Я буду использовать Google Colab, поскольку они предоставляют бесплатные облачные графические процессоры для обучения, что делает ненужными мощные машины для этих задач.
Обзор
Прежде всего, я проведу вас через построение кодировочной части сети по отдельности, а затем сделаю кодировщик и декодер, подключу его и обучу его с пользовательскими данными, и на протяжении всего этого я также буду объяснять нейронную сеть автокодера и способы Улучши это.
Библиотеки для импорта
Мы будем использовать Tensorflow 2.0 для построения сети, модуль U rllib для загрузки изображений, Numpy для обработки массива изображений, Open -Cv2 для изменения размера изображения, модуль Os для загрузки изображений и Matplotlib для отображения изображений.
Что такое автоэнкодеры?
Автоэнкодер - это просто неконтролируемая нейронная сеть, которая изначально учится сокращать объем данных и восстанавливать их, теряя как можно меньше данных.
Как вы уже догадались, он состоит из кодировщика и декодера. Роль кодировщика состоит в том, чтобы сжимать данные до более низкого измерения таким образом, чтобы сохранялись только наиболее важные функции, такие как PCA, а роль декодера - восстанавливать данные из представления более низкого измерения, чтобы как можно ближе к нему приблизиться. оригинал.
Сборка кодировщика
Здесь у нас есть 2 блока Conv2D, так как у нас есть изображения всего 256 пикселей в высоту и ширину. Однако при использовании изображений размером 1920 X 1080 пикселей я бы предложил использовать более 4 блоков Conv2D с увеличением фильтра в 2 раза. Это обеспечит наличие достаточного количества параметров для изменения и достаточного количества фильтров, которые в конечном итоге можно будет использовать для сверхразрешения изображения до 10x.
Вот краткое изложение модели.
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_2 (InputLayer) [(None, 256, 256, 3)] 0 _________________________________________________________________ conv2d_5 (Conv2D) (None, 256, 256, 64) 1792 _________________________________________________________________ conv2d_6 (Conv2D) (None, 256, 256, 64) 36928 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 128, 128, 64) 0 _________________________________________________________________ conv2d_7 (Conv2D) (None, 128, 128, 128) 73856 _________________________________________________________________ conv2d_8 (Conv2D) (None, 128, 128, 128) 147584 _________________________________________________________________ max_pooling2d_3 (MaxPooling2 (None, 64, 64, 128) 0 _________________________________________________________________ conv2d_9 (Conv2D) (None, 64, 64, 256) 295168 ================================================================= Total params: 555,328 Trainable params: 555,328 Non-trainable params: 0 _________________________________________________________________
Как видите, у нас есть 256 фильтров, мы могли бы остановиться на 128 или 64, но у нас не так много изображений, с которыми можно было бы тренироваться, а также реальные размеры изображения всего 256X 256, и из-за этого , мы должны компенсировать это, используя множество фильтров. Хотя в реальной жизни изображение будет 1920 X 1080, и поэтому сжатие до 192 X 108 будет гораздо более очевидным.
Изображение, чтобы лучше понять поток кодировщика
Вся модель
Как вы можете видеть, мы используем повышающую дискретизацию вместо Conv2D Transpose, это связано с тем, что транспонирование Conv2D имеет обучаемые параметры, но при этом полезно для нашей задачи, оно увеличивает время обучения и небольшой объем данных, который у нас есть, он не нужен, но, безусловно, для Для моделей производственного уровня обязательно использовать слой Conv2D Transpose вместо слоя Upsampling2D.
Вот резюме,
Model: "model_15" _______________________________________________________________ Layer (type) Output Shape Param # =============================================================== input_21 (InputLayer) [(None, 256, 256, 3) 0 ________________________________________________________________ conv2d_141 (Conv2D) (None, 256, 256, 64) 1792 ________________________________________________________________ conv2d_142 (Conv2D) (None, 256, 256, 64) 36928 ________________________________________________________________ max_pooling2d_36 (MaxPooling2D) (None, 128, 128, 64) 0 ________________________________________________________________ conv2d_143 (Conv2D) (None, 128, 128, 128 73856 ________________________________________________________________ conv2d_144 (Conv2D) (None, 128, 128, 128 147584 ________________________________________________________________ max_pooling2d_37 (MaxPooling2D) (None, 64, 64, 128) 0 ________________________________________________________________ conv2d_145 (Conv2D) (None, 64, 64, 256) 295168 ________________________________________________________________ up_sampling2d_21 (UpSampling2D) (None, 128, 128, 256 0 ________________________________________________________________ conv2d_146 (Conv2D) (None, 128, 128, 128 295040 ________________________________________________________________ conv2d_147 (Conv2D) (None, 128, 128, 128 147584 ________________________________________________________________ add_20 (Add) (None, 128, 128, 128 0 ________________________________________________________________ up_sampling2d_22 (UpSampling2D) (None, 256, 256, 128 0 ________________________________________________________________ conv2d_148 (Conv2D) (None, 256, 256, 64) 73792 ________________________________________________________________ conv2d_149 (Conv2D) (None, 256, 256, 64) 36928 ________________________________________________________________ add_21 (Add) (None, 256, 256, 64) 0 ________________________________________________________________ conv2d_150 (Conv2D) (None, 256, 256, 3) 1731 ================================================================ Total params: 1,110,403 Trainable params: 1,110,403 Non-trainable params: 0 ________________________________________________________________
Как вы могли заметить, мы используем остаточное соединение между кодером и декодером, это сделано для уменьшения результатов с потерями окончательного реконструированного изображения, это может или не может быть необходимо в соответствии с объемом ваших обучающих данных, что делает его необязательным.
Остаточное соединение более очевидно на этой диаграмме:
Как вы могли заметить, мы используем среднеквадратичную ошибку в качестве функции потерь, которая, возможно, является худшей, но самой быстрой, и поэтому я использовал ее здесь.
Однако я предлагаю не использовать его в продакшене, а использовать Perpetual loss, он лучше, чем MSE. Исследовательскую статью, объясняющую потерю, можно найти здесь.
Получение данных и метод обучения
Я получил изображения автомобилей из сети изображений с помощью Urllib, а затем использовал OpenCV, чтобы изменить размер изображения до 1/4 его размера. Использование изображения с измененным размером с большой потерей данных в качестве входных данных и исходного изображения сверхвысокого разрешения в качестве изображения для сравнения потерь.
Таким образом, модель будет постепенно учиться увеличивать разрешение изображения до 4-кратного его исходного разрешения, оптимизируя потери между восстановленным и исходным изображением.
Конечный результат
Как видите, наш автоэнкодер отлично справляется со своей задачей!
Места для улучшения
Ниже приведены способы увеличения сверхвысокого разрешения до 10 раз, а может быть, даже больше!
- Самым важным моментом было бы использовать изображения Full HD для обучения модели, а также использовать более 5000 изображений.
- Используйте слои Conv2D Transpose вместо слоев Upscaling.
- Используйте Perceptual Loss вместо MSE.
- Используйте оптимизатор Adam вместо Adadelta.
- Используйте Сверточные слои с динамической регуляризацией.
Примечание
Я впервые пишу статью и что-то объясняю, поэтому, пожалуйста, дайте мне знать, как я могу улучшить, а также сообщите, если вы чего-то не поняли. Я буду более чем счастлив помочь. Кроме того, подробное объяснение кода можно найти здесь: https://www.coursera.org/learn/image-super-resolution-autoencoders-keras/