• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

技术+案例无监督学习Autoencoder

武飞扬头像
华为云开发者联盟
帮助1

摘要:本篇文章将分享无监督学习Autoencoder的原理知识,然后用MNIST手写数字案例进行对比实验及聚类分析。

一.什么是Autoencoder

首先,什么是自编码(Autoencoder)?自编码是一种神经网络的形式,注意它是无监督学习算法。例如现在有一张图片,需要给它打码,然后又还原图片的过程,如下图所示:

学新通

一张图片经过压缩再解压的工序,当压缩时原有的图片质量被缩减,当解压时用信息量小却包含所有关键性文件恢复出原来的图片。为什么要这么做呢?有时神经网络需要输入大量的信息,比如分析高清图片时,输入量会上千万,神经网络从上千万中学习是非常难的一个工作,此时需要进行压缩,提取原图片中具有代表性的信息或特征,压缩输入的信息量,再把压缩的信息放入神经网络中学习。这样学习就变得轻松了,所以自编码就在这个时候发挥作用。

学新通

如下图所示,将原数据白色的X压缩解压成黑色的X,然后通过对比两个X,求出误差,再进行反向的传递,逐步提升自编码的准确性。

学新通

训练好的自编码,中间那部分就是原数据的精髓,从头到尾我们只用到了输入变量X,并没有用到输入变量对应的标签,所以自编码是一种无监督学习算法。

学新通

但是真正使用自编码时,通常只用到它的前半部分,叫做编码器,能得到原数据的精髓。然后只需要创建小的神经网络进行训练,不仅减小了神经网络的负担,而且同样能达到很好的效果。

下图是自编码整理出来的数据,它能总结出每类数据的特征,如果把这些数据放在一张二维图片上,每一种数据都能很好的用其精髓把原数据区分开来。自编码能类似于PCA(主成分分析)一样提取数据特征,也能用来降维,其降维效果甚至超越了PCA。

学新通

二.Autoencoder分析MNIST数据

Autoencoder算法属于非监督学习,它是把数据特征压缩,再把压缩后的特征解压的过程,跟PCA降维压缩类似。

  • 第一部分:使用MNIST数据集,通过feature的压缩和解压,对比解压后的图片和压缩之前的图片,看看是否一致,实验想要的效果是和图片压缩之前的差不多。
  • 第二部分:输出encoder的结果,压缩至两个元素并可视化显示。在显示图片中,相同颜色表示同一类型图片,比如类型为1(数字1),类型为2(数字2)等等,最终实现无监督的聚类。

有监督学习和无监督学习的区别

(1) 有监督学习方法必须要有训练集与测试样本。在训练集中找规律,而对测试样本使用这种规律。而非监督学习没有训练集,只有一组数据,在该组数据集内寻找规律。
(2) 有监督学习的方法就是识别事物,识别的结果表现在给待识别数据加上了标签。因此训练样本集必须由带标签的样本组成。而非监督学习方法只有要分析的数据集的本身,预先没有什么标签。 如果发现数据集呈现某种聚集性,则可按自然的聚集性分类,但不予以某种预先分类标签对上号为目的。

让我们开始编写代码吧!

第一步,打开Anaconda,然后选择已经搭建好的“tensorflow”环境,运行Spyder。

学新通

第二步,导入扩展包。

  1.  
    import numpy as np
  2.  
    import tensorflow as tf
  3.  
    import matplotlib.pyplot as plt
  4.  
    from tensorflow.examples.tutorials.mnist import input_data

第三步,下载数据集。

由于MNIST数据集是TensorFlow的示例数据,所以我们只需要下面一行代码,即可实现数据集的读取工作。如果数据集不存在它会在线下载,如果数据集已经被下载,它会被直接调用。

  1.  
    # 下载手写数字图像数据集
  2.  
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

学新通

第四步,定义参数。

