tensorflow實現自編碼器
阿新 • • 發佈:2019-01-03
簡介
- 自編碼器是利用神經網路提取出影象中的高階特徵,同時可以利用高階特徵重構自己
- 如果向原圖中新增噪聲,則可以通過高階特徵的提取,對原始影象進行去噪
- tensorflow實戰第四章內容
程式碼
import numpy as np import sklearn.preprocessing as prep import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data 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.training_scale = scale network_weights = self._initialize_weights() self.weights = network_weights 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'] ) self.cost = 0.5 * tf.reduce_sum( tf.pow( tf.subtract( self.reconstruction, self.x ), 2 ) ) self.optimizer = optimizer.minimize( self.cost ) init = tf.global_variables_initializer() self.sess = tf.Session() self.sess.run( init ) print "begin to run session..." 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.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 == None: hidden = np.random.normal( size = self.weights['b1'] ) return self.sess.run( self.reconstruction, feed_dict = { self.hidden : hidden } ) def reconstruction( 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'] ) 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_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) ] X_train, X_test =standard_scale( mnist.train.images, mnist.test.images ) n_samples = int( mnist.train.num_examples ) training_epochs = 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.0001 ), 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_xs = get_random_block_from_data( X_train, batch_size ) cost = autoencoder.partial_fit( batch_xs ) avg_cost = cost / n_samples * batch_size if epoch % display_step == 0: print( "epoch : %04d, cost = %.9f" % ( epoch+1, avg_cost ) ) print( "Total cost : ", str( autoencoder.calc_total_cost(X_test)
說明
- 檔案中
mnist
初始化時需要設定資料集的位置 - 隱藏層的節點數越大,訓練後得到的誤差越小,200個節點時,測試誤差為60萬左右,400個節點時,測試誤差為20萬左右
- 自己又加了一個隱藏層,但是效果好像不明顯,隨著訓練次數的變化,訓練誤差呈現出發散的狀態