资讯专栏INFORMATION COLUMN

利用 TensorFlow 实现卷积自编码器

Steven / 3125人阅读

摘要:自编码器的一个非常受欢迎的使用场景是图像处理。这个自编码器就称之为卷积自编码器,使用卷积自编码器卷积自编码器可以用于图像的重构工作。网络架构卷积自编码器的编码部分将是一个典型的卷积过程。

作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
简书地址:https://www.jianshu.com/p/250...


介绍和概念

自动编码器(Auto-encoders)是神经网络的一种形式,它的输入数据与输出数据是相同的。他们通过将输入数据压缩到一个潜在表示空间里面,然后再根据这个表示空间将数据进行重构得到最后的输出数据。

自编码器的一个非常受欢迎的使用场景是图像处理。其中使用到的小技巧是用卷积层来替换全连接层。这个转变方法是将一个非常宽的,非常瘦的(比如 100*100 的像素点,3 通道,RGB)图像转换成一个非常窄的,非常厚的图像。这种方法非常有助于帮助我们从图像中提取出视觉特征,从而得到更准确的潜在表示空间。最后我们的图像重构过程采用上采样和卷积。

这个自编码器就称之为卷积自编码器(Convolutional Autoencoder,CAE)

使用卷积自编码器

卷积自编码器可以用于图像的重构工作。例如,他们可以学习从图片中去除噪声,或者重构图片缺失的部分。

为了实现上述提到的效果,我们一般不使用相同的输入数据和输出数据,取而代之的是,使用含有噪声的图片作为输入数据,然后输出数据是一个干净的图片。卷积自编码器就会通过学习,去去除图片中的噪声,或者去填补图片中的空缺部分。

接下来,让我们来看一下 CAE 是如何来填充图中眼睛上的十字架。我们假设图片的眼睛上面存在一个十字架黑影,我们需要删除这个十字架噪声。首先,我们需要来手动创建这个数据库,当然,这个动作非常方便。

现在我们的卷积自编码器就可以开始训练了,我们可以用它去除我们从未见过的眼睛照片上面的十字线!

利用 TensorFlow 来实现这个卷积自编码器

看我们利用 MNIST 数据集来看看这个网络是如何实现的,完整的代码可以在 Github 上面下载。

网络架构

卷积自编码器的编码部分将是一个典型的卷积过程。每一个卷积层之后都会加上一个池化层,主要是为了减少数据的维度。解码器需要从一个非常窄的数据空间中重构出一个宽的图像。

一般情况下,你会看到我们后面是采用反卷积层来增加我们图像的宽度和高度。它们的工作原理和卷积层的工作原理几乎完全一样,但是作用方向相反。比如,你有一个 33 的卷积核,那么在编码器中我们是将该区域的图像编码成一个元素点,但是在解码器中,也就是反卷积中,我们是把一个元素点解码成 33 个元素点。TensorFlow API 为我们提供了这个功能,参考 tf.nn.conv2d_transpose

自动编码器只需要在噪声的图像上进行训练,就可以非常成功的进行图片去燥。比如,我们可以在训练图片中添加入高斯噪声来创建包含噪声的图像,然后将这些像素值裁剪在 0 到 1 之间。我们将噪声图像作为输入数据,最原始的感觉图像作为输出数据,也就是我们的目标值。

