利用卷积自编码器对图片进行降噪 自编码器图像去噪

   2023-02-12 学习力499
核心提示:前言这周工作太忙,本来想更把 Attention tranlsation 写出来,但一直抽不出时间,等后面有时间再来写。我们这周来看一个简单的自编码器实战代码,关于自编码器的理论介绍我就不详细介绍了,网上一搜一大把。最简单的自编码器就是通过一个 encoder 和 decoder

前言

这周工作太忙,本来想更把 Attention tranlsation 写出来,但一直抽不出时间,等后面有时间再来写。我们这周来看一个简单的自编码器实战代码,关于自编码器的理论介绍我就不详细介绍了,网上一搜一大把。最简单的自编码器就是通过一个 encoder 和 decoder 来对输入进行复现,例如我们将一个图片输入到一个网络中,自编码器的 encoder 对图片进行压缩,得到压缩后的信息,进而 decoder 再将这个信息进行解码从而复现原图。

利用卷积自编码器对图片进行降噪

作图工具:OmniGraffle

自编码器实际上是通过去最小化 target 和 input 的差别来进行优化,即让输出层尽可能地去复现原来的信息。由于自编码器的基础形式比较简单,对于它的一些变体也非常之多,包括 DAE,SDAE,VAE 等等,如果感兴趣的小伙伴可以去网上搜一下其他相关信息。

本篇文章将实现两个 Demo,第一部分即实现一个简单的 input-hidden-output 结的自编码器,第二部分将在第一部分的基础上实现卷积自编码器来对图片进行降噪。

工具说明

  • TensorFlow1.0

  • jupyter notebook

  • 数据:MNIST 手写数据集

  • 完整代码地址:NELSONZHAO/zhihu

第一部分

首先我们将实现一个如上图结构的最简单的 AutoEncoder。

加载数据

在这里,我们使用 MNIST 手写数据集来进行实验。首先我们需要导入数据,TensorFlow 已经封装了这个实验数据集,所以我们使用起来也非常简单。

利用卷积自编码器对图片进行降噪