MNIST图片是28*28的像素,其n_input输入特征为784,feature不断压缩,先压缩成256个,再经过一层隐藏层压缩到128个。然后把128个放大,解压256个,再解压缩784个。最后对解压的784个和原始的784个特征进行cost对比,并根据cost提升Autoencoder的准确率。

  1.  
    #-------------------------------------初始化设置-------------------------------------------
  2.  
    # 基础参数设置
  3.  
    learning_rate = 0.01 #学习效率
  4.  
    training_epochs = 5 #5组训练
  5.  
    batch_size = 256 #batch大小
  6.  
    display_step = 1
  7.  
    examples_to_show = 10 #显示10个样本
  8.  
     
  9.  
    # 神经网络输入设置
  10.  
    n_input = 784 #MNIST输入数据集(28*28)
  11.  
     
  12.  
    # 隐藏层设置
  13.  
    n_hidden_1 = 256 #第一层特征数量
  14.  
    n_hidden_2 = 128 #第二层特征数量
  15.  
    weights = {
  16.  
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
  17.  
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
  18.  
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
  19.  
    'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input]))
  20.  
    }
  21.  
    biases = {
  22.  
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  23.  
    'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  24.  
    'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  25.  
    'decoder_b2': tf.Variable(tf.random_normal([n_input]))
  26.  
    }
学新通

第五步,编写核心代码,即定义encoder和decoder函数来实现压缩和解压操作。

学新通

encoder就是两层Layer,分别压缩成256个元素和128个元素。decoder同样包括两层Layer,对应解压成256和784个元素。

  1.  
    #---------------------------------压缩和解压函数定义---------------------------------------
  2.  
    # Building the encoder
  3.  
    def encoder(x):
  4.  
    # 第一层Layer压缩成256个元素 压缩函数为sigmoid(压缩值为0-1范围内)
  5.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
  6.  
    biases['encoder_b1']))
  7.  
    # 第二层Layer压缩成128个元素
  8.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
  9.  
    biases['encoder_b2']))
  10.  
    return layer_2
  11.  
     
  12.  
    # Building the decoder
  13.  
    def decoder(x):
  14.  
    # 解压隐藏层调用sigmoid激活函数
  15.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
  16.  
    biases['decoder_b1']))
  17.  
    # 第二层Layer解压成784个元素
  18.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
  19.  
    biases['decoder_b2']))
  20.  
    return layer_2
  21.  
     
  22.  
    #-----------------------------------压缩和解压操作---------------------------------------
  23.  
    # 压缩:784 => 128
  24.  
    encoder_op = encoder(X)
  25.  
     
  26.  
    # 解压:784 => 128
  27.  
    decoder_op = decoder(encoder_op)
学新通

需要注意,在MNIST数据集中,xs数据的最大值是1,最小值是0,而不是图片的最大值255,因为它已经被这里的sigmoid函数归一化了。

batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x) = 1, min(x) = 0

第六步,定义误差计算方式。

其中,y_pred表示预测的结果,调用decoder_op解压函数,decoder_op又继续调用decoder解压和encoder压缩函数,对图像数据集X进行处理。

  1.  
    #--------------------------------对比预测和真实结果---------------------------------------
  2.  
    # 预测
  3.  
    y_pred = decoder_op
  4.  
    # 输入数据的类标(Labels)
  5.  
    y_true = X
  6.  
    # 定义loss误差计算 最小化平方差
  7.  
    cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
  8.  
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

第七步,定义训练和可视化代码,该部分为神经网络运行的核心代码。

首先进行init初始化操作,然后分5组实验进行训练,batch_x为获取的图片数据集,通过 sess.run([optimizer, cost], feed_dict={X: batch_xs}) 计算真实图像与预测图像的误差。

  1.  
    #-------------------------------------训练及可视化-------------------------------------
  2.  
    # 初始化
  3.  
    init = tf.initialize_all_variables()
  4.  
     
  5.  
    # 训练集可视化操作
  6.  
    with tf.Session() as sess:
  7.  
    sess.run(init)
  8.  
    total_batch = int(mnist.train.num_examples/batch_size)
  9.  
     
  10.  
    # 训练数据 training_epochs为5组实验
  11.  
    for epoch in range(training_epochs):
  12.  
    # Loop over all batches
  13.  
    for i in range(total_batch):
  14.  
    batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0
  15.  
    # 运行初始化和误差计算操作
  16.  
    _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
  17.  
    # 每个epoch显示误差值
  18.  
    if epoch % display_step == 0:
  19.  
    print("Epoch:", 'd' % (epoch 1), "cost=", "{:.9f}".format(c))
  20.  
    print("Optimization Finished!")
学新通