模型定义
learning_rate = 0.001
inputs_ = tf.placeholder(tf.float32, (None, 28, 28, 1), name="inputs")
targets_ = tf.placeholder(tf.float32, (None, 28, 28, 1), name="targets")
### Encoder
conv1 = tf.layers.conv2d(inputs=inputs_, filters=32, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 28x28x32
maxpool1 = tf.layers.max_pooling2d(conv1, pool_size=(2,2), strides=(2,2), padding="same")
# Now 14x14x32
conv2 = tf.layers.conv2d(inputs=maxpool1, filters=32, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 14x14x32
maxpool2 = tf.layers.max_pooling2d(conv2, pool_size=(2,2), strides=(2,2), padding="same")
# Now 7x7x32
conv3 = tf.layers.conv2d(inputs=maxpool2, filters=16, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 7x7x16
encoded = tf.layers.max_pooling2d(conv3, pool_size=(2,2), strides=(2,2), padding="same")
# Now 4x4x16
### Decoder
upsample1 = tf.image.resize_images(encoded, size=(7,7), method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
# Now 7x7x16
conv4 = tf.layers.conv2d(inputs=upsample1, filters=16, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 7x7x16
upsample2 = tf.image.resize_images(conv4, size=(14,14), method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
# Now 14x14x16
conv5 = tf.layers.conv2d(inputs=upsample2, filters=32, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 14x14x32
upsample3 = tf.image.resize_images(conv5, size=(28,28), method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
# Now 28x28x32
conv6 = tf.layers.conv2d(inputs=upsample3, filters=32, kernel_size=(3,3), padding="same", activation=tf.nn.relu)
# Now 28x28x32
logits = tf.layers.conv2d(inputs=conv6, filters=1, kernel_size=(3,3), padding="same", activation=None)
#Now 28x28x1
# Pass logits through sigmoid to get reconstructed image
decoded = tf.nn.sigmoid(logits)
# Pass logits through sigmoid and calculate the cross-entropy loss
loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=targets_, logits=logits)
# Get cost and define the optimizer
cost = tf.reduce_mean(loss)
opt = tf.train.AdamOptimizer(learning_rate).minimize(cost)

训练过程:

sess = tf.Session()
epochs = 100
batch_size = 200
# Set"s how much noise we"re adding to the MNIST images
noise_factor = 0.5
sess.run(tf.global_variables_initializer())
for e in range(epochs):
    for ii in range(mnist.train.num_examples//batch_size):
        batch = mnist.train.next_batch(batch_size)
        # Get images from the batch
        imgs = batch[0].reshape((-1, 28, 28, 1))
        
        # Add random noise to the input images
        noisy_imgs = imgs + noise_factor * np.random.randn(*imgs.shape)
        # Clip the images to be between 0 and 1
        noisy_imgs = np.clip(noisy_imgs, 0., 1.)
        
        # Noisy images as inputs, original images as targets
        batch_cost, _ = sess.run([cost, opt], feed_dict={inputs_: noisy_imgs,
                                                         targets_: imgs})
print("Epoch: {}/{}...".format(e+1, epochs),
              "Training loss: {:.4f}".format(batch_cost))

作者:chen_h
微信号 & QQ:862251340
简书地址:https://www.jianshu.com/p/250...

CoderPai 是一个专注于算法实战的平台,从基础的算法到人工智能算法都有设计。如果你对算法实战感兴趣,请快快关注我们吧。加入AI实战微信群,AI实战QQ群,ACM算法微信群,ACM算法QQ群。长按或者扫描如下二维码,关注 “CoderPai” 微信号(coderpai)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41200.html

相关文章

  • tensorflow学习笔记3——MNIST应用篇

    摘要:的卷积神经网络应用卷积神经网络的概念卷积神经网络是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。 MNIST的卷积神经网络应用 卷积神经网络的概念 卷积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。[2] 它...

    baishancloud 评论0 收藏0
  • 卷积编码

    摘要:卷积满足交换操作,因此在一般的维空间输入,自编码可以被用来训练解码编码。事实上,解码卷积的超参数是由编码框架确定的由于卷积跨越每个特征图,并且产生具有的维度,因此经过滤波器之后产生相同的空间范围。 作者:chen_h微信号 & QQ:862251340微信公众号:coderpai简书地址:https://www.jianshu.com/p/ec4... 这篇教程是翻译Paolo Ga...

    shiyang6017 评论0 收藏0
  • 初学者怎么选择神经网络环境?对比MATLAB、Torch和TensorFlow

    摘要:本报告面向的读者是想要进入机器学习领域的学生和正在寻找新框架的专家。其输入需要重塑为包含个元素的一维向量以满足神经网络。卷积神经网络目前代表着用于图像分类任务的较先进算法,并构成了深度学习中的主要架构。 初学者在学习神经网络的时候往往会有不知道从何处入手的困难,甚至可能不知道选择什么工具入手才合适。近日,来自意大利的四位研究者发布了一篇题为《神经网络初学者:在 MATLAB、Torch 和 ...

    yunhao 评论0 收藏0

发表评论

0条评论

Steven

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<