自编码器

基本自编码器

考虑监督学习神经网络模型:
y = f θ ( x ) y=f_\theta(x) y=fθ(x)
x是样本数据,y是通过x预测得到实际值。如果使用样本中数据x替代标签数据时有:
x ^ = f θ ( x ) \hat x=f_\theta(x) x^=fθ(x)
即尝试着利用数据x本身作为监督信号来指导网络的训练,希望神经网络能够学习到映射𝑓𝜃:𝒙 → 𝒙,把网络𝑓𝜃切分为 2 个部分,前面的子网络尝试学习映射关 系:𝑔𝜃1:𝒙 → 𝒛,后面的子网络尝试学习映射关系ℎ𝜃2:𝒛 → 𝒙,(𝒛称为隐变量,是对𝒙的降维操作,体现了𝒙的分布)我们把𝑔𝜃1看成一个数据编码 (Encode)的过程,ℎ𝜃2看成数据解码(Decode)的过程,编码器和解码器共同完成了输入数据𝒙的编码和解码过程,我们把整个网络模型𝑓𝜃叫做自动编码器(Auto-Encoder),简称自编码器。

在这里插入图片描述

在这里插入图片描述

x ^ = h θ ( g θ ( x ) ) z = g θ ( x ) \hat x = h_\theta(g_\theta(x)) \quad\quad\quad\quad z=g_\theta(x) x^=hθ(gθ(x))z=gθ(x)
模型损失函数可采用方差表示:
l o s s = ∑ ( x − x ^ ) 2 loss = \sum(x-\hat x)^2 loss=(xx^)2

自编码器的模型性能一般不好量化评价,但我们最终希望获得还原度较高的重建样本。一般需要根据具体问题来讨论自编码器的学习效果,比如对于图片重建,一般依赖于人工主观评价图片生成的质量。

MNIST 图片重建实例

import numpy as np
import tensorflow as tf
import tensorflow.python.keras.datasets.mnist as mnist
import matplotlib.pyplot as plt

tf.compat.v1.disable_eager_execution()

TRAINING_STEPS = 10000
batch_size = 500


# 定义mnist数据加载初始化
def data_init():
    (x_train, y_train), (x_test, y_test) = mnist.load_data("E://python//tensorflow_study//MNIST_data//mnist.npz")
    x_train = np.reshape(x_train, (60000, 784))
    x_test = np.reshape(x_test, (10000, 784))

    x_train = (x_train - 255) / 255
    x_test = (x_test - 255) / 255

    # 5.5W训练集
    x_train_np = np.array(x_train[5000:], dtype='float32')

    # 1W测试集
    x_test_np = np.array(x_test[:], dtype='float32')

    return {"x_train": x_train_np, "x_test": x_test_np}


def getRandomIndex(n, x):
    # 索引范围为[0, n),随机选x个不重复,注意replace=False不重复
    if x > n:
        x = n
    index = np.random.choice(np.arange(n), size=x, replace=False)
    return index


# 随机获取数据
def data_batch_set(input_data_feed, feed_name):
    data_len = len(input_data_feed[feed_name])
    index = getRandomIndex(data_len, batch_size)
    return input_data_feed[feed_name][index]


# 定义层函数
def add_layer(input, in_size, out_size, active_function):
    # input 输入矩阵
    # in_size 输入矩阵列大小
    # out_size 输出矩阵列大小
    # active_function 激活函数
    weighs = tf.Variable(tf.compat.v1.random_normal([in_size, out_size]))
    # 定义L2正则化(定义刻画网络复杂度的损失函数,解决过拟合问题)
    regularizers_L2 = tf.keras.regularizers.l2(0.000005)
    weighs_loss = regularizers_L2(x=weighs)
    # 加入集合,losses是集合的名字,第二个参数是要加入这个集合的内容。
    tf.compat.v1.add_to_collection('losses', weighs_loss)
    bais = tf.Variable(tf.compat.v1.random_normal([1, out_size]))
    # 激励输入
    z_i = tf.matmul(input, weighs) + bais
    return active_function(z_i)