如果想让数据显示灰度图像,使用代码 plt.imshow(img.reshape((28,28)), cmap=\'Greys_r\') 即可。

通过 input_data 就可以加载我们的数据集。如果小伙伴本地已经有了 MNIST 数据集(四个压缩包),可以把这四个压缩包放在目录 MNIST_data 下,这样 TensorFlow 就会直接 Extract 数据,而不用再重新下载。我们可以通过 imshow 来随便查看一个图像。由于我们加载进来的数据已经被处理成一个 784 维度的向量,因此重新显示的时候需要 reshape 一下。

构建模型

我们把数据加载进来以后就可以进行最简单的建模。在这之前,我们首先来获取一下 input 数据的大小,我们加载进来的图片是 28x28 的像素块,TensorFlow 已经帮我们处理成了 784 维度的向量。同时我们还需要指定一下 hidden layer 的大小。

利用卷积自编码器对图片进行降噪

在这里我指定了 64,hidden_units 越小,意味着信息损失的越多,小伙伴们也可以尝试一下其他的大小来看看结果。

AutoEncoder 中包含了 input,hidden 和 output 三层。

利用卷积自编码器对图片进行降噪

在隐层,我们采用了 ReLU 作为激活函数。

至此,一个简单的 AutoEncoder 就构造完成,接下来我们可以启动 TensorFlow 的 graph 来进行训练。

利用卷积自编码器对图片进行降噪

训练结果可视化

经过上面的步骤,我们构造了一个简单的 AutoEncoder,下面我们将对结果进行可视化看一下它的表现。

利用卷积自编码器对图片进行降噪

这里,我挑选了测试数据集中的 5 个样本来进行可视化,同样的,如果想观察灰度图像,指定 cmap 参数为\'Greys_r\'即可。上面一行为 test 数据集中原始图片,第二行是经过 AutoEncoder 复现以后的图片,可以很明显的看到像素信息的损失。

同样,我们也可以把隐层压缩的数据拿出来可视化,结果如下:

利用卷积自编码器对图片进行降噪

这五张图分别对应了 test 中五张图片的隐层压缩后的图像。

通过上面一个简单的例子,我们了解了 AutoEncoder 的基本工作原理,下面我们将更进一步改进我们的模型,将隐层转换为卷积层来进行图像降噪。

上面过程中省略了一部分代码,完整代码请去我的 GitHub 上查看。

第二部分

在了解了上面 AutoEncoder 工作原理的基础上,我们在这一部分将对 AutoEncoder 加入多个卷积层来进行图片的降噪处理。

同样的我们还是使用 MNIST 数据集来进行实验,关于数据导入的步骤不再赘述,请下载代码查看。在开始之前,我们先通过一张图片来看一下我们的整个模型结构:

利用卷积自编码器对图片进行降噪

作图工具:OmniGraffle

我们通过向模型输入一个带有噪声的图片,在输出端给模型没有噪声的图片,让模型通过卷积自编码器去学习降噪的过程。

输入层

利用卷积自编码器对图片进行降噪

这里的输入层和我们上一部分的输入层已经不同,因为这里我们要使用卷积操作,因此,输入层应该是一个 height x width x depth 的一个图像,一般的图像 depth 是 RGB 格式三层,这里我们的 MNIST 数据集的 depth 只有 1。

Encoder 卷积层

Encoder 卷积层设置了三层卷积加池化层,对图像进行处理。

利用卷积自编码器对图片进行降噪

第一层卷积中,我们使用了 64 个大小为 3 x 3 的滤波器(filter),strides 默认为 1,padding 设置为 same 后我们的 height 和 width 不会被改变,因此经过第一层卷积以后,我们得到的数据从最初的 28 x 28 x 1 变为 28 x 28 x 64。

紧接着对卷积结果进行最大池化操作(max pooling),这里我设置了 size 和 stride 都是 2 x 2,池化操作不改变卷积结果的深度,因此池化以后的大小为 14 x 14 x 64。

对于其他卷积层不再赘述。所有卷积层的激活函数都是用了 ReLU。

经过三层的卷积和池化操作以后,我们得到的 conv3 实际上就相当于上一部分中 AutoEncoder 的隐层,这一层的数据已经被压缩为 4 x 4 x 32 的大小。

至此,我们就完成了 Encoder 端的卷积操作,数据维度从开始的 28 x 28 x 1 变成了 4 x 4 x 32。

Decoder 卷积层

接下来我们就要开始进行 Decoder 端的卷积。在这之前,可能有小伙伴要问了,既然 Encoder 中都已经把图片卷成了 4 x 4 x 32,我们如果继续在 Decoder 进行卷积的话,那岂不是得到的数据 size 越来越小?所以,在 Decoder 端,我们并不是单纯进行卷积操作,而是使用了 Upsample(中文翻译可以为上采样)+ 卷积的组合。

我们知道卷积操作是通过一个滤波器对图片中的每个 patch 进行扫描,进而对 patch 中的像素块加权求和后再进行非线性处理。举个例子,原图中我们的 patch 的大小假如是 3 x 3(说的通俗点就是一张图片中我们取其中一个 3 x 3 大小的像素块出来),接着我们使用 3 x 3 的滤波器对这个 patch 进行处理,那么这个 patch 经过卷积以后就变成了 1 个像素块。在 Deconvolution 中(或者叫 transposed convolution)这一过程是反过来的,1 个像素块会被扩展成 3 x 3 的像素块。

但是 Deconvolution 有一些弊端,它会导致图片中出现 checkerboard patterns,这是因为在 Deconvolution 的过程中,滤波器中会出现很多重叠。为了解决这个问题,有人提出了使用 Upsample 加卷积层来进行解决。

关于 Upsample 有两种常见的方式,一种是 nearest neighbor interpolation,另一种是 bilinear interpolation。

本文也会使用 Upsample 加卷积的方式来进行 Decoder 端的处理。

利用卷积自编码器对图片进行降噪

在 TensorFlow 中也封装了对 Upsample 的操作,我们使用 resize_nearest_neighbor 对 Encoder 卷积的结果 resize,进而再进行卷积处理。经过三次 Upsample 的操作,我们得到了 28 x 28 x 64 的数据大小。最后,我们要将这个结果再进行一次卷积,处理成我们原始图像的大小。

利用卷积自编码器对图片进行降噪

最后一步定义 loss 和 optimizer。

利用卷积自编码器对图片进行降噪

loss 函数我们使用了交叉熵进行计算,优化函数学习率为 0.001。

构造噪声数据

通过上面的步骤我们就构造完了整个卷积自编码器模型。由于我们想通过这个模型对图片进行降噪,因此在训练之前我们还需要在原始数据的基础上构造一下我们的噪声数据。

利用卷积自编码器对图片进行降噪

我们通过上面一个简单的例子来看一下如何加入噪声,我们获取一张图片的数据 img(大小为 784),在它的基础上加入噪声因子乘以随机数的结果,就会改变图片上的像素。接着,由于 MNIST 数据的每个像素数据都被处理成了 0-1 之间的数,所以我们通过 numpy.clip 对加入噪声的图片进行 clip 操作,保证每个像素数据还是在 0-1 之间。

np.random.randn(*img.shape) 的操作等于 np.random.randn(img.shape[0], img.shape[1])

我们下来来看一下加入噪声前后的图像对比。

利用卷积自编码器对图片进行降噪

训练模型

介绍完模型构建和噪声处理,我们接下来就可以训练我们的模型了。

利用卷积自编码器对图片进行降噪

在训练模型时,我们的输入已经变成了加入噪声后的数据,而输出是我们的原始没有噪声的数据,主要要对原始数据进行 reshape 操作,变成与 inputs_相同的格式。由于卷积操作的深度,所以模型训练时候有些慢,建议使用 GPU 跑。

记得最后关闭 sess。

结果可视化

经过上面漫长的训练,我们的模型终于训练好了,接下来我们就通过可视化来看一看模型的效果如何。

利用卷积自编码器对图片进行降噪

可以看到通过卷积自编码器,我们的降噪效果还是非常好的,最终生成的图片看起来非常顺滑,噪声也几乎看不到了。

有些小伙伴可能就会想,我们也可以用基础版的 input-hidden-output 结构的 AutoEncoder 来实现降噪。因此我也实现了一版用最简单的 input-hidden-output 结构进行降噪训练的模型(代码在我的 GitHub)。我们来看看它的结果:

利用卷积自编码器对图片进行降噪

可以看出,跟卷积自编码器相比,它的降噪效果更差一些,在重塑的图像中还可以看到一些噪声的影子。

结尾

至此,我们完成了基础版本的 AutoEncoder 模型,还在此基础上加入卷积层来进行图片降噪。相信小伙伴对 AntoEncoder 也有了一个初步的认识。

完整的代码已经放在我的 GitHub(NELSONZHAO/zhihu) 上,其中包含了六个文件:

  • BasicAE,基础版本的 AutoEncoder(包含 jupyter notebook 和 html 两个文件)

  • EasyDAE,基础版本的降噪 AutoEncoder(包含 jupyter notebook 和 html 两个文件)

  • ConvDAE,卷积降噪 AutoEncoder(包含 jupyter notebook 和 html 两个文件)

如果觉得不错,可以给我的 GitHub 点个 star 就更好啦!

 
反对 0举报 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理(2)
    【深度学习系列】卷积神经网络CNN原理详解(一)
    本文为【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理(2)从上文的计算中我们可以看到,同一层的神经元可以共享卷积核,那么对于高位数据的处理将会变得非常简单。并且使用卷积核后图片的尺寸变小,方便后续计算,并且我们不需要手动去选取特征,
    03-08
  • 技术向:一文读懂卷积神经网络 - 艾斯1213
    技术向:一文读懂卷积神经网络自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。正文之前,先
    03-08
  • 卷积神经网络CNN理解 卷积神经网络 简书
    自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。正文之前,先说几点自己对于CNN的感触。先明
    03-08
  • 理解图像的卷积
    转自:https://www.zhihu.com/question/22298352从数学上讲,卷积就是一种运算。某种运算,能被定义出来,至少有以下特征:首先是抽象的、符号化的其次,在生活、科研中,有着广泛的作用比如加法: ,是抽象的,本身只是一个数学符号在现实中,有非常多的意
    03-08
  • 什么是卷积 什么是卷积网络
    什么是卷积 什么是卷积网络
    目录Feature mapsWhy not Linear335k or 1.3MBem...Receptive FieldFully connnectedPartial connectedLocally connectedRethink Linear layerFully VS LovallyWeight sharingWhy call Convolution?2D ConvolutionConvolution in Computer VisionCNN on feat
    03-08
  • Tensorflow--一维离散卷积 tensorflow一维卷积神经网络
    Tensorflow--一维离散卷积 tensorflow一维卷积
    一维离散卷积的运算是一种主要基于向量的计算方式一.一维离散卷积的计算原理一维离散卷积通常有三种卷积类型:full卷积,same卷积和valid卷积1.full卷积full卷积的计算过程如下:K沿着I顺序移动,每移动一个固定位置,对应位置的值相乘,然后对其求和其中K称
    03-08
  • TensorFlow系列专题(十四): 手把手带你搭建卷积神经网络实现冰山图像分类
    TensorFlow系列专题(十四): 手把手带你搭建卷积
    目录:冰山图片识别背景数据介绍数据预处理模型搭建结果分析总结 一、冰山图片识别背景这里我们要解决的任务是来自于Kaggle上的一道赛题(https://www.kaggle.com/c/statoil-iceberg-classifier-challenge),简单介绍一下赛题的背景:在加拿大的东海岸经常
    03-08
  • 卷积神经网络的“卷积”操作不等于数学上定义的卷积操作
    卷积神经网络的“卷积”操作不等于数学上定义的
    在介绍卷积神经网络CNN的时候,大部分教材在介绍“卷积操作”的时候都与下面这张图类似的说明这点让人很困惑,因为在数学上,卷积运算是这么定义的\((f * g )(t) = \int_{0}^{t} f(\tau) g(t - \tau)\, d\tau\)很明显,在与\(f(\tau)\)相乘的是\(g(t-\tau)\)
    03-08
  • 卷积神经网络——池化层学习——最大池化
    卷积神经网络——池化层学习——最大池化
    池化层(Pooling layers)除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性,我们来看一下。先举一个池化层的例子,然后我们再讨论池化层的必要性。假如输入是一个4×4矩阵,用到的池化类型是最大池化(max
    03-08
  • opecv 卷积原理、边缘填充方式、卷积操作详解
    opecv 卷积原理、边缘填充方式、卷积操作详解
    什么是二维卷积呢?看下面一张图就一目了然:卷积就是循环对图像跟一个核逐个元素相乘再求和得到另外一副图像的操作,比如结果图中第一个元素5是怎么算的呢?原图中3×3的区域与3×3的核逐个元素相乘再相加:5=1×1+2×0+1×0+0×0+1×0+1×0+3×0+0×0+2×2
    03-08
点击排行