摘要:想不想将神经网络训练成一个“放大镜”?我们就训练了一个这样炫酷的神经网络,点击文章一起看下吧!
当我们网购时,我们肯定希望有一个贴近现实的购物体验,也就是说能够全方位的看清楚产品的细节。而分辨率高的大图像能够对商品进行更加详细的介绍,这真的可以改变顾客的购物体验,让顾客有个特别棒的购物之旅。idealo.de 是欧洲领先的比价网站,也是德国电子商务市场最大的门户网站之一,在此基础上,我们希望能够在此基础上为用户提供一个用户友好、有吸引力的购物平台。
在这里,我们利用深度学习来评估数百万酒店图像的美学层次和技术质量,另外,那些没有任何信息的、特别难看的小的产品图像对我们来说是无效的,因此需要想办法解决。
购物网站上并不是所有的商店都能为顾客提供高质量的图像,相反,商家提供的图像特别小、分辨率特别低、质量也很低。为了向用户展示高质量的高分辨率图像,我们基于 2018 年的论文《图像超分辨率的 RDN 网络》,训练了一个特别先进的卷积神经网络。
我们的目标很简单:拍摄一些特别小的图像,然后就像使用放大镜一样,对图像进行放大,并且还要保持高分辨率。
本文对实现这一目标做了详细介绍,另外,具体实现的细节,请查看 GitHub。
总概
与大多数深度学习项目一样,我们的深度学习项目主要有四个步骤:
1. 回顾前人对该项目所做的贡献。
2. 实施一个或多个解决方案,然后比较预先训练的版本。
3. 获取数据,训练并测试模型。
4. 针对训练和验证结果对模型进行改进和优化。
具体来说,本文主要有以下几方面的内容:
1. 介绍模型训练的配置,如何评估模型的性能
2. 查看早期训练和测试结果,了解从哪方面进行改进。
3. 指出后续需要探索的方向。
训练
与以往“标准”的监督深度学习任务不同,我们这个“放大镜”深度学习模型输出的不仅仅是类标签或一个分数,而是一整幅图像。这就意味着训练过程以及评估会跟以往略有不同,我们要输出的是原始高分辨率图像,为了更好的对模型进行评估,我们需要一种测量缩放输出图像“质量”的方法,该方法更详细的优缺点将在后面进一步做详细阐释。
损失函数
损失函数是用来评估神经网络的性能究竟如何,这个有很多方法可以评估。这个问题的本质为大家留下了创造力空间,如有些聪明的人会用高级特征和对抗网络。对于第一次迭代,我们使用标准方法:网络的超分辨率(SR)输出和高分辨率输出(HR)之间的像素均方差(MSE)。
评估
我们用峰值信噪比(PSNR)来评估输出图像的质量,峰值信噪比是基于两个图像之间的像素均方差(MSE)。由于峰值信噪比是最常用的评估输出图像质量的方法,因此我们也使用这一评估标准,以便将本文模型与其他模型作比较。
开始
我们在 p2.xlarge AWS EC2 实例上进行训练,直到验证损失函数收敛,训练结束,这大概需要 90 个周期(一个周期 24 小时),然后使用 Tensorboard 跟踪训练数据集及验证数据集的损失函数和 PSNR 值。
如上图所示,左上角为在每个周期结束时,反向传播到神经网络上的训练损失函数。右上角为跟踪泛化性能的非训练数据及的损失。左下角为训练数据集的 PSNR 值。右下角为验证数据集的 PSNR 值。
结果
输出的结果如下所示,我们先看看模型的输出结果,再考虑如何对该模型进行改进。左侧是验证数据集中的整个图像,中间是卷积神经网络的输出提取图像块,右侧是使用标准过程将中间输出提取图像块按比例放大后的输出,这里使用了 GIMP 的图像缩放功能
![LR 图像(左),重建 SR(中),GIMP 基线缩放(右)。](https://upload-images.jianshu…
这个结果肯定不是特别完美:蝴蝶的天线周围有些没必要的噪声,蝴蝶的颈部和背部的毛发及翅膀上有些斑点轮廓,神经网络的输出图像(中)看起来要比 GIMP 基线输出图像(右)更加清晰。
结果分析
为了进一步理解模型有哪些优缺点,我们需要从验证数据集中提取具有高 PSNR 值的图像块和具有低能量度值的图像块。
不出所料,性能最佳的图像块是具有较多平坦区域的图像块,而较为复杂的图像块难以准确再现。因此,我们重点关注这些较复杂的图像块,以便对结果进行训练和评估。
同样的,我们也可以使用热图(heatmap)突出显示原始 HR 图像和神经网络输出 SR 图像之间的误差,颜色较暗的部分对应于较高的像素均方误差(较差的结果),颜色较浅的部分对应于较低的像素均方误差(或较好的结果)
我们可以看到,具有多种模式的区域的误差会更大,但是看起来“更简单”的过渡区域则是相当黑暗的(例如云、天空),这是可以改进的,因为它与 idealo 的目录用例相关。
浅谈深度学习任务中的非真实数据
与常见的分类问题或输出为一个分值的监督式深度学习任务不同,我们用于评估神经网络输出的真实数据是原始 HR 图像。
这既有好处,也有坏处。
坏处:像 Keras 这样的当前较为流行的深度学习框架没有预先制定训练解决方案,比如生成器。实际上,它们通常依赖于从一维数组中获取训练和验证标签或文件,或者是直接从文件结构中派生出来的,这会涉及到一些额外的编码算法。
好处:没有必要花太多时间来获得标签,给出一个 HR 图像池,我们可以对其进行简单的缩小,获得我们所需要的 LR 训练数据,并使用原始 HR 图像来评估损失函数
通常来说,使用图像数据对神经网络进行训练时,需要从训练数据集中随机的选择多个图像来创建训练批次。然后将这些尺寸重新缩小到一个较小的尺寸,一般来说,大小约为 100×100 像素。我们随时使用随机变换对图像进行增强,并反馈到神经网络中。在这种情况下,没有必要向神经网络反馈整张图像,并且这也非常不可取。这是因为,我们不能将图像重新缩放到 100×100 的小像素点。毕竟,我们想要对图像进行放大。同时,我们也无法用较大尺寸的图像进行训练,比如大小为 500×600 像素的图像,因为处理这种大图像需要很长的时间。相反,我们可以从整个图像中提取一个非常小的随机色块,比如大小为 16×16 像素块,这样一来,我们就有了更多的数据点,因为每个图像都可以提供数百个不同的色块。
我们之所以能够处理这种小色块,是因为我们不需要将一堆图像进行分类,比如:腿 + 尾巴 + 胡须 + 死老鼠 = 猫。因此,模型的末端就没有全连接层。我们只需要使用神经网络来构建这些模式的抽象表示,然后学习如何对其进行放大,除此以外,还要对块进行重新组合,使组合后的图像变得有意义。这种抽象表示由卷积层和放大层来完成,其中,卷积层是该网络中唯一的一种层类型。
我们还要说明的是,全卷积结构使该网络的输入大小相互独立。也就是说,这意味着它与普通的分类卷积神经网络有所不同,你可以向完全卷积神经网络中输入任何大小的图像:无论输入图像原始大小是什么,网络都会输入一个输入图像大小 2 倍的图像。
有关图像超分辨率的 RDN 网络更加详细的介绍,请查看文末链接。
另一方面,我们还需要思考如何从图像中提取这些块。思路如下:从数据集中提取出 n 个随机图像,然后从每个图像中提取 p 个随机快。我们尝试了几种方法,如下图所示:
首先,从一个均匀的网格中提出块,并创建一个完整的块数据集。在训练的时候,我们随机的提取其 batch_size,并对其进行放大,反馈给网络。这种方法的缺点是需要静态的存储非常大的数据集,如果要用云服务器进行训练,这种方法其实并不理想:移动和提取数据集是一项相当耗时的操作,并且具有确定性定义的数据集可能并不是最佳数据集。
另一种方法是随机选择 batch_size 大小的图像,并从中提取单个块。这种方法需要从磁盘中读取数据,这就大大降低了训练时间(我们设置的每个训练时间为 15min-1h)。
最后,我们将原始数据集中随机提取的单个图像块进行融合,并从中提取动态的 batch_size 块,这不仅能存储原始数据集,同时,也能保持较快的训练速度。
拓展
这是放大 idealo 网站产品目录的第一步,我们已经完成了。
下面是我们将产品图像中低质量、低分辨率的图像进行放大,并输出。
从上图中,我们可以看到,图像中较为平坦的地方会产生较为明显的噪声,文本也会略有失真。这就是我们计划要改进的地方。
在下一步的探索中,我们将在自己的产品图像数据集上对神经网络进行训练。
相关链接
Github: Image Super Resolution
Paper: Residual Dense Network for Image Super-Resolution (Zhang et al. 2018)
Dataset: DIVerse 2K resolution high quality images
本文作者:【方向】阅读原文
本文为云栖社区原创内容,未经允许不得转载。