TensorFlow实现自编码器

来源:互联网 发布:知善恶树英语 编辑:程序博客网 时间:2024/06/05 10:27
import numpy as npimport sklearn.preprocessing as prepimport tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_dataclass 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        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 = tf.add(tf.matmul(self.hidden, self.weights['w2']), self.weights['b2'])        # cost        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)    def _initialize_weights(self):        all_weights = dict()        all_weights['w1'] = tf.get_variable("w1", shape=[self.n_input, self.n_hidden],            initializer=tf.contrib.layers.xavier_initializer())        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):        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 getBiases(self):        return self.sess.run(self.weights['b1'])class MaskingNoiseAutoencoder(object):    def __init__(self, n_input, n_hidden, transfer_function = tf.nn.softplus, optimizer = tf.train.AdamOptimizer(),                 dropout_probability = 0.95):        self.n_input = n_input        self.n_hidden = n_hidden        self.transfer = transfer_function        self.dropout_probability = dropout_probability        self.keep_prob = tf.placeholder(tf.float32)        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(tf.nn.dropout(self.x, self.keep_prob), self.weights['w1']),                                           self.weights['b1']))        self.reconstruction = tf.add(tf.matmul(self.hidden, self.weights['w2']), self.weights['b2'])        # cost        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)    def _initialize_weights(self):        all_weights = dict()        all_weights['w1'] = tf.get_variable("w1", shape=[self.n_input, self.n_hidden],            initializer=tf.contrib.layers.xavier_initializer())        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):        cost, opt = self.sess.run((self.cost, self.optimizer),                                  feed_dict = {self.x: X, self.keep_prob: self.dropout_probability})        return cost    def calc_total_cost(self, X):        return self.sess.run(self.cost, feed_dict = {self.x: X, self.keep_prob: 1.0})    def transform(self, X):        return self.sess.run(self.hidden, feed_dict = {self.x: X, self.keep_prob: 1.0})    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.keep_prob: 1.0})    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_data', one_hot=True)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_testdef 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)]X_train, X_test = standard_scale(mnist.train.images, mnist.test.images)n_samples = int(mnist.train.num_examples)training_epochs = 20batch_size = 128display_step = 1autoencoder = 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)    # Loop over all batches    for i in range(total_batch):        batch_xs = get_random_block_from_data(X_train, batch_size)        # Fit training using batch data        cost = autoencoder.partial_fit(batch_xs)        # Compute average loss        avg_cost += cost / n_samples * batch_size    # Display logs per epoch step    if epoch % display_step == 0:        print("Epoch:", '%d,' % (epoch + 1),              "Cost:", "{:.9f}".format(avg_cost))print("Total cost: " + str(autoencoder.calc_total_cost(X_test)))