# 定义前向传播
def inference(input_tensor):
    # 编码器部分
    # 第一层输入NX784形状输入,输出为NX512
    out_1 = add_layer(input=input_tensor, in_size=784, out_size=512, active_function=tf.nn.sigmoid)
    # 第二层输入为NX512,输出为NX64
    out_2 = add_layer(input=out_1, in_size=512, out_size=64, active_function=tf.nn.sigmoid)
    # 第三层输入为NX64,输出为NX16
    out_3 = add_layer(input=out_2, in_size=64, out_size=16, active_function=tf.nn.sigmoid)

    # 解码器部分
    # 第四层输入NX16形状输入,输出为NX64
    out_4 = add_layer(input=out_3, in_size=16, out_size=64, active_function=tf.nn.sigmoid)
    # 第五层输入为NX64,输出为NX512
    out_5 = add_layer(input=out_4, in_size=64, out_size=512, active_function=tf.nn.sigmoid)
    # 第六层输入为NX512,输出为NX784(最后输出图片)
    out_6 = add_layer(input=out_5, in_size=512, out_size=784, active_function=tf.nn.sigmoid)

    return out_6


# 定义模型训练过程
def train():
    global_step = tf.Variable(0, trainable=False)

    # 定义输入、标签。这里标签y_就是输入x
    x = tf.compat.v1.placeholder(tf.float32, [None, 784])
    y_ = tf.compat.v1.placeholder(tf.float32, [None, 784])

    # 计算当前参数在神经网络上的结果
    y = inference(x)

    # 定义损失函数
    loss_mean = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_)))

    # 将loss_mean加入损失集合。
    tf.compat.v1.add_to_collection('losses', loss_mean)
    # 总损失函数
    loss = tf.add_n(tf.compat.v1.get_collection('losses'))

    # 初始速率0.1,后面每训练100次后在学习速率基础上乘以0.96
    learning_rate = tf.compat.v1.train.exponential_decay(0.9999, global_step, 5000, 0.9, staircase=True)

    # 使用tf.train.GradientDescentOptimizer 优化算法来优化损失函数。
    train_step = tf.compat.v1.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)

    # 加载样本数据
    data_feed = data_init()
    # 初始化会话并开始训练过程。
    init_var = tf.compat.v1.global_variables_initializer()
    with tf.compat.v1.Session() as sess:
        sess.run(init_var)

        for i in range(TRAINING_STEPS):
            train_batch_x = data_batch_set(data_feed, feed_name='x_train')
            # 标签就是样本x
            sess.run(train_step, feed_dict={x: train_batch_x, y_: train_batch_x})
            if i % 500 == 0:
                # loss
                loss_val = sess.run(loss, feed_dict={x: train_batch_x, y_: train_batch_x})
                print("After %d training step(s) , loss=%f" % (i, loss_val))

        # test
        test_batch_x = data_batch_set(data_feed, feed_name='x_test')
        # test_img
        test_x = test_batch_x[0]

        # 原图
        test_x_img = test_x * 255
        test_x_img = np.reshape(test_x_img, (28, 28))

        # 重建后的图
        # 转换为0-1之间的值
        test_y = tf.nn.sigmoid(y)
        test_y = sess.run(test_y, feed_dict={x: [test_x]})
        test_y_img = test_y * 255
        test_y_img = np.reshape(test_y_img, (28, 28))

        plt.subplot(1, 2, 1)
        plt.title('origin')
        plt.imshow(test_x_img)

        plt.subplot(1, 2, 2)
        plt.title('forecast')
        plt.imshow(test_y_img)

        plt.show()


def main():
    train()


if __name__ == '__main__':
    main()

在这里插入图片描述

降噪自编码器

基于基本的自编码模型,将输入样本x加上噪声,作为输入,标签数据使用原生x去训练神经网络的一种模型。
x = x + ϵ ϵ −   N ( 0 , σ 2 ) x = x + \epsilon \quad\quad\quad\quad\epsilon -~ N(0,\sigma^2) x=x+ϵϵ N(0,σ2)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值