自编码和解码

压缩与解压

  有一个神经网络,它所做的事情是接收一张图片,然后给它打码,最后再从打码后的图片中还原,具体过程如下:

在这里插入图片描述

  可以看出图片其实是经过了压缩再解压的这一道工序,当压缩的时候,原有的图片质量被缩减,解压时用信息量小却包含了所有关键信息的文件恢复出原本的图片。为什么要这样做呢?
在这里插入图片描述

  原来有时神经网络要接受大量的输入信息,比如输入信息是高清图片时,输入信息量可能达到上千万,让神经网络直接从上千万个信息源中学习是一件很吃力的工作。所以需要压缩一下,提取出原图片中的最具代表性的信息,缩减输入信息量,再把缩减过后的信息放进神经网络学习,这样学习起来就简单轻松了,自编码就能在这时发挥作用。通过将原数据白色的X压缩并解压成黑色的X,然后通过对比黑白X,求出预测误差,进行反向传递,逐步提升自编码的准确性。训练好的自编码中间这一部分就是能总结原数据的精髓。可以看出,从头到尾我们只用到了输入数据X,并没有用到X对应的数据标签,所以也可以说自编码是一种非监督学习。到了真正使用自编码的时候,通常只会用到自编码前半部分。

编码器Encoder

  这部分也叫作encoder编码器,编码器能得到原数据的精髓,然后我们只需要再创建一个小的神经网络学习这个精髓的数据,不仅减少了神经网络的负担,而且同样能达到很好的效果。
在这里插入图片描述

  右图是一个通过自编码整理出来的数据,它能从原数据中总结出每种类型数据的特征,如果把这些特征类型都放在一张二维的图片上,每种类型都已经被很好的用原数据的精髓区分开来。如果你了解PCA主成分分析,在提取主要特征时,自编码和它一样,甚至超越了PCA。换句话说,自编码可以像PCA一样给特征属性降维。

Autoencoder

  基本设置代码如下:

learning_rate = 0.01  # 学习率
training_epochs = 20  # 训练的轮数
batch_size = 256  # 每次训练的数据多少
display_step = 1  # 每隔多少轮显示一次训练结果
examples_to_show = 10  # 从测试集中中选取10张图片去验证自动编码器的结果
n_input = 784  # 输入数据的特征值个数,MNIST data input (img shape: 28 * 28)
  • 压缩环节:我们要把这个Features不断压缩,经过第一个隐藏层压缩至256Features,再经过第二个隐藏层压缩至128个。
  • 解压环节:我们将128Features还原至256个,再经过一步还原至784个。
  • 对比环节:比较原始数据与还原后的拥有784Features的数据进行cost的对比,根据cost来提升Autoencoder的准确率。

下面是两个隐藏层的weightsbiases定义:

n_hidden_1 = 256  # (第一个隐藏层神经元的个数,也是特征值的个数)1st layer num features
n_hidden_2 = 128  # (第二个隐藏层神经元的个数,也是特征值的个数)2nd layer num features

# 然后定义输入数据,这里是无监督学习,所以只要输入图片数据,不需要标记数据
X = tf.placeholder("float", [None, n_input])

# 初始化每一层的权重和偏置
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_b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
    'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'decoder_b2': tf.Variable(tf.random_normal([n_input])),
}

  下面来定义EncoderDecoder,使用的Activation functionsigmoid,压缩之后的值应该在[0, 1]这个范围内。在decoder过程中,通常使用对应于encoderActivation function

def encoder(x):  # (定义压缩函数)Building the encoder
    # Encoder Hidden layer with sigmoid activation
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1']))
    # Decoder Hidden layer with sigmoid activation
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']), biases['encoder_b2']))
    return layer_2

def decoder(x):  # (定义解压缩函数)Building the decoder
    # Encoder Hidden layer with sigmoid activation
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1']))
    # Decoder Hidden layer with sigmoid activation
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_b2']))
    return layer_2

来实现EncoderDecoder输出的结果:

# (构建模型)Construct model
encoder_op = encoder(X)  # 128 Features
decoder_op = decoder(encoder_op)  # 784 Features

# (得出预测值)Prediction
y_pred = decoder_op  # After
# (得出真实值,即输入值)Targets (Labels) are the input data
y_true = X  # Before

再通过非监督学习进行对照,即对原始的有784个Features的数据集通过Prediction得出的有784个Features的数据集进行最小二乘法的计算,并且使cost最小化:

# (定义损失)Define loss and optimizer, minimize the squared error
cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

最后通过Matplotlibpyplot模块将结果显示出来,注意在输出时MNIST数据集经过压缩之后x的最大值是1,而非255

with tf.Session() as sess:  # Launch the graph
    sess.run(tf.global_variables_initializer())
    total_batch = int(mnist.train.num_examples / batch_size)

    for epoch in range(training_epochs):  # Training cycle
        for i in range(total_batch):  # Loop over all batches
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)  # max(x) = 1, min(x) = 0
            # Run optimization op (backprop) and cost op (to get loss value)
            _, c = sess.run([optimizer, cost], feed_dict={
    
    X: batch_xs})

        if epoch % display_step == 0:  # Display logs per epoch step
            print("Epoch:", '%04d' % (epoch + 1), "cost =", "{:.9f}".format(c))

    print("Optimization Finished!")
    # Applying encode and decode over test set
    encode_decode = sess.run(y_pred, feed_dict={
    
    X: mnist.test.images[:examples_to_show]})
    # Compare original images with their reconstructions
    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()

通过20Epoch的训练,结果如下,上面一行是真实数据,下面一行是经过encoderdecoder之后的数据。如果继续进行训练,效果会更好。

在这里插入图片描述

おすすめ

転載: blog.csdn.net/fukangwei_lite/article/details/121714223
おすすめ