逐层构建深度自编码器

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39709476/article/details/79144679
自编码器是神经网络的一种基本结构,通过使神经网络的输出等于输入,迫使隐层学习到最能表征原数据的特征。自编码器属于一种无监督学习方法,也可称为自监督学习(网络的输入等于输出)。能对数据进行非线性降维。同时,可以作为一种特征提取工具,在训练自编码器的同时,提取出数据的特征,可以使用这些特征做后续的分类问题。也可以使用自编码器训练的到的权重,去初始化深度神经网络,使得深度神经网络更容易收敛到最小值。
class AdditiveGaussianNoiseAutoencoder(object):#定义一个自编码器的类

    def __init__(self, n_input, n_hidden, transfer_function = tf.nn.sigmoid, 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

        network_weights = self._initialize_weights()

        self.weights = network_weights



        # model

        self.x = tf.placeholder(tf.float32, [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 = self.transfer(tf.add(tf.matmul(self.hidden, self.weights['w2']), self.weights['b2']))



        # cost
        regularizer=tf.contrib.layers.l2_regularizer(0.05)
        self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(self.reconstruction, self.x), 2.0))+regularizer(self.weights['w1'])

        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 = 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.transpose(all_weights['w1'])

        #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):

        cost, opt = self.sess.run((self.cost, self.optimizer), feed_dict = {self.x: X,

                                                                            self.scale: self.training_scale

                                                                            })

        return cost	



    def calc_total_cost(self, X):

        return self.sess.run(self.cost, feed_dict = {self.x: X,

                                                     self.scale: self.training_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 = self.sess.run(tf.random_normal([1, self.n_hidden]))

        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.training_scale

                                                               })


    def getWeights(self):

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

        return self.sess.run(self.weights['w2'])


    def getBiases(self):

        return self.sess.run(self.weights['b1'])

    def getBiases1(self):

        return self.sess.run(self.weights['b2'])
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

import numpy as np  
import tensorflow as tf  
import sys
sys.path.append('F:/autoencoder')
import DenoisingAutoencoder
train_data=mnist.train.images
train_tag=mnist.train.labels
test_data=mnist.test.images
test_tag=mnist.test.labels

#定义训练参数  
training_epochs = 100
display_step = 1  
stack_size = 3  #栈中包含3个ae  
hidden_size = [400, 100,10]  
batch_size=100
data_size=train_data.shape[0]
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)]  

#建立sdae图  
sdae = []  
for i in range(stack_size):  
    if i == 0:   
        ae = DenoisingAutoencoder.AdditiveGaussianNoiseAutoencoder(n_input = 784,  
                                               n_hidden = hidden_size[i],  
                                               transfer_function = tf.nn.sigmoid,  
                                               optimizer = tf.train.AdamOptimizer(learning_rate = 0.001),  
                                               scale = 0.0)  
        ae._initialize_weights()  
        sdae.append(ae)  
    else:  
        ae = DenoisingAutoencoder.AdditiveGaussianNoiseAutoencoder(n_input=hidden_size[i-1],  
                                              n_hidden=hidden_size[i],  
                                              transfer_function=tf.nn.sigmoid,  
                                              optimizer=tf.train.AdamOptimizer(learning_rate=0.001),  
                                              scale=0.0)  
        ae._initialize_weights()  
        sdae.append(ae)  
  
          
W = []  
b = []  
Hidden_feature = [] #保存每个ae的特征  
#X_train = np.array([0])  
for j in range(stack_size):  
    #输入  
    if j == 0:  
        X_train=train_data
        print (X_train.shape) 
    else:  
 
        X_train = sdae[j-1].transform(X_train)  
        print (X_train.shape)  
          
      
    #训练  
    for epoch in range(training_epochs):  
        avg_cost = 0.  
        total_batch = int(X_train.shape[0] / batch_size)  
        # Loop over all batches  
        for i in range(total_batch): 
            start=(i*batch_size)%data_size
            end=min(start+batch_size,data_size)
  
            # Fit training using batch data  
            cost = sdae[j].partial_fit(train_data[start:end])  
            # Compute average loss  
            avg_cost += cost / X_train.shape[1]  
  
        # Display logs per epoch step  
        #if epoch % display_step == 0:
        if(epoch==0 or (epoch + 1)%10==0):
            print ("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(avg_cost))
    Hidden_feature.append(sdae[j].transform(X_train))
    #保存每个ae的参数  
    weight = sdae[j].getWeights()  
    W.append(weight)  
    b.append(sdae[j].getBiases())  
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
(55000, 784)
Epoch: 0001 cost= 2034.047836615
Epoch: 0010 cost= 382.623935622
Epoch: 0020 cost= 232.092221630
Epoch: 0030 cost= 170.012632720
Epoch: 0040 cost= 135.499188793
Epoch: 0050 cost= 113.486793207
(55000, 400)
Epoch: 0001 cost= 2907.624038086
Epoch: 0010 cost= 994.305351563
Epoch: 0020 cost= 694.901478271
Epoch: 0030 cost= 593.179305420
Epoch: 0040 cost= 545.583732300
Epoch: 0050 cost= 517.480595703
(55000, 100)
Epoch: 0001 cost= 5003.117812500
Epoch: 0010 cost= 3782.418325195
Epoch: 0020 cost= 3354.688271484
Epoch: 0030 cost= 3197.682797852
Epoch: 0040 cost= 3126.495908203
Epoch: 0050 cost= 3089.451923828
可以看出,随着训练次数的增加,重构误差不断减小。至此,便得到了基于mnist数据集的自编码器,自编码器的节点数分别为【784,400,784】,【400,100,400】,【100,10,100】,我们同时得到了每一个自编码器的隐层输出。可以使用这些隐层输出作为特征,使用SVM对mnist数据集进行分类。也可以使用我们得到的自编码器的权重和偏置,初始化一个节点数为【784,400,100,10】的深度神经网络,最后加上一个softmax分类器。使用训练数据和标签对整个网络进行微调,得到深度神经网络模型,进而对mnist数据集进行分类。



                                    
展开阅读全文

没有更多推荐了,返回首页