TensorFlow学习(三)—_实现自编码器

欢迎点击参观我的 ——> 个人学习网站

自编码器的介绍请参考 这里

准备

​ 导入所需要的包。

import numpy as np
import sklearn.preprocessing as pre
import tensorflow as tf
from tensorflow.example.tutorials.mnist import input_data

定义函数

参数初始化方法 xavier initialization

这里是初始化参数的方法,不是初始化参数!

为什么要参数初始化?

​ 如果神经网络的权重初始化太小,那么我们的输入在经过每层计算后,逐渐缩小而难以产生作用,如果权重初始化太大,则计算后将逐渐增大并导致发散和失效。

​ 不适合的权重似的隐含层的输入方差过大,经过 sigmoid 激活函数时离中心较远,导数接近于零,从而导致提督弥散。

* xavier权重初始化 *

​ xavier权重初始化可以减少梯度弥散,使输入可以传递的更深。

​ xavier根据某一层网络的输入、输出节点数量自动调整最合适的分布,让权重满足0均值,同时方差为 2nin+nout 2 n i n + n o u t ,分布可以使用均匀分布或者高斯分布。

​ 下面我们创建一个 6nin+nout,6nin+nout ⟮ − 6 n i n + n o u t , 6 n i n + n o u t ⟯ 范围内的均匀分布,而它的方差根据 D(x)=(maxmin)2/12 D ( x ) = ( m a x − m i n ) 2 / 12 正好等于 2nin+nout 2 n i n + n o u t

# fan_in:输入节点的数量,fan_out: 输出节点的数量
def xavier_init(fan_in, fan_out, constant=1):
    low = -constant * np.sqrt(6.0 / (fan_in + fan_out))
    high = constant * np.sqrt(6.0 / (fan_in + fan_out))
    return tf.random.unifom((fan_in, fan_out), minval=low, maxval=high, dtype=tf.float32)

定义自编码器类的构建函数

参数解释:

n_input: 输入层个数 n_hidden: 隐含层个数 transfer_function: 隐含层的激活函数,设为softplus

optimizer:优化器,设为Adam scale:高斯噪声系数,设为0.1

class内的scale参数设为一个placeholder 权重初始化使用定义的init_weights函数

这里我们只定义了一层隐含层,可以继续添加!

class AdditiveGaussianNoiseAutoencoder(object):
    def __init__(self, n_input, n_hidden, transfer_function=tf.nn.softplus,
                 optimizer=tf.train.AdamOptimizer(), scale=0.1):
        self.n_input = n_input
        self.n_hidden = n_hidden
        self.transfer = transfer_function
        self.scale = tf.placeholder(tf.float32)
        self.training_scale = scale
        weights = self.init_weights()
        self.weights = weights

定义权重初始化函数 init_weights

w1经过 xavier_init 函数初始化,传入输入层和隐含层的节点数,xavier会返回一个适合 softplus 等激活函数的权重初始分布,偏置 b1 全部置为0即可。对于输出层,因为没有使用激活函数,w2、b2 全部初始化为0。

def init_weights(self):
    all_weights = dict()
    all_weights['w1'] = tf.Variable(xavier_init(self.n_input, self.n_hidden))
    all_weights['b1'] = tf.Variable(tf.zeros([self.n_hidden], dtype=tf.float32))
    all_weights['w2'] = tf.Variable(tf.zeros([self.n_hidden, self.n_input], dtype=tf.float32))
    sll_weights['b2'] = tf.Variable(tf.zeros([n_input], dtype=tf.float32))
    return all_weights

定义网络结构

  • 输入层: self.x
  • 隐含层:首先计算 w1 * x + b ,然后带入激活函数 transfer 中计算。其中 x 为输入加上噪声即 self.x + scale * tf.random_normal({n_input,})
  • 重建层(输出层):将数据尽大的复原为输入的数据
self.x = tf.placeholder(tf.float, [None, self.n_input])
self.hidden = self.transfer(tf.add(tf.matmul(
    self.x + scale * tf.random_normal({n_input,}), 
    self.weights['w1']), self.weights['b1']))
self.reconstruction = tf.add(tf.matmul(
    self.hidden, self.weights['w2']), self.weights['b3'])

定义损失函数

使用平方误差函数(SSE)

self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(
                                self.reconstruction, self.x), 2.0))
self.optimizer = optimizer.minimize(self.cost)

初始化全部参数

init = tf.global_variables_initializer()
self.sess = tf.Session()
self.sess.run(init)

