利用自编码(Autoencoder)来提取输入数据的特征

自编码(Autoencoder)介绍

Autoencoder是一种无监督的学习算法,将输入信息进行压缩,提取出数据中最具代表性的信息。其目的是在保证重要特征不丢失的情况下,降低输入信息的维度,减小神经网络的处理负担。简单来说就是提取输入信息的特征。类似于主成分分析(Principal Components Analysis,PAC)

对于输入信息X,通过神经网络对其进行压缩,提取出数据的重要特征,然后将其解压得到数据Y,然后通过对比X与Y求出预测误差进行反向传递,逐步提升自编码的准确性。训练完成的自编码中间部分就是输入数据的精髓,实际使用中通常只会用到自编码的前半部分。

Tensorflow实现

用到的数据集

用到的数据集是Tensorflow模块中的mnist数据集,其中有70000个数字0-9的带标签图片样本,包含了60000个训练样本和10000个测试样本。

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=False) #读取文件

"/tmp/data/"为文件保存的位置,如果没有则会自动下载到该文件夹。"one_hot=False"表示返回一个长度为n的numpy数组.每个元素代表图片上的数字.

参数定义

# Parameter
learning_rate = 0.01 #学习率0.01
training_epochs = 5 # 五组训练
batch_size = 256 #批尺寸大小
display_step = 1 #每隔多少epoch显示打印一次cost
examples_to_show = 10 #显示多少张图片

网络输入inputs

n_input = 784  # mnist中图片的尺寸是28*28总共有784个像素特征
# tf Graph input (only pictures)
X = tf.placeholder("float", [None, n_input]) #定义网络的输入特征

隐藏层的权重weights和偏置biases定义

  • 将输入进的784个Features,经过第一个隐藏层压缩到256个Features,然后经过第二个隐藏层压缩至128个。
  • 在解压环节将128个Features还原至256,再到784.
  • 将前后的784个特征进行对比,反向传递cost来提升自编码的准确度
# hidden layer settings
n_hidden_1 = 256 # 第一层隐藏层的特征数量
n_hidden_2 = 128 # 第二层的数量
weights = {
	'encoder_h1':tf.Variable(tf.random_normal([n_input,n_hidden_1])),      #[784,256]
	'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1,n_hidden_2])),  #[256,128]
	'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2,n_hidden_1])),  #[128,256]
	'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])),    #[256,784]
	}
biases = {
	'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),             #[256]
	'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),             #[128]
	'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),             #[256]
	'decoder_b2': tf.Variable(tf.random_normal([n_input])),                #[784]
	}

定义压缩Encoder和解压Decoder层

使用的激活函数是sigmoid,压缩之后的值应该在[0,1],在decoder中激活函数一样

# Building the encoder
def encoder(x):
    # Encoder Hidden layer with sigmoid activation #1
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
                                   biases['encoder_b1']))
    # Decoder Hidden layer with sigmoid activation #2
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
                                   biases['encoder_b2']))
    return layer_2
    
# Building the decoder
def decoder(x):
    # Encoder Hidden layer with sigmoid activation #1
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
                                   biases['decoder_b1']))
    # Decoder Hidden layer with sigmoid activation #2
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
                                   biases['decoder_b2']))
    return layer_2

Encoder和Decoder的输出结果

encoder_op = encoder(X) 	        # 128 Features
decoder_op = decoder(encoder_op)	# 784 Features

# Prediction
y_pred = decoder_op	# 预测值
y_true = X		# 真实值(原始输入)

定义cost和训练

cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) #cost为(y_true - y_pred)^2的均值
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) #利用AdamOptimizer来训练

最后通过Matplotlib的pyplot来显示结果

with tf.Session() as sess:
    init=tf.global_variables_initializer()
    sess.run(init)
    total_batch=int(mnist.train.num_examples/batch_size) #计算训练循环的次数

    #train cycle
    for epoch in range(training_epochs):
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
        if epoch % display_step == 0: #输入经过每一个epoch后cost的值
            print("Epoch:", '%04d' % (epoch + 1), #输出格式为Epoch:0001 cost=0.123456789
                  "cost=", "{:.9f}".format(c))
    print("Optimization Finished!")
    #在测试集上应用encoder和decoder
    encode_decode = sess.run(
        y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})
    # 显示对比图像
    f, a = plt.subplots(2, 10, figsize=(10, 2)) #定义画布
    for i in range(examples_to_show):
        a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
        a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
    plt.show()

结果

Epoch: 0001 cost= 0.077869482
Epoch: 0002 cost= 0.070396304
Epoch: 0003 cost= 0.066303633
Epoch: 0004 cost= 0.062276978
Epoch: 0005 cost= 0.055230502

参考

本文内容来自于莫烦python,进行学习整理,非常感谢。
相关代码

posted @ 2020-01-06 18:17  吃瓜的哲学  阅读(8785)  评论(0编辑  收藏  举报