第八步,调用matplotlib库画图,可视化对比原始图像和预测图像。

  1.  
    # 压缩和解压测试集
  2.  
    encode_decode = sess.run(
  3.  
    y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})
  4.  
     
  5.  
    # 比较原始图像和预测图像数据
  6.  
    f, a = plt.subplots(2, 10, figsize=(10, 2))
  7.  
     
  8.  
    # 显示结果 上面10个样本是真实数据 下面10个样本是预测结果
  9.  
    for i in range(examples_to_show):
  10.  
    a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
  11.  
    a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
  12.  
    plt.show()

第九步,运行代码并分析结果。

输出结果如下图所示,误差在不断减小,表示我们的无监督神经网络学习到了知识。

  1.  
    Extracting MNIST_data\train-images-idx3-ubyte.gz
  2.  
    Extracting MNIST_data\train-labels-idx1-ubyte.gz
  3.  
    Extracting MNIST_data\t10k-images-idx3-ubyte.gz
  4.  
    Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
  5.  
     
  6.  
    Epoch: 0001 cost= 0.097888887
  7.  
    Epoch: 0002 cost= 0.087600455
  8.  
    Epoch: 0003 cost= 0.083100438
  9.  
    Epoch: 0004 cost= 0.078879632
  10.  
    Epoch: 0005 cost= 0.069106154
  11.  
    Optimization Finished!

通过5批训练,显示结果如下图所示,上面是真实的原始图像,下面是压缩之后再解压的图像数据。注意,其实5批训练是非常少的,正常情况需要更多的训练。

学新通

完整代码:

  1.  
    # -*- coding: utf-8 -*-
  2.  
    """
  3.  
    Created on Wed Jan 15 15:35:47 2020
  4.  
    @author: xiuzhang Eastmount CSDN
  5.  
    """
  6.  
    import numpy as np
  7.  
    import tensorflow as tf
  8.  
    import matplotlib.pyplot as plt
  9.  
    from tensorflow.examples.tutorials.mnist import input_data
  10.  
     
  11.  
    #-----------------------------------初始化设置---------------------------------------
  12.  
    # 基础参数设置
  13.  
    learning_rate = 0.01 #学习效率
  14.  
    training_epochs = 5 #5组训练
  15.  
    batch_size = 256 #batch大小
  16.  
    display_step = 1
  17.  
    examples_to_show = 10 #显示10个样本
  18.  
     
  19.  
    # 神经网络输入设置
  20.  
    n_input = 784 #MNIST输入数据集(28*28)
  21.  
     
  22.  
    # 输入变量(only pictures)
  23.  
    X = tf.placeholder("float", [None, n_input])
  24.  
     
  25.  
    # 隐藏层设置
  26.  
    n_hidden_1 = 256 #第一层特征数量
  27.  
    n_hidden_2 = 128 #第二层特征数量
  28.  
    weights = {
  29.  
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
  30.  
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
  31.  
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
  32.  
    'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input]))
  33.  
    }
  34.  
    biases = {
  35.  
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  36.  
    'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  37.  
    'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  38.  
    'decoder_b2': tf.Variable(tf.random_normal([n_input]))
  39.  
    }
  40.  
     
  41.  
    # 导入MNIST数据
  42.  
    mnist = input_data.read_data_sets("MNIST_data", one_hot=False)
  43.  
     
  44.  
    #---------------------------------压缩和解压函数定义---------------------------------------
  45.  
    # Building the encoder
  46.  
    def encoder(x):
  47.  
    # 第一层Layer压缩成256个元素 压缩函数为sigmoid(压缩值为0-1范围内)
  48.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
  49.  
    biases['encoder_b1']))
  50.  
    # 第二层Layer压缩成128个元素
  51.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
  52.  
    biases['encoder_b2']))
  53.  
    return layer_2
  54.  
     
  55.  
    # Building the decoder
  56.  
    def decoder(x):
  57.  
    # 解压隐藏层调用sigmoid激活函数(范围内为0-1区间)
  58.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
  59.  
    biases['decoder_b1']))
  60.  
    # 第二层Layer解压成784个元素
  61.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
  62.  
    biases['decoder_b2']))
  63.  
    return layer_2
  64.  
     
  65.  
    #-----------------------------------压缩和解压操作---------------------------------------
  66.  
    # Construct model
  67.  
    # 压缩:784 => 128
  68.  
    encoder_op = encoder(X)
  69.  
     
  70.  
    # 解压:784 => 128
  71.  
    decoder_op = decoder(encoder_op)
  72.  
     
  73.  
    #--------------------------------对比预测和真实结果---------------------------------------
  74.  
    # 预测
  75.  
    y_pred = decoder_op
  76.  
     
  77.  
    # 输入数据的类标(Labels)
  78.  
    y_true = X
  79.  
     
  80.  
    # 定义loss误差计算 最小化平方差
  81.  
    cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
  82.  
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
  83.  
     
  84.  
    #-------------------------------------训练及可视化-------------------------------------
  85.  
    # 初始化
  86.  
    init = tf.initialize_all_variables()
  87.  
     
  88.  
    # 训练集可视化操作
  89.  
    with tf.Session() as sess:
  90.  
    sess.run(init)
  91.  
    total_batch = int(mnist.train.num_examples/batch_size)
  92.  
     
  93.  
    # 训练数据 training_epochs为5组实验
  94.  
    for epoch in range(training_epochs):
  95.  
    # Loop over all batches
  96.  
    for i in range(total_batch):
  97.  
    batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0
  98.  
    # 运行初始化和误差计算操作
  99.  
    _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
  100.  
    # 每个epoch显示误差值
  101.  
    if epoch % display_step == 0:
  102.  
    print("Epoch:", 'd' % (epoch 1), "cost=", "{:.9f}".format(c))
  103.  
    print("Optimization Finished!")
  104.  
     
  105.  
    # 压缩和解压测试集
  106.  
    encode_decode = sess.run(
  107.  
    y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})
  108.  
     
  109.  
    # 比较原始图像和预测图像数据
  110.  
    f, a = plt.subplots(2, 10, figsize=(10, 2))
  111.  
     
  112.  
    # 显示结果 上面10个样本是真实数据 下面10个样本是预测结果
  113.  
    for i in range(examples_to_show):
  114.  
    a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
  115.  
    a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
  116.  
    plt.show()