定义计算损失 cost 及执行进一步训练的函数 partial_fit

功能:触发训练操作,对一个 batch 的数据进行训练并计算当前的损失!

​ 函数里只需让Session执行两个计算图的节点,分别是损失 cost 和训练过程 optimizer ,输入的 feed_dict 包括输入数据 x 、噪声的系数 scale

def partial_fit(self, x):
    cost, opt = self.sess.run((self.cost, self.optimizer),
                             feed_Dict={self.x: x, self.scale: self.training_scale})
    return cost

定义总损失函数 calc_total_cost

自编码器训练完后,用来在测试集数据上对数据模型进行评测

​ 与 partial_fit 函数不同,这里只让Session执行一个计算图节点 self.cost ,传入的参数和上一个函数一样。

def cal_total_cost(self, x):
    return self.sess.run(self.cost, feed_dict={self.x: x, 
                                               self.scale: self.training.scale})

定义 transform 函数

功能:返回自编码器隐含层的输出结果。隐含层的主要功能是学习处数据中的高级特征,该函数目的是提供一个接口来得到经过隐含层抽象后的特征!

def transform(self, x):
    return self.sess.run(self.hidden, feed_dict={self.x: x, 
                                                self.scale: self.training_scale})

定义 generate 函数

功能:返回自编码器重构层的输出结果。重构层的主要功能是将隐含层提取的高阶特征复原为原输入数据。

def generaate(self, hidden = None):
    if hidden == None:
        hidden = np.random.normal(size = self.weights['b1'])
     return self.sess.run(self.reconstruction, feed_dict={self.hidden: hidden})

定义reconstruct 函数

功能:完整运行 输入数据 提取高级特征 复原数据 ,即同时包括 transformgenerate 函数。

def reconstruct(self, x):
    return self.sess.run(self.reconstruction, feed_dict={self.x: x,
                                                       self.scale: self.training_scale})

定义获取参数函数

功能:得到隐含层的权重 w1 和偏置 b1

def getWeight(self):
    return self.sess.run(self.weights['w1'])
def getBias(self):
    return self.sess.run(self.weights['b1'])

去噪编码器类已经定义完成,包括对神经网络的设计、权重的初始化以及几个成员函数。


测试

我们使用TensorFlow提供的 MNIST 数据集进行测试。

input_data.read_data_sets('MNIST_data', one_hot=True)

定义数据标准化函数

即将数据变为均值为0, 便准差为1的分布。将数据减去均值,然后除以方差。

​ 使用 sklearn.preprocessingStandardScaler 类现在训练集上进行 fit ,再将这个 Scale 用在训练数据和测试数据上。保证训练数据和测试数据使用同一个 Scale ,使得后面模型处理数据时的一致性。

def Standard_scale(x_train, x_test):
    preprocessor = prep.Stap yndardScale().fit(x_train)
    x_train = preprocessor.transform(x_train)
    x_test = preprocessor.transform(x_test)
    retutn x_train, x_test

定义获取随机 batch_size 大小的数据函数

不放回的每次抽样!

python
def get_random_block_from_data(data, batch_seze):
start_index = np.random.randint(0, len(data)-batch_size)
return data[start_index : (start_index + batch_size)]

标准化训练集、测试集

x_train, x_test = Standard_scale(mnist.train.images, mnist.test.images)

定义常用参数

参数解释:

n_samples:总训练样本数 training_epoches:最大训练轮数 batch_size:批数据样本大小,设为128

n_samples = int(mnist.train.num_examples)
training_epoches = 20
batch_size = 128
display_step = 1

训练

实例化自编码器类

autoencoder = AdditiveGaussianNoiseAutoencoder(n_input=784,
                                              n_hidden=200,
                                              transfer_function = tf.nn.softplus,
                                              optimizer=tf.train.AdamOptimizer(learning_rate=0.001),
                                              scale=0.01)

开始训练

for epoch in range(training_epochs):
    avg_cost = 0.
    total_batch = int(n_samples / batch_size)
    for i in range(total_size):
        batch_xs = get_random_block_from_data(x_train, batch_size)
        cost = autoencoder.partial_fit(batch_xs)
        avg_cost += cost / n_sample * batch_size

    if epoch % display_step == 0:
        print("Epoch:", '%04d' %(epoch + 1), "cost=", ":.9f".format(avg_cost))

评测

​ 使用平方误差和来

print("total cost:" + autoencoder.cal_total_cost(x_test))

去噪自编码器的TensorFlow实现完成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值