autoEncoder

autoEncoder

Deep Learning最简单的一种方法是利用人工神经网络的特点,人工神经网络(ANN)本身就是具有层次结构的系统,如果给定一个神经网络,我们假设其输出与输入是相同的,然后训练调整其参数,得到每一层中的权重。自然地,我们就得到了输入I的几种不同表示(每一层代表一种表示),这些表示就是特征。自动编码器就是一种尽可能复现输入信号的神经网络。为了实现这种复现,自动编码器就必须捕捉可以代表输入数据的最重要的因素,就像PCA那样,找到可以代表原信息的主要成分。————摘自此文

%matplotlib inline
import numpy as np
import sklearn.preprocessing as prep
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

这里采用xavier initialization来初始化参数,特点是会根据某一层网络的INPUT, OUTPUT节点数量自动调节最适合的分布。让权重被初始化得不大不小正好合适。

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_uniform((fan_in, fan_out),                    #均匀分布
                            minval = low, maxval = high,
                            dtype = tf.float32)
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.traning_scale = scale
        network_weights = self._initialize_weights()        #调用成员函数,得到初始化权重w、偏移b
        self.weights = network_weights

        #开始定义网格结构
        self.x = tf.placeholder(tf.float32, [None, self.n_input])
        self.hidden = self.transfer(tf.add(tf.matmul(                                  #给x加上噪声,并通过激活函数
                                            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['b2'])
        #定义自编码器的损失函数
        self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(                            #reconstruction与x的差的平方,在sum
                                            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)

    def _initialize_weights(self):
        all_weights = {}
        all_weights['w1'] = tf.Variable(xavier_init(self.n_input,                      #可以改为get_variables
                                                    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))
        all_weights['b2'] = tf.Variable(tf.zeros([self.n_input],
                                                dtype=tf.float32))
        return all_weights

    def partial_fit(self, X):                                                  #会触发训练操作,用一个batch训练并返回cost
        cost, opt = self.sess.run((self.cost, self.optimizer),
                                 feed_dict = {self.x: X, self.scale: self.traning_scale})
        return cost

    def calc_total_cost(self, X):
        return self.sess.run(self.cost,                                               #不会出发训练操作
                            feed_dict = {self.x: X, self.scale: self.traning_scale})

    def transform(self, X):                                                           #计算隐藏层的输出
        return self.sess.run(self.hidden, feed_dict = {self.x: X,
                                                      self.scale: self.training_scale})

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

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

    def getWeights(self):
        return self.sess.run(self.weights['w1'])

    def getBiases(self):
        return self.sess.run(self.weights['b1'])
mnist = input_data.read_data_sets("../../mnist/.", one_hot = True)
Extracting ../../mnist/./train-images-idx3-ubyte.gz
Extracting ../../mnist/./train-labels-idx1-ubyte.gz
Extracting ../../mnist/./t10k-images-idx3-ubyte.gz
Extracting ../../mnist/./t10k-labels-idx1-ubyte.gz
#标准化处理(均值为0, 标准差为1的分布),这里调用sklearn.preprossing的一个类,现在训练集上fit,再应用到train集跟test集上
def standard_scale(X_train, X_test):
    preprocessor = prep.StandardScaler().fit(X_train)
    X_train = preprocessor.transform(X_train)
    X_test = preprocessor.transform(X_test)
    return X_train, X_test
def get_random_block_from_data(data, batch_size):
    start_index = np.random.randint(0, len(data) - batch_size)
    return data[start_index:(start_index + batch_size)]
#将标准化变化应用到train集跟test集上
X_train, X_test = standard_scale(mnist.train.images, mnist.test.images)
mnist.test.cls = np.array([label.argmax() for label in mnist.test.labels])

img_size = 28

img_size_flat = img_size * img_size

img_shape = (img_size, img_size)

num_classes = 10

def plot_images(images, cls_true, cls_pred = None):
    assert len(images) == len(cls_true) == 9

    fig, axes = plt.subplots(3, 3)
    fig.subplots_adjust(hspace=0.3, wspace=0.3)

    for i, ax in enumerate(axes.flat):
        ax.imshow(images[i].reshape(img_shape), cmap='binary')

        if cls_pred is None:
            xlabel = "True: {0}".format(cls_true[i])
        else:
            xlabel = "True: {0}, Pred: {1}".format(cls_true[i], cls_pred[i])

        ax.set_xlabel(xlabel)
        ax.set_xticks([])
        ax.set_yticks([])

#plot some images in the standarded test-set
images = X_test[0:9]

cls_true = mnist.test.cls[0:9]

plot_images(images=images, cls_true=cls_true)

autoEncoder_第1张图片

n_samples = int(mnist.train.num_examples)
training_epochs = 30                 #最大训练轮数
batch_size = 64
display_step = 10
#创建一个AGN自编码器实例
autoEncoder = AdditiveGaussianNoiseAutoencoder(n_input=img_size_flat,
                                              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_batch):               #在每一个batch里面
        batch_xs = get_random_block_from_data(X_train, batch_size)  #获得一个随机的batch(不放回抽样,提高数据利用效率)

        cost = autoEncoder.partial_fit(batch_xs)                   #对batch进行训练,并返回cost
        avg_cost += cost / n_samples * batch_size                   #计算平均cost

    if epoch % display_step == 0:
        print("Epoch:", '%04d' % (epoch + 1), "cost=",
             "{:.9f}".format(avg_cost))
('Epoch:', '0001', 'cost=', '8004.381811364')
('Epoch:', '0011', 'cost=', '4676.882887358')
('Epoch:', '0021', 'cost=', '4472.520707528')
print("Total cost: " + str(autoEncoder.calc_total_cost(X_test)))
Total cost: 655923.0
images = X_test[0:9]

cls_true = mnist.test.cls[0:9]

re_images = autoEncoder.reconstruct(images)

plot_images(images=re_images, cls_true=cls_true)
print("---------------------------------------------------------")
plot_images(images=images, cls_true=cls_true)
---------------------------------------------------------

autoEncoder_第2张图片

autoEncoder_第3张图片

你可能感兴趣的:(机器学习)