学新通

三.特征聚类分析

第一部分实验完成,它对比了10张原始图像和预测图像。我们接着分享第二部分的实验,生成聚类图。

第一步,修改参数。

修改如下,学习效率设置为0.001,训练批次设置为20。

  1.  
    # 基础参数设置
  2.  
    learning_rate = 0.001 #学习效率
  3.  
    training_epochs = 20 #20组训练
  4.  
    batch_size = 256 #batch大小
  5.  
    display_step = 1

第二步,增加encoder和decoder层数,并修改参数。

我们将隐藏层设置为4层,这样的效果会更好。首先从784压缩到128,再压缩到64、10,最后压缩到只有2个元素(特征),从而显示在二维图像上。同时更新weights值和biases值,encoder和decoder都设置为4层。

  1.  
    # 隐藏层设置
  2.  
    n_hidden_1 = 128 #第一层特征数量
  3.  
    n_hidden_2 = 64 #第二层特征数量
  4.  
    n_hidden_3 = 10 #第三层特征数量
  5.  
    n_hidden_4 = 2 #第四层特征数量
  6.  
     
  7.  
    weights = {
  8.  
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
  9.  
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
  10.  
    'encoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3])),
  11.  
    'encoder_h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4])),
  12.  
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_3])),
  13.  
    'decoder_h2': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_2])),
  14.  
    'decoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
  15.  
    'decoder_h4': tf.Variable(tf.random_normal([n_hidden_1, n_input]))
  16.  
    }
  17.  
     
  18.  
    biases = {
  19.  
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  20.  
    'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  21.  
    'encoder_b3': tf.Variable(tf.random_normal([n_hidden_3])),
  22.  
    'encoder_b4': tf.Variable(tf.random_normal([n_hidden_4])),
  23.  
    'decoder_b1': tf.Variable(tf.random_normal([n_hidden_3])),
  24.  
    'decoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  25.  
    'decoder_b3': tf.Variable(tf.random_normal([n_hidden_1])),
  26.  
    'decoder_b4': tf.Variable(tf.random_normal([n_input])),
  27.  
    }
学新通

