zoukankan      html  css  js  c++  java
  • tensorflow 梯度下降以及summary

    # 保证脚本与Python3兼容
    from __future__ import print_function
    
    import os
    
    import tensorflow as tf
    import numpy as np
    from utils import createSummaryWriter, generateLinearData, createLinearModel    #导入utils
    
    
    def gradientDescent(X, Y, model, learningRate=0.01, maxIter=10000, tol=1.e-6):
        """
        利用梯度下降法训练模型。
    
        参数
        ----
        X : np.array, 自变量数据
    
        Y : np.array, 因变量数据
    
        model : dict, 里面包含模型的参数,损失函数,自变量,应变量。
        """
        # 确定最优化算法
        method = tf.train.GradientDescentOptimizer(learning_rate=learningRate)
        optimizer = method.minimize(model["loss_function"])
        # 增加日志
        tf.summary.scalar("loss_function", model["loss_function"])
        tf.summary.histogram("params", model["model_params"])
        tf.summary.scalar("first_param", tf.reduce_mean(model["model_params"][0]))
        tf.summary.scalar("last_param", tf.reduce_mean(model["model_params"][-1]))
        summary = tf.summary.merge_all()
        # 在程序运行结束之后,运行如下命令,查看日志
        # tensorboard --logdir logs/
        # Windows下的存储路径与Linux并不相同
        if os.name == "nt":
            summaryWriter = createSummaryWriter("logs\gradient_descent")
        else:
            summaryWriter = createSummaryWriter("logs/gradient_descent")
        # tensorflow开始运行
        sess = tf.Session()
        # 产生初始参数
        init = tf.global_variables_initializer()
        # 用之前产生的初始参数初始化模型
        sess.run(init)
        # 迭代梯度下降法
        step = 0
        prevLoss = np.inf
        diff = np.inf
        # 当损失函数的变动小于阈值或达到最大循环次数,则停止迭代
        while (step < maxIter) & (diff > tol):
            _, summaryStr, loss = sess.run(
                [optimizer, summary, model["loss_function"]],
                feed_dict={model["independent_variable"]: X,
                           model["dependent_variable"]: Y})
            # 将运行细节写入目录
            summaryWriter.add_summary(summaryStr, step)
            # 计算损失函数的变动
            diff = abs(prevLoss - loss)
            prevLoss = loss
            step += 1
        summaryWriter.close()
        # 在Windows下运行此脚本需确保Windows下的命令提示符(cmd)能显示中文
        # 输出最终结果
        print("模型参数:
    %s" % sess.run(model["model_params"]))
        print("迭代次数:%s" % step)
        print("损失函数值:%s" % loss)
    
    
    def run():
        """
        程序入口
        """
        # dimension表示自变量的个数,num表示数据集里数据的个数。
        dimension = 30
        num = 10000
        # 随机产生模型数据
        X, Y = generateLinearData(dimension, num)
        # 定义模型
        model = createLinearModel(dimension)
        # 使用梯度下降法,估计模型参数
        gradientDescent(X, Y, model)
    
    
    if __name__ == "__main__":
        run()

    utils:

    """
    此脚本用于随机生成线性模型数据、定义模型以及其他工具
    """
    
    
    import numpy as np
    import tensorflow as tf
    
    
    def generateLinearData(dimension, num):
        """
        随机产生线性模型数据
    
        参数
        ----
        dimension :int,自变量个数
    
        num :int,数据个数
    
        返回
        ----
        x :np.array,自变量
    
        y :np.array,因变量
        """
        np.random.seed(1024)
        beta = np.array(range(dimension)) + 1
        x = np.random.random((num, dimension))
        epsilon = np.random.random((num, 1))
        # 将被预测值写成矩阵形式,会极大加快速度
        y = x.dot(beta).reshape((-1, 1)) + epsilon
        return x, y
    
    
    def createLinearModel(dimension):
        """
        搭建模型,包括数据中的自变量,应变量和损失函数
    
        参数
        ----
        dimension : int,自变量的个数
    
        返回
        ----
        model :dict,里面包含模型的参数,损失函数,自变量,应变量
        """
        np.random.seed(1024)
        # 定义自变量和应变量
        x = tf.placeholder(tf.float64, shape=[None, dimension], name='x')
        ## 将被预测值写成矩阵形式,会极大加快速度
        y = tf.placeholder(tf.float64, shape=[None, 1], name="y")
        # 定义参数估计值和预测值
        betaPred = tf.Variable(np.random.random([dimension, 1]))
        yPred = tf.matmul(x, betaPred, name="y_pred")
        # 定义损失函数
        loss = tf.reduce_mean(tf.square(yPred - y))
        model = {"loss_function": loss, "independent_variable": x,
            "dependent_variable": y, "prediction": yPred, "model_params": betaPred}
        return model
    
    
    def createSummaryWriter(logPath):
        """
        检查所给路径是否已存在,如果存在删除原有日志。并创建日志写入对象
    
        参数
        ----
        logPath :string,日志存储路径
    
        返回
        ----
        summaryWriter :FileWriter,日志写入器
        """
        if tf.gfile.Exists(logPath):
            tf.gfile.DeleteRecursively(logPath)
        summaryWriter = tf.summary.FileWriter(logPath, graph=tf.get_default_graph())
        return summaryWriter

    (1)对于单个数值型的变量,比如所示函数值,使用scalar函数记录它的信息

    (2)对于矩阵型变量比如模型参数使用histogram函数记录信息。 如果想追踪某个特定参数,需要先将特定参数转化为标量,再用scalar函数记录信息

    (3)summary类定义的操作和其他tensorflow操作一样,只有在Session()对象调用它们时才会真正运行,手工调用效率显然不高,所以使用merge_all函数将他们合并为一个操作。

    (4)为了记录产生的日志,需要创建tf.summary.FileWriter对象,。然后在每次迭代梯度下降法的使用时,将相应的日志写入文件。

  • 相关阅读:
    团队第五次作业评分 项目冲刺
    团队第四次作业评分 系统设计和数据库设计
    随笔
    爬虫
    javascript简单分页
    cookie的存储与取值
    redis的五种数据类型
    什么是反射
    小王同学的随笔
    something just like this---About Me
  • 原文地址:https://www.cnblogs.com/francischeng/p/9736777.html
Copyright © 2011-2022 走看看