自编码器AutoEncoder

 

自编码器AutoEncoder

我们先构架一个神经网络模型,这个模型是收集一张图片,接受这个图片后,神经网络给这个图片压缩,最后再从压缩的图片中还原,是不是感觉有点抽象,其实我也觉得这样的解释不太恰当,那就让我们更加的具体一点来深入了解下这个自编码。

《自编码器AutoEncoder》

现在假设我们刚才构建的模型是这个样子,我们可以从图片中看出来,我们刚才上传给自编码模型的图片实质上是经过压缩以后再进行解压的一个过程。当压缩的时候,原有的图片的质量被缩减(降维),解压的时候,用信息量小却包含了所有信息的文件来恢复出原来的图片(还原)。那么,为什么要这么做呢?当神经网络要输入大量的信息,比如高清图片的时候,输入的图像数量可以达到上千万,要神经网络直接从输入的数据量中进行学习,是一件非常费力不讨好的工作,因此我们就想,为什么不压缩一下呢?提取出原图片中最具有代表性的信息,缩减输入中的信息量,然后在把缩减过后的信息放入到神经网络中学习,这样学习起来就变得轻松了,所以自编码就是能在这个时候发挥作用,现在我们假设从上图中的输入层中的信息A解压缩到隐含层中得到a,然后用隐含层的a和输入层的A进行对比,得到预测误差,再进行反向传递,然后逐步的提高自编码的准确率,训练一段时间后在中间隐含层获得的一个部分的数据a就是源数据的精髓,可以从上面那个模型看出,从头到尾,我们只用到了这个输入的信息A,并没有用到数据A所对应的数据标签,所以我们这时候可以得出结论,自编码是一种非监督学习,通常我们在使用自编码的时候通常只会使用自编码的前半部分,这个部分也叫作EnCode,编码器,编码器可以得到源数据的精髓。

然后我们只需要在创建一个小的神经网络模型再去学习这个精髓中的数据,不仅可以减少神经网络的负担,并且同样可以达到一个很好的效果。

同样的如果我们通过自编码整理数据,他能从各种数据中筛选总结出各种数据的特征,如果把这个图片的类型特征都整理好放到一个图片上,那么数据类型都可以很好的用源数据的类型区分出来,如果你了解PCA主成分分析,自编码的功能和他类似,甚至在某些部分超出了PCA,换句话说,自编码可以和PCA一样可以给特殊属性降维。

下面是用mnist数据集进行压缩然后再还原到原图的一个网络

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
#获取数据
mnist = input_data.read_data_sets('/tmp/data/', one_hot=False)
#定义超参数
learning_rate   = 0.01  #学习率
training_ephches= 20    #训练次数
batch_size      = 256   #每批送入数据数目
display_step    = 1     #训练多少次打印一次
example_to_show = 15    #展示多少张图片
total_batch = mnist.train.images.shape[0]//batch_size   #每一轮训练要多少次,计算公式为 数据量/batch_size
n_input = 784           #输入数据的维度28*28
n_hidden_1 = 256        #第一层维度256
n_hidden_2 = 32        #第二层维度128
X = tf.placeholder(dtype=tf.float32, shape=[None, n_input])
#下面是我以字典的形式定义了权重和偏置,然后引用的时候直接输入字典的键,就会有相应的value
weights = {
    'encoder_h1': tf.Variable(tf.random_normal([n_input   , n_hidden_1])),
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),

    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
    'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])),
}

biases = {
    'encoder_h1': tf.Variable(tf.random_normal([n_hidden_1])),
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_2])),

    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_1])),
    'decoder_h2': tf.Variable(tf.random_normal([n_input])),
}
#定义编码器
def encoder(x):
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_h1']))
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']), biases['encoder_h2']))
    return layer_2
#定义解码器
def decoder(x):
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_h1']))
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_h2']))
    return layer_2

encoder_op = encoder(X)
decoder_op = decoder(encoder_op)

y_pre  = decoder_op
y_true = X

cost = tf.reduce_mean(tf.square(y_pre - y_true))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
#展示图片的函数
def show_image(batches=0):
    #encode_decode = sess.run(y_pre, feed_dict={X: mnist.test.images[batches:(batches+1)*example_to_show]})
    encode_decode = sess.run(y_pre, feed_dict={X: mnist.test.images[:example_to_show]})

    f, a = plt.subplots(2, example_to_show, figsize=(15, 3))
    for i in range(example_to_show):
        #a[0][i].imshow(np.reshape(mnist.test.images[batches + i], (28, 28)))
        a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
        a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
    plt.pause(1)
    plt.close()

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    show_image()
    for epoch in range(training_ephches):
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.images[batch_size * i: batch_size * (i+1)],\
                                 mnist.train.labels[batch_size * i: batch_size * (i+1)]
            sess.run(optimizer, feed_dict={X: batch_xs})
            if epoch % display_step == 0:
                print('Epoch:{:2} ,cost={:.4f}'.format(epoch+1,
                                                sess.run(cost, feed_dict={X: batch_xs})))
        show_image(epoch)
    print("Optimization Finished!")

 

 

 

点赞