第三步,修改压缩和解压定义函数,也是增加到四层。

  1.  
    #---------------------------------压缩和解压函数定义---------------------------------------
  2.  
    # Building the encoder
  3.  
    def encoder(x):
  4.  
    # 压缩隐藏层调用函数sigmoid(压缩值为0-1范围内)
  5.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
  6.  
    biases['encoder_b1']))
  7.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
  8.  
    biases['encoder_b2']))
  9.  
    layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['encoder_h3']),
  10.  
    biases['encoder_b3']))
  11.  
    # 输出范围为负无穷大到正无穷大 调用matmul函数
  12.  
    layer_4 = tf.add(tf.matmul(layer_3, weights['encoder_h4']),
  13.  
    biases['encoder_b4'])
  14.  
    return layer_4
  15.  
     
  16.  
    # Building the decoder
  17.  
    def decoder(x):
  18.  
    # 解压隐藏层调用sigmoid激活函数(范围内为0-1区间)
  19.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
  20.  
    biases['decoder_b1']))
  21.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
  22.  
    biases['decoder_b2']))
  23.  
    layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['decoder_h3']),
  24.  
    biases['decoder_b3']))
  25.  
    layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['decoder_h4']),
  26.  
    biases['decoder_b4']))
  27.  
    return layer_4
学新通

第四步,最后修改训练代码,我们不再观看它的训练结果,而是观察它解压前的结果。

  1.  
    # 观察解压前的结果
  2.  
    encoder_result = sess.run(encoder_op, feed_dict={X: mnist.test.images})
  3.  
    # 显示encoder压缩成2个元素的预测结果
  4.  
    plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=mnist.test.labels)
  5.  
    plt.colorbar()
  6.  
    plt.show()

