自动编码器重建图像及Python实现

自动编码器重建图像及Python实现自动编码器简介自动编码器(一下简称AE)属于生成模型的一种,目前主流的生成模型有AE及其变种和生成对抗网络(GANs)及其变种。随着深度学习的出现,AE可以通过网络层堆叠形成深度自动编码器来实现数据降维。通过编码过程减少隐藏层中的单元数量,可以以分层的方式实现降维,在更深的隐藏层中获得更高级的特征,从而在解码过程中更好的重建数据。自动编码器原理自动编码器是通过无监督学习训练的神经网络,实际上…

大家好,又见面了,我是你们的朋友全栈君。

自动编码器简介

自动编码器(一下简称AE)属于生成模型的一种,目前主流的生成模型有AE及其变种和生成对抗网络(GANs)及其变种。随着深度学习的出现,AE可以通过网络层堆叠形成深度自动编码器来实现数据降维。通过编码过程减少隐藏层中的单元数量,可以以分层的方式实现降维,在更深的隐藏层中获得更高级的特征,从而在解码过程中更好的重建数据。

自动编码器原理

自动编码器是通过无监督学习训练的神经网络,实际上是一个将数据的高维特征进行压缩降维编码,再经过相反的解码过程还原原始数据的一种学习方法。学习过程中通过解码得到的最终结果与原数据进行比较,通过修正权重偏置参数降低损失函数,不断提高对原数据的复原能力。自动编码器学习的前半段的编码过程得到的结果即可代表原数据的低维“特征值”。通过学习得到的自编码器模型可以实现将高维数据压缩至所期望的维度,原理与PCA相似。自编码器的学习过程如图1所示:
图1图1
自动编码器架构主要由两部分组成:
编码过程:
自动编码器将输入数据 x 进行编码,得到新的特征 x’ ,这称为编码过程,可表述为:在这里插入图片描述
其编码过程就是在 (Wx+b) 的线性组合外加上非线性的激活函数 f(x) 。
解码过程:
利用特征 x’ 重构出与原始输入数据最接近的重构数据 x^ ,这称为解码过程,可表述为:
在这里插入图片描述
原始输入 x 和重构原始输入 x^ 之间构成重构误差,自动编码器学习最小化该重建误差,即:
在这里插入图片描述
一般会给自编码器增加 WT = W 的限制

AE算法伪代码

AE算法伪代码如下图2所示:
图2

深度自编码(DAE)

利用自编码器的隐藏层作为下一个自动编码器的输入可以实现堆叠自动编码器而形成深度自动编码器(DeepAuto Encoder,DAE)。为避免隐藏层繁琐的查找表表示,深度自动编码器减少了隐藏层单元数,进而更容易提取到更好的特征。简而言之,DAE相较于AutoEncoder原理相同,只是网络层数更深。DAE学习过程如图3所示:
图3

AE算法重建图像的Python实现

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import scipy
from scipy import ndimage
import math

# 下载数据集
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

path = '/home/yuelingyi/PyCharmProjects/Practive/AE/test_images'

bath_size = 1

# 定义卷积函数
def conv2d(input_, shape, k_step, name):
    # input_ = [batch_size, in_height, in_width, in_channels]   format NHWC
    # shape = [filter_height, filter_width, in_channels, out_channels]
    with tf.variable_scope(name):
        w = tf.get_variable('w', shape, initializer=tf.truncated_normal_initializer(stddev=0.02))
        b = tf.get_variable('b', [shape[-1]], initializer=tf.constant_initializer(value=0.0))
        conv = tf.nn.bias_add(conv, b)
        return conv

# 定义解卷积函数
def deconv2d(input_, output_shape, k_step, name):
    # input_ = input_ = [batch_size, in_height, in_width, in_channels]  
    # output_shaoe = [batch_size, output_height, output_width, output_channels]
    w = tf.get_variable('w', [k_step, k_step, output_shape[-1], input_.shape()[-1], initialier = tf.truncated_normal_initializer(stddev=0.02)])
    b = tf.get_variable('b', [output_shape[-1]], initializer=tf.constant_initializer(value=0.0) )
    deconv = tf.nn.bias_add(deconv, b)
    rerurn deconv

# 定义激活函数leakyrelu
def leakyrelu(x, leaky=0.2):
    return max(x, x*leaky)

#def leakyrelu(x, leaky=0.2):
    #k1 = (1 + leaky) * 0.5
    #k2 = (1 - leaky) * 0.5
    # return k1 * x + k2 * tf.abs(x)

