深度学习笔记(二):基于tensorflow gpu版本的深度神经网络程序总览

来源:互联网 发布:万网域名后台 编辑:程序博客网 时间:2024/05/21 15:45

在第一篇笔记深度学习笔记(一):基于numpy的深度神经网络程序总览之后,又用tensorflow的gpu版本实现了一遍,果然封装很好,写起来很舒服,速度也快很多,100次epoch分分钟就结束了,效果和第一篇笔记中基于numpy的效果差不多,以下是代码,比基于numpy的代码少了一多半,后续笔记就开始记录程序结构和算法步骤了,有时间就更新。

源代码和数据:点击打开链接

# -*- coding: utf-8 -*-"""Created on Sat Sep 30 18:45:47 2017@author: 董玮"""import argparseimport timeimport numpy as npimport matplotlib.pyplot as pltfrom tensorflow.examples.tutorials.mnist import input_dataimport tensorflow as tffrom tensorflow.python.framework import ops"""类型:抽象类说明:规则化数据接口,一般用于数据预处理中。"""class interface_normalize_data(object):        """    类型:公有成员变量    说明:规则化数据过程中,定义一个无穷小精度,用来防止数据计算中的非法操作。    """    epsilon = 1e-8        """    类型:抽象公有成员函数    说明:用来规则化数据。    参数:        data -- 待处理的数据。    返回值:        data -- 处理后的数据。    """    def normalize_data(self, data):                pass"""类型:实体类,继承自抽象类interface_normalize_data说明:用于中心化数据,使数据中心在坐标原点上。"""class mean_normalization(interface_normalize_data):                       def normalize_data(self, data):        #计算数据每个维度的期望,并用每一条数据减去期望。        center = data - tf.reduce_mean(data, axis = 0, keep_dims = True)        return center"""类型:实体类,继承自抽象类interface_normalize_data说明:用于中心化数据,并除以方差,使数据中心在坐标原点上,并且使每个维度之间的跨度相似。"""  class variance_normalization(interface_normalize_data):        def normalize_data(self, data):        center = data - tf.reduce_mean(data, axis = 0, keep_dims = True)        #计算数据每个维度的方差。        variance = tf.reduce_mean(tf.square(center), axis = 0, keep_dims = True)        #除以方差并在除数上加上无穷小精度。        vscore = center / (variance + self.epsilon)        return vscore"""类型:实体类,继承自抽象类interface_normalize_data说明:用于Z-Score统计,与上述实体类的区别是除以标准差而不是方差。"""     class zscore_normalization(interface_normalize_data):        def normalize_data(self, data):        center = data - tf.reduce_mean(data, axis = 0, keep_dims = True)        variance = tf.reduce_mean(tf.square(center), axis = 0, keep_dims = True)        #除以标准差并在除数上加上无穷小精度。        zscore = center / tf.sqrt(variance + self.epsilon)        return zscore    """   类型:抽象类说明:神经网络初始化参数接口。"""class interface_initialize_parameters(object):        """    类型:公有成员变量    说明:定义输入层、隐藏层、输出层每层的神经元个数。    """    structure = None        """    类型:公有成员变量    说明:定义规则化功能。    """    regularizer = None        """    类型:公有成员变量    说明:随机种子,用来产生随机数。    """    seed = 1        """    类型:抽象公有成员函数    说明:用来初始化参数。    """    def initialize_parameters(self):                pass"""类型:实体类说明:标准的x-avier参数初始化,继承自抽象类interface_initialize_parameters"""class xavier_initialize_parameters(interface_initialize_parameters):        """    类型:公有成员函数    说明:用来初始化参数。    参数:无    返回值:        parameters -- 返回初始化后的参数。    """    def initialize_parameters(self):                tf.set_random_seed(self.seed)        parameters = {}                #初始化两类参数,一种是W1、W2、W3……,另一种是b1、b2、b3……。其中数字代表层数。        #W的维度为(当前层神经元数,前一层神经元数)。b的维度为(当前层神经元数,1)。        for l in range(1, len(self.structure)):            parameters["W" + str(l)] = tf.get_variable("W" + str(l), [self.structure[l-1], self.structure[l]],                       initializer = tf.contrib.layers.xavier_initializer(self.seed), regularizer = self.regularizer)                        parameters["b" + str(l)] = tf.get_variable("b" + str(l), [1, self.structure[l]],                       initializer = tf.zeros_initializer())                    return parameters"""类型:实体类说明:具有batch normalization功能的x-avier参数初始化,继承自抽象类interface_initialize_parameters"""    class xavier_initialize_parameters_BN(interface_initialize_parameters):        """    类型:公有成员函数    说明:用来初始化参数。    参数:无    返回值:        parameters -- 返回初始化后的参数。    """    def initialize_parameters(self):                tf.set_random_seed(self.seed)        parameters = {}                #因batch normalization需要,初始化三类参数,W1、W2、W3……,gamma1、gamma2、gamma3……,beta1、beta2、beta3……。其中数字代表层数。        #W的维度为(当前层神经元数,前一层神经元数)。gamma与beta的维度均为(当前层神经元数,1)。        for l in range(1, len(self.structure)):            parameters["W" + str(l)] = tf.get_variable("W" + str(l), [self.structure[l-1], self.structure[l]],                       initializer = tf.contrib.layers.xavier_initializer(self.seed), regularizer = self.regularizer)            parameters["gamma" + str(l)] = tf.get_variable("gamma" + str(l), [1, self.structure[l]],                       initializer = tf.ones_initializer())            parameters["beta" + str(l)] = tf.get_variable("beta" + str(l), [1, self.structure[l]],                       initializer = tf.zeros_initializer())                    return parameters"""类型:抽象类说明:定义向前向后算法。"""class interface_propagation(object):        """    类型:公有成员变量    说明:规则化数据过程中,定义一个无穷小精度,用来防止数据计算中的非法操作。    """    epsilon = 1e-8        """    类型:公有成员变量    说明:是否进行dropout规则化操作。    """    is_dropout = False        """    类型:公有成员变量    说明:如果is_dropout为真,那么此变量存储每一层保持神经元个数的概率。    """    keep_prob = 1.        """    类型:公有成员变量    说明:定义激活函数。    """    act_func = None    """    类型:抽象公有函数    说明:向前算法。    参数:        training_set -- 训练集。        training_label -- 训练标签。        parameters -- 训练参数。    """    def forward_propagation(self, training_set, training_label, parameters):                pass"""类型:具体类说明:标准的向前算法,继承自interface_propagation。"""  class propagation_standard(interface_propagation):    def forward_propagation(self, training_set, training_label, parameters):                if(len(parameters) < 2):            return None                #向前算法        A = training_set                layer_number = len(parameters) // 2        for l in range(1, layer_number):            Z = tf.matmul(A, parameters["W"+str(l)]) + parameters["b" + str(l)]            #激活函数            A = self.act_func(Z)                        #添加dropout正则化功能            if(self.is_dropout == True):                A = tf.nn.dropout(A, self.keep_prob)            Z = tf.matmul(A, parameters["W"+str(layer_number)]) + parameters["b" + str(layer_number)]                #计算代价函数        cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = training_label, logits = Z)) + tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))                return cross_entropy, Z"""类型:具体类说明:带有Batch normalization的向前算法,继承自interface_propagation。"""     class propagation_BN(interface_propagation):        def forward_propagation(self, training_set, training_label, parameters):                if(len(parameters) < 2):            return None                #向前算法        A = training_set                #注意,因为Batch normalization有三个学习参数,这里要除以3取整。        layer_number = len(parameters) // 3        for l in range(1, layer_number):            Z = tf.matmul(A, parameters["W"+str(l)])            #向前算法中的Batch normalization步骤。            Zmean = tf.reduce_mean(Z, axis = 0, keep_dims = True)            Zcenter = Z - Zmean            Zvariance = tf.reduce_mean(tf.square(Zcenter), axis = 0, keep_dims = True)            Ztilde = Zcenter / tf.sqrt(Zvariance + self.epsilon)            Z = tf.multiply(Ztilde, parameters["gamma" + str(l)]) + parameters["beta" + str(l)]                        #激活函数            A = self.act_func(Z)            if(self.is_dropout == True):                A = tf.nn.dropout(A, self.keep_prob)                #向前算法中输出层的Batch normalization步骤。        Z = tf.matmul(A, parameters["W"+str(layer_number)])        Zmean = tf.reduce_mean(Z, axis = 0, keep_dims = True)        Zcenter = Z - Zmean        Zvariance = tf.reduce_mean(tf.square(Zcenter), axis = 0, keep_dims = True)        Ztilde = Zcenter / tf.sqrt(Zvariance + self.epsilon)        Z = tf.multiply(Ztilde, parameters["gamma" + str(layer_number)]) + parameters["beta" + str(layer_number)]                #计算代价函数        cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = training_label, logits = Z)) + tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))                return cross_entropy, Z"""类型:抽象类说明:定义一个工厂类,用来生产学习模型过程中所需要的模块。"""class interface_factory(object):        """    类型:公有成员变量    说明:数据预处理规则化模块。    """    normalizer = None        """    类型:公有成员变量    说明:学习参数初始化模块。    """    initializer = None        """    类型:公有成员变量    说明:向前学习算法模块。    """    propagator = None        """    类型:公有成员变量    说明:规则化数据过程中,定义一个无穷小精度,用来防止数据计算中的非法操作。    """    epsilon = 1e-8        """    类型:公有成员变量    说明:定义优化算法的学习率。    """    learning_rate = 1e-3        """    类型:公有成员变量    说明:Batch normalization超参数。    """    beta1 = 0.9        """    类型:公有成员变量    说明:Batch normalization超参数。    """    beta2 = 0.999        """    类型:公有成员变量    说明:数据批量优化算法说需要的batch大小,即每次训练从训练集里抽样的个数。    """    minibatch_size = 512        """    类型:公有成员变量    说明:epoch个数,即需要训练整个数据集多少遍。    """    num_epochs = 100        """    类型:公有成员变量    说明:定义每几步衰减一次。    """    epoch_step = 5        """    类型:公有成员变量    说明:衰退比率。    """    k = 0.09        """    类型:抽象公有成员函数    说明:创建一个工厂,该工厂生产训练和测试数据过程中所需要的模块。    """    def create_workpiece(self, *arguments):                pass"""类型:具体类说明:工厂版本v1,不带Batch normalization功能,激活函数为relu,最后一层激活函数为softmax,代价函数用的是交叉熵损失函数,优化算法为adam,学习率为指数衰减。"""class factory_v1(interface_factory):        """    类型:公有成员函数    说明:创建一个工厂,该工厂生产训练和测试数据过程中所需要的模块。    参数:        arguments[0] -- 数值计算精度 - epsilon        arguments[1] -- 网络结构 - structure        arguments[2] -- 随机种子 - seed        arguments[3] -- 学习率 - learning_rate        arguments[4] -- adam参数 - beta1        arguments[5] -- adam参数 - beta2        arguments[6] -- batch的大小 - minibatch_size        arguments[7] -- epoch个数 - num_epochs        arguments[8] -- 衰减步数 - epoch_step        arguments[9] -- 衰减率 - k    """    def create_workpiece(self, *arguments):                self.epsilon = arguments[0]                self.normalizer = zscore_normalization()        self.normalizer.epsilon = self.epsilon                structure = arguments[1]        seed = arguments[2]                self.initializer = xavier_initialize_parameters()        self.initializer.structure = structure        self.initializer.seed = seed                self.propagator = propagation_standard()        self.propagator.epsilon = self.epsilon        self.propagator.act_func = tf.nn.relu                self.learning_rate = arguments[3]        self.beta1 = arguments[4]        self.beta2 = arguments[5]                self.minibatch_size = arguments[6]        self.num_epochs = arguments[7]                self.epoch_step = arguments[8]        self.k = arguments[9]                return self"""类型:具体类说明:工厂版本v3,带Batch normalization功能,带dropout规则化,激活函数为relu,最后一层激活函数为softmax,代价函数用的是交叉熵损失函数,优化算法为adam,学习率为指数衰减。"""     class factory_v2(interface_factory):        """    类型:公有成员函数    说明:创建一个工厂,该工厂生产训练和测试数据过程中所需要的模块。    参数:        arguments[0] -- 数值计算精度 - epsilon        arguments[1] -- 网络结构 - structure        arguments[2] -- 随机种子 - seed        arguments[3] -- 学习率 - learning_rate        arguments[4] -- adam参数 - beta1        arguments[5] -- adam参数 - beta2        arguments[6] -- batch的大小 - minibatch_size        arguments[7] -- epoch个数 - num_epochs        arguments[8] -- 衰减步数 - epoch_step        arguments[9] -- 衰减率 - k        arguments[10] -- 是否进行dropout步骤 - is_dropout        arguments[11] -- dropout保持概率 - keep_prob    """    def create_workpiece(self, *arguments):                self.epsilon = arguments[0]        #tf_epsilon = tf.Variable(epsilon)                self.normalizer = zscore_normalization()        self.normalizer.epsilon = self.epsilon                structure = arguments[1]        seed = arguments[2]                self.initializer = xavier_initialize_parameters_BN()        self.initializer.structure = structure        self.initializer.seed = seed                self.propagator = propagation_BN()        self.propagator.epsilon = self.epsilon        self.propagator.act_func = tf.nn.relu                self.learning_rate = arguments[3]        self.beta1 = arguments[4]        self.beta2 = arguments[5]                self.minibatch_size = arguments[6]        self.num_epochs = arguments[7]                self.epoch_step = arguments[8]        self.k = arguments[9]                is_dropout = arguments[10]        keep_prob = arguments[11]                self.propagator.is_dropout = is_dropout        self.propagator.keep_prob = keep_prob                return self"""类型:抽象类说明:定义一个工厂类,用来生产学习模型过程中所需要的模块。"""   class interface_train_model(object):        """    类型:公有成员变量    说明:学习参数。    """    parameters = None        """    类型:公有成员变量    说明:训练集。    """    training_set = None        """    类型:公有成员变量    说明:训练标签。    """    training_label = None        """    类型:公有成员变量    说明:验证集。    """    validation_set = None        """    类型:公有成员变量    说明:验证标签。    """    validation_label = None        """    类型:公有成员变量    说明:测试集。    """    test_set = None        """    类型:公有成员变量    说明:测试标签。    """    test_label = None        """    类型:公有成员变量    说明:工厂对象。    """    factory = None        """    类型:抽象公有成员函数    说明:训练模型方法。    """    def training_model(self, *arguments):                pass"""类型:具体类说明:定义深度神经网络。"""class deep_neural_networks(interface_train_model):    """    类型:初始化函数    说明:初始化工厂对象。    """    def __init__(self, factory):        self.factory = factory        def training_model(self, *arguments):                #重置图计算步骤,恢复默认状态。        ops.reset_default_graph()                #定义占位符,用来输入数据        X = tf.placeholder(tf.float32, shape=(None, self.training_set.shape[1]))        Y = tf.placeholder(tf.float32, shape=(None, self.training_label.shape[1]))                #定义深度神经网络结构        self.factory.initializer.structure = np.append(np.array([self.training_set.shape[1]]), self.factory.initializer.structure)        num_minibatches = int(self.training_set.shape[0] / self.factory.minibatch_size) + 1                #定义数据预处理步骤        if(self.factory.normalizer != None):            normalize_result = self.factory.normalizer.normalize_data(X)                #定义学习参数及超参数初始化步骤        self.parameters = self.factory.initializer.initialize_parameters()        seed = self.factory.initializer.seed                #定义向前算法步骤        cross_entropy, ZL = self.factory.propagator.forward_propagation(X, Y, self.parameters)                global_step = tf.Variable(0, trainable = False)                #定义学习率衰减        learning_rate_target = tf.train.natural_exp_decay(self.factory.learning_rate, global_step, self.factory.epoch_step * self.training_set.shape[0], self.factory.k, staircase=True)                #定义优化算法        optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate_target, beta1 = self.factory.beta1, beta2 = self.factory.beta2, epsilon = self.factory.epsilon).minimize(cross_entropy, global_step = global_step)        #定义计算精度        correct_prediction = tf.equal(tf.argmax(ZL, 1), tf.argmax(Y, 1))        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))                costs = []        training_accuracies = []        validation_accuracies = []                #在验证集上表现最好的学习参数        best_parameters = {}        #最好学习参数时,训练集的精度        best_training_acc = 0.        #最好学习参数时,验证集的精度        best_validation_acc = 0.                    init = tf.global_variables_initializer()                #执行计算图        with tf.Session() as sess:                        start = time.clock()            sess.run(init)                        #数据在计算图中的预处理步骤            if(self.factory.normalizer != None):                self.training_set = sess.run(normalize_result, feed_dict={X: self.training_set})                self.validation_set = sess.run(normalize_result, feed_dict={X: self.validation_set})                        #epoch学习过程            for iter_epoch in range(1, self.factory.num_epochs + 1):                cost = 0                                #minibatch学习过程                for iter_batch in range(1, num_minibatches + 1):                    seed += 1                    (minibatch_X, minibatch_Y) = self.__random_mini_batches(self.factory.minibatch_size, seed)                    _ , minibatch_cost = sess.run([optimizer, cross_entropy], feed_dict={X: minibatch_X, Y: minibatch_Y})                    cost += minibatch_cost                                cost /= num_minibatches                costs.append(cost)                training_acc = accuracy.eval(feed_dict={X: self.training_set, Y: self.training_label})                training_accuracies.append(training_acc)                validation_acc = accuracy.eval(feed_dict={X: self.validation_set, Y: self.validation_label})                validation_accuracies.append(validation_acc)                                if(validation_acc > best_validation_acc):                    best_training_acc = training_acc                    best_validation_acc = validation_acc                    best_parameters = sess.run(self.parameters)                                print ("Cost after epoch %i: %f" % (iter_epoch, cost))                print ("Training accuracy after epoch %i: %f" % (iter_epoch, training_acc))                print ("Validation accuracy after epoch %i: %f" % (iter_epoch, validation_acc))                            end = time.clock()                        self.factory.initializer.seed = seed            self.parameters = best_parameters                            plt.plot(np.squeeze(costs))            plt.ylabel('cost')            plt.xlabel('epochs')            plt.title("Learning rate of Start step =" + str(self.factory.learning_rate))            plt.show()                        plt.plot(np.squeeze(training_accuracies))            plt.ylabel('training accracy')            plt.xlabel('epochs')            plt.title("Learning rate of Start step =" + str(self.factory.learning_rate))            plt.show()                        plt.plot(np.squeeze(validation_accuracies))            plt.ylabel('validation accracy')            plt.xlabel('epochs')            plt.title("Learning rate of Start step =" + str(self.factory.learning_rate))            plt.show()                        print ("Accuracy of total Training set: %f%%" % (best_training_acc * 100))            print ("Accuracy of total Validation set: %f%%" % (best_validation_acc * 100))            print ("Training of total Time: %f Minutes" % ((end - start) / 60))        """    从训练数据集和标签集中随机抽取minibatch。    参数:        X_train -- 训练数据集。        Y_train -- 训练标签集。        minibatch_size -- minibatch尺寸。        seed -- 随机种子。    返回值:        元组 -- 返回一个minibatch,包括训练数据和对应的标签数据。    """    def __random_mini_batches(self, minibatch_size, seed):                np.random.seed(seed)        shuffle_array = np.random.randint(0, self.training_set.shape[0], minibatch_size)        return (self.training_set[shuffle_array, :], self.training_label[shuffle_array, :])   def main():        parser = argparse.ArgumentParser()    parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data',                        help='Directory for storing input data')    FLAGS, unparsed = parser.parse_known_args()    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)        struct = [512, 256, 128, 64, 32, 16, 10]    factory = factory_v2()    factory.create_workpiece(1e-8, struct, 1, 1e-3, 0.9, 0.999, 512, 100, 5, 0.009, False, 0.8)        dnn = deep_neural_networks(factory)    dnn.training_set = mnist.train.images    dnn.training_label = mnist.train.labels    dnn.validation_set = mnist.test.images    dnn.validation_label = mnist.test.labels    dnn.training_model()main()

运行结果:


阅读全文
1 0
原创粉丝点击