自编码器与图像分辨率提升

在数字摄影时代之前,冲洗照片是一个神秘的过程,只有摄影师和专家才能驾驭。只能看到被昏暗的红灯照亮的暗室。简而言之,获取照片是一个耗时的过程。随着数码相机革命的开始,再也没有回头!甚至不再费心打印照片了——大多数人的照片都在智能手机、笔记本电脑或某些云存储中。

可能想知道照片和自编码器有什么关系。嗯,正是自编码器使能够增强和改善数字照片的质量!即使现在,也会遇到(并点击)模糊、像素化和不清晰的图片。肯定对此感到内疚,知道很多人在点击完美照片时也遇到了困难。这就是深度学习和自编码器概念帮助地方。

将学习自编码器是什么以及它们是如何工作的。然后,将使用Python中的自编码器解决一个现实世界的问题——提高图像分辨率。

前提条件:熟悉Keras、使用神经网络进行图像分类和卷积层。如果需要复习这些概念,请查看这些资源:神经网络入门(免费课程)、构建第一个图像分类模型。

什么是自编码器?根据Pulkit Sharma的文章:“自编码器本质上是神经网络架构,其目标是学习输入数据的低维特征表示。”自编码器由两个连接的网络组成——编码器和解码器。编码器的目标是接收一个输入(x)并产生一个特征映射(z):

# 编码器的目标是接收一个输入(x)并产生一个特征映射(z) encoder_input = Input(shape=(input_shape,)) encoded = encoder_model(encoder_input)

这个特征映射(z)的大小或长度通常比x小。认为为什么会这样?因为希望z只捕捉能够描述输入数据的有意义的变化因素,所以z的形状通常比x小。

现在,问题是,如何学习这个特征表示(z)?如何训练这个模型?为此,可以在提取的特征之上添加一个解码器网络,然后训练模型:

# 在提取的特征之上添加一个解码器网络 decoder_input = Input(shape=(encoded.shape[1],)) decoded = decoder_model(decoder_input)

这个网络被训练成可以使用特征(z)重建原始输入数据(x)。如果输出(Ẋ)与输入(x)不同,损失会惩罚它并帮助重建输入数据。

将解决的问题与图像去噪自编码器的工作原理相关。让详细了解自编码器如何被部署来从任何给定的图像中去除噪声。假设有一组手写数字图像,其中一些已经被破坏。以下是一些带有噪声(破坏)的图像:

从图像中去除这种噪声被称为图像去噪问题。期望的输出是干净的图像,其中大部分噪声已经被去除,如下所示:

但是自编码器如何从图像中去除这种噪声呢?正如在前一节已经看到的,自编码器试图重建输入数据。所以,如果将损坏的图像作为输入,自编码器将尝试重建噪声图像。那么现在应该做什么?改变架构?实际上并不是!只需要一个小小的调整。不是使用输入和重建的输出来计算损失,而是可以通过使用真实图像和重建图像来计算损失。这个图表很好地说明了观点:

# 使用真实图像和重建图像来计算损失 from keras.losses import mean_squared_error def autoencoder_loss(y_true, y_pred): return mean_squared_error(y_true, y_pred)

现在已经熟悉了去噪自编码器的工作原理,让继续解决想要使用自编码器解决的问题。

问题陈述——使用自编码器提高图像分辨率。一定对这个问题很熟悉。大多数人都在努力点击模糊的图像,并努力提高它们的分辨率。好吧,将在这里使用自编码器解决这个问题!假设有一组低分辨率的人脸图像。任务是提高这些图像的分辨率。这可以使用Photoshop等照片编辑工具完成。但是,当有成千上万的图像需要处理时,需要一种更智能的方式来完成这项任务。

让打开Jupyter笔记本并导入所需的库:

# 导入所需的库 import numpy as np import glob import matplotlib.pyplot as plt from keras.preprocessing.image import ImageDataGenerator

将在流行的“Labeled Faces in the Wild”数据集上工作。这是一个为研究无约束人脸识别问题而设计的人脸照片数据库。然而,这里目标不是人脸识别,而是构建一个模型来提高图像分辨率。让下载并提取数据集:

# 下载并提取数据集 !wget http://vis-www.cs.umass.edu/lfw/lfw.tgz !tar -xvzf lfw.tgz

这个数据集将被提取到多个文件夹中。因此,捕获所有图像的文件路径非常重要。可以很容易地使用glob库来做到这一点:

# 捕获图像的路径 face_images = glob.glob('lfw/**/*.jpg')

加载和预处理图像。图像的原始大小是250 x 250像素。然而,使用这些图像在配置适中的系统上会消耗相当多的计算能力。因此,将缩小所有图像的大小:

# 缩小所有图像的大小 from keras.preprocessing.image import img_to_array, load_img from tqdm import tqdm def load_and_preprocess_images(image_paths, image_size=(250, 250)): images = [] for img_path in tqdm(image_paths): img = load_img(img_path, target_size=image_size) img = img_to_array(img) images.append(img) return np.array(images)

数据准备用于模型训练。接下来,将数据集(图像)分成两组——训练和验证。将使用训练集来训练模型,并使用验证集来评估模型的性能:

# 将数据集分成训练和验证集 from sklearn.model_selection import train_test_split train_images, val_images = train_test_split(images, test_size=0.2, random_state=42)

让看看数据集中的一张图像:

这个练习的想法与去噪自编码器中使用的想法非常相似。将对输入图像进行一些修改,并使用原始图像计算损失。由于这是一个分辨率增强任务,将降低原始图像的分辨率并将其作为输入提供给模型。

# 降低原始图像的分辨率 from keras.preprocessing.image import img_to_array, load_img def downsample_images(image_paths, image_size=(50, 50)): images = [] for img_path in tqdm(image_paths): img = load_img(img_path, target_size=image_size) img = img_to_array(img) images.append(img) return np.array(images)

让降低所有图像的分辨率。将为训练集和验证集都这样做:

# 为训练集和验证集降低所有图像的分辨率 train_images_low_res = downsample_images(train_image_paths) val_images_low_res = downsample_images(val_image_paths)

构建模型。让定义模型的结构:

# 定义模型结构 from keras.layers import Input, Dense from keras.models import Model encoder_input = Input(shape=(input_shape,)) encoded = Dense(128, activation='relu')(encoder_input) decoded = Dense(input_shape, activation='sigmoid')(encoded) autoencoder = Model(encoder_input, decoded)

可以随时修改这个架构。可以改变层的数量,改变层的类型,使用正则化等等。目前,让继续使用这个架构。

# 可视化模型架构 autoencoder.summary() # 训练模型 autoencoder.compile(optimizer='adam', loss='mean_squared_error') autoencoder.fit(train_images, train_images, epochs=50, batch_size=256, shuffle=True, validation_data=(val_images, val_images)) # 进行预测 predictions = autoencoder.predict(val_images_low_res)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485