# 定义全连接层函数
def fully_connected(input_, shape, name):
    w = tf.get_valiable('w', shape, initializer= tf.truncated_normal_initializer(stddev=0.02))
    b = tf.get_valiable('b', shape[-1], initializer=tf.constant_initializer(value=0.0))
    fc = tf.matmul(input_, w) + b
    return fc

#定义转换函数
def rescale_image(image):
    convert_image = (image / 1.5 + 0.5) * 255
    return convert_image

# 定义保存图像函数
def save_image(input_, size, image_path, color, iter):
    h, w = input_.shape[1], input_shape[2]
    convert_input = input_.reshape(batch_size, h, w)
    if color is True:
        image = np.zeros((h*size, w*size, 3))
    else:
        image = np.zeros((h*size, w*size))
    for index, img in enumerate(convert_input):
        i = index % size
        j = math.floor(img / size)
        if color is True:
            image[h*j:h*j+h, i*w:i*w+w,:] = img
        else:
            image[h*j:h*j+h, i*w:i*w+w] = img
        scipy.misc.toimage(rescale_image(image), cmin=0, cmax=0).save(image_path + 'tr_gt_%s.png' % (iter))

# 搭建AE框架,这里使用4层编码4层解码,卷积核大小(3, 3), 步长2
def AutoEncoder(inputs):
    with tf.variable_scope("AutoEncoder", reuse=tf.AUTO_REUSE) as scope0:
        conv1 = leakyrelu(conv2d(input_, [3, 3, 1, 16], 2, 'conv1'))
        conv2 = leakyrelu(conv2d(conv1, [3, 3, 16, 32], 2, 'conv2'))
        conv3 = leakyrelu(conv2d(conv2, [3, 3, 32, 64], 2, 'conv3'))
        conv4 = leakyrelu(conv2d(conv3, [3, 3, 64, 128], 2, 'conv4'))
        deconv1 = leakyrelu(deconv2d(conv4, [batch_size, 4, 4, 64], 'deconv1'))
        deconv2 = leakyrelu(deconv2d(deconv1, [batch_size, 7, 7, 32], 2, 'deconv2'))
        deconv3 = leakyrelu(deconv2d(deconv2, [batch_size, 14, 14, 16], 2, 'deconv3'))
        deconv4 = leakyrelu(deconv2d(deconv3, [batch_size, 28, 28, 1], 2, 'deconv4'))
        output = tf.tanh(deconv4)
        return output

with tf.name_scope('input'):
    input_image = tf.placeholder(tf.float32, [None, 28, 28, 1], "input_image")
    
with tf.name_scope("Network"):
    generate_image = AutoEncoder(input_image)
    
tf.summary.image("output_image", generate_image, 100)

with tf.name_scope("loss"):
    Auto_loss = tf.reduce_mean(tf.reduce_sum(tf.pow(tf.suntract(generate_iamge, input_image), 2), 3))

tf.summary.scalar("loss", Auto_loss)

train_var = tf.trainable_variables()

with tf.name_scope("train"):
    train_loss = tf.train.AdmaOptimizer(0.001, beta1 = 0.9).minimize(Auto_loss)

init = tf.initialize_all_variables()

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.5)

with tf.Session(config=tf.ConfigProto(gpu_options=gup_options)) as sess:
    sess.run(init)
    merged_summary = tf.summary.merge_all()
    writer = tf.summary.FileWriter(''/home/yuelingyi/PyCharmProjects/Practive/AE/logs'', sess.graph)
    for i in range(3000):
        mnist_image = tf.train.next_batch(batch_size)
        batch_image = mnist_image[0].reshape(batch_size, 28, 28, 1)
        sess.run(train_loss, feed_dict={input_image: batch_image})
        print(sess.run(Auto_loss, feed_dict={input_image: batch_image}))
        summary = sess.run(merged_summary, feed_dict={input_iamge: batch_image})
        writer.add_summary(summary, i)
        
        if i % 50 == 0:
            output_image = sess.run(genereat_image, feed_dict={input_iamge: batch_image})
            result =  sess.run(merged_summary, feed_dict={input_image: batch_image})
            writer.add_summary(summary, i)
            save_image(output_image, 1, path, False, i)
           

程序运行结果