完整代码如下:

  1.  
    # -*- coding: utf-8 -*-
  2.  
    """
  3.  
    Created on Wed Jan 15 15:35:47 2020
  4.  
    @author: xiuzhang Eastmount CSDN
  5.  
    """
  6.  
    import numpy as np
  7.  
    import tensorflow as tf
  8.  
    import matplotlib.pyplot as plt
  9.  
    from tensorflow.examples.tutorials.mnist import input_data
  10.  
     
  11.  
    #-----------------------------------初始化设置---------------------------------------
  12.  
    # 基础参数设置
  13.  
    learning_rate = 0.001 #学习效率
  14.  
    training_epochs = 20 #20组训练
  15.  
    batch_size = 256 #batch大小
  16.  
    display_step = 1
  17.  
    examples_to_show = 10 #显示10个样本
  18.  
     
  19.  
    # 神经网络输入设置
  20.  
    n_input = 784 #MNIST输入数据集(28*28)
  21.  
     
  22.  
    # 输入变量(only pictures)
  23.  
    X = tf.placeholder("float", [None, n_input])
  24.  
     
  25.  
    # 隐藏层设置
  26.  
    n_hidden_1 = 128 #第一层特征数量
  27.  
    n_hidden_2 = 64 #第二层特征数量
  28.  
    n_hidden_3 = 10 #第三层特征数量
  29.  
    n_hidden_4 = 2 #第四层特征数量
  30.  
     
  31.  
    weights = {
  32.  
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
  33.  
    'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
  34.  
    'encoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3])),
  35.  
    'encoder_h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4])),
  36.  
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_3])),
  37.  
    'decoder_h2': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_2])),
  38.  
    'decoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
  39.  
    'decoder_h4': tf.Variable(tf.random_normal([n_hidden_1, n_input]))
  40.  
    }
  41.  
     
  42.  
    biases = {
  43.  
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
  44.  
    'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  45.  
    'encoder_b3': tf.Variable(tf.random_normal([n_hidden_3])),
  46.  
    'encoder_b4': tf.Variable(tf.random_normal([n_hidden_4])),
  47.  
    'decoder_b1': tf.Variable(tf.random_normal([n_hidden_3])),
  48.  
    'decoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
  49.  
    'decoder_b3': tf.Variable(tf.random_normal([n_hidden_1])),
  50.  
    'decoder_b4': tf.Variable(tf.random_normal([n_input])),
  51.  
    }
  52.  
     
  53.  
    # 导入MNIST数据
  54.  
    mnist = input_data.read_data_sets("MNIST_data", one_hot=False)
  55.  
     
  56.  
    #---------------------------------压缩和解压函数定义---------------------------------------
  57.  
    # Building the encoder
  58.  
    def encoder(x):
  59.  
    # 压缩隐藏层调用函数sigmoid(压缩值为0-1范围内)
  60.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
  61.  
    biases['encoder_b1']))
  62.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
  63.  
    biases['encoder_b2']))
  64.  
    layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['encoder_h3']),
  65.  
    biases['encoder_b3']))
  66.  
    # 输出范围为负无穷大到正无穷大 调用matmul函数
  67.  
    layer_4 = tf.add(tf.matmul(layer_3, weights['encoder_h4']),
  68.  
    biases['encoder_b4'])
  69.  
    return layer_4
  70.  
     
  71.  
    # Building the decoder
  72.  
    def decoder(x):
  73.  
    # 解压隐藏层调用sigmoid激活函数(范围内为0-1区间)
  74.  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
  75.  
    biases['decoder_b1']))
  76.  
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
  77.  
    biases['decoder_b2']))
  78.  
    layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['decoder_h3']),
  79.  
    biases['decoder_b3']))
  80.  
    layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['decoder_h4']),
  81.  
    biases['decoder_b4']))
  82.  
    return layer_4
  83.  
     
  84.  
    #-----------------------------------压缩和解压操作---------------------------------------
  85.  
    # Construct model
  86.  
    # 压缩:784 => 128
  87.  
    encoder_op = encoder(X)
  88.  
     
  89.  
    # 解压:784 => 128
  90.  
    decoder_op = decoder(encoder_op)
  91.  
     
  92.  
    #--------------------------------对比预测和真实结果---------------------------------------
  93.  
    # 预测
  94.  
    y_pred = decoder_op
  95.  
     
  96.  
    # 输入数据的类标(Labels)
  97.  
    y_true = X
  98.  
     
  99.  
    # 定义loss误差计算 最小化平方差
  100.  
    cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
  101.  
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
  102.  
     
  103.  
    #-------------------------------------训练及可视化-------------------------------------
  104.  
    # 初始化
  105.  
    init = tf.initialize_all_variables()
  106.  
     
  107.  
    # 训练集可视化操作
  108.  
    with tf.Session() as sess:
  109.  
    sess.run(init)
  110.  
    total_batch = int(mnist.train.num_examples/batch_size)
  111.  
     
  112.  
    # 训练数据
  113.  
    for epoch in range(training_epochs):
  114.  
    # Loop over all batches
  115.  
    for i in range(total_batch):
  116.  
    batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0
  117.  
    # 运行初始化和误差计算操作
  118.  
    _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
  119.  
    # 每个epoch显示误差值
  120.  
    if epoch % display_step == 0:
  121.  
    print("Epoch:", 'd' % (epoch 1), "cost=", "{:.9f}".format(c))
  122.  
    print("Optimization Finished!")
  123.  
     
  124.  
    # 观察解压前的结果
  125.  
    encoder_result = sess.run(encoder_op, feed_dict={X: mnist.test.images})
  126.  
    # 显示encoder压缩成2个元素的预测结果
  127.  
    plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=mnist.test.labels)
  128.  
    plt.colorbar()
  129.  
    plt.show()
学新通

这个训练过程需要一点时间,运行结果如下图所示:

学新通

聚类显示结果如下图所示,它将不同颜色的分在一堆,对应不同的数字。比如左下角数据集被无监督学习聚类为数字0,而另一边又是其他的数据。

学新通

但其聚类结果还有待改善,因为这只是Autoencoder的一个简单例子。希望这篇文章能够帮助博友们理解和认识无监督学习和Autoencoder算法,后续作者会更深入的分享好案例。

参考文献:

[1] 杨秀璋, 颜娜. Python网络数据爬取及分析从入门到精通(分析篇)[M]. 北京:北京航天航空大学出版社, 2018.
[2] “莫烦大神” 网易云视频地址
[3] https://study.163.com/course/courseLearn.htm?courseId=1003209007
[4] https://github.com/siucaan/CNN_MNIST
[5] https://github.com/eastmountyxz/AI-for-TensorFlow
[6]《机器学习》周志华
[7] 深度学习(07)RNN-循环神经网络-02-Tensorflow中的实现 - 莫失莫忘Lawlite
[8] https://github.com/lawlite19/DeepLearning_Python

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabaif
系列文章
更多 icon
同类精品
更多 icon
继续加载