用3000张MNIST数据集中的手写数字训练,每50张可视化一张生成图像,得到的生成图像结果如图4所示:
图4
由生成的图像可见,训练开始时,AE还不能够重建出输入图像,随着训练迭代次数的加深,重建的图像与真实输入越来越接近,从输出的loss值中也可以看出重建误差在逐渐减小。

思考

自动编码器实际上不算是真正的学习如何去重建原始图像,它不向GAN那样去学习原始数据的分布,而只是通过逐像素的比较原始图像和重建图像的误差,逐步优化重建结果。当出现如下两种情况时,单纯的通过自动编码器的重建误差不能区分图像重建结果的好坏与否:

在这里插入图片描述

在这里插入图片描述

假设以上两幅图像中数字7的大小相同(即涂黑的像素一样多),上面的图像中,原图和生成图像所在位置相同,但是生成图像的右上方多生成了两个像素,即原图和生成图像的重建误差为2个像素,可见重建误差很小,但是显然生成图像不是我们想要的结果;下图中,原图像中数字7和生成图像的数字7涂黑的像素个数相同,唯一不同的是两个数字7所处的位置,此时计算的重建误差比较大,但是生成图像确实是我们想要的结果。所以自动编码器在重建图像这一方面受到了一些人的质疑。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/145108.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • opencv识别多条形码数字_opencv测试代码

    opencv识别多条形码数字_opencv测试代码这其实是一个小工程完成的功能: 使用摄像头采集图像进行预处理(检测部分) 提取出预处理的条形码图像(识别部分) 将条形码进行存入数据库(存储部分) 首先接到这个图像识别的小工程需要先确定这个工程的最初输入,和最后输出,输入就是普通的RGB图像,输出是数据库文件。其中需要完成的过程,就是我需要做得功能,检测部分、识别部分和存储部分,话不多说,上部分代码:/…

    2022年10月29日
  • vue富文本编辑器插件推荐_elementui富文本编辑器

    vue富文本编辑器插件推荐_elementui富文本编辑器富文本编辑器官网http://tinymce.ax-z.cn安装npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S下载语言包语言包下载完之后在项目里新建public文件夹1)在public目录下新建tinymce文件夹,并将下载的语言包解压到该目录下2)在node_modules里面找到tinymce,将skins目录复制到public/tinymce里面<template><divclass

    2022年10月15日
  • linux替换大文件内容,Linux批量替换文件内容

    linux替换大文件内容,Linux批量替换文件内容今天测试人员一不小心把导航的地址改错了,大约6000多个导航文件,要通过后台配置的话也很麻烦,可以通过linux命令实现对批量文件进行内容替换,但是技术经理不在,我对linux命令不熟,没办法只好硬着头皮来。经在网上一番辛苦搜索,找到以下几个命令,并尝试执行……最终终于实现效果,哎,“书到用时方恨少”,特此针对今天的情况总结了一下Linux批量替换文件内容的命令,第一种:格式:sed-i”s/…

    2022年7月26日
  • 通达OA 工作流执行出现的异常现象处理(图文)

    通达OA 工作流执行出现的异常现象处理(图文)一个朋友用的工作流,突然说这里面多了很多人不应该看到这个流程的,就是在查询工作时,最上面多了一个“查阅信息”项,然后最下面多了很多人查询的记录。这个项目是从哪里来的呢?普通的流程倒也无所谓了,而有些流程如发文、任职等还是需要保密的,这样让大家查阅肯定是不行的。一开始以为是使用了工作流的转存文件柜的功能,实验了一下,这样转存后并不会在流程里关联查看到查阅信息。又实验了一下转发布公告,同样不是。最后咨

    2022年6月23日
  • ALLURE架构整理

    ALLURE架构整理ALLURE1.开始安装1.1.安装命令行1.1.1.Linux1.1.2.MacOSX1.1.3.Windows1.1.4.手动安装2.报告结构2.1.总览页面2.2.类别2.3.测试套2.4.图表2.5.时间刻度2.6.功能2.7.包2.8测试用例页面3.Pytest与Allure3.1.安装3.2.用法示例:3.3.基本报告3.4.支持的Pytest功能XfailskipifFixtures和finalizersParametrization3.5AllureFeatu

    2022年7月26日
  • Windows编程(操作注册表)

    Windows编程(操作注册表)注册表存储在二进制文件里面,win32API提供了大量的函数操作注册表RegCreateKey创建指定的注册表项RegCreateKeyW(_In_

    2021年12月13日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号