一、TensorFlow基础

1、tensorflow简介

深度学习,如深度神经网络、卷积神经网络和递归神经网络已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

 深度学习框架:TensorFlow、caffe、Torch、Theano、CNTK

 TensorFlow特点:

① 真正的可移植性:引入各种计算设备的支持包括CPU/GPU/TPU,以及能够很好地运行在移动端,如安卓设备、ios、树莓派等等

② 多语言支持:Tensorflow 有一个合理的c++使用界面,也有一个易用的python使用界面来构建和执行你的graphs,你可以直接写python/c++程序。

③ 高度的灵活性与效率:TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库,能够灵活进行组装图,执行图。随着开发的进展,Tensorflow的效率不算在提高

④ 支持TensorFlow:由谷歌提供支持,谷歌投入了大量精力开发 TensorFlow,它希望TensorFlow 成为机器学习研究人员和开发人员的通用语言

 

新建虚拟环境:conda create -n MyTensorflow1 python=3.7.4

激活虚拟环境:conda activate MyTensorflow1

安装tensorflow: pip install tensorflow==1.13.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

在python命令中import tensorflow报FutureWarning错误:numpy版本过高导致的问题,降低版本即可:pip install numpy==1.16.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

GPU:专门为计算设计。要使用GPU非常简单,一行代码就能指定设备。需要安装tensorflow-gpu版本。

 

2、tensorflow的结构

使用tensorflow实现加法运算

关闭警告:import os

os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 实现一个加法运算
a = tf.constant(5.0)
b = tf.constant(6.0)
print(a, b)
sum1 = tf.add(a, b)
print(sum1)

with tf.Session() as sess:
    print(sess.run(sum1))

tensorflow思想:

把数据封装为tensor张量

operation(op):用来运算的操作节点

图graph:整个程序的结构

会话session:运算程序的图

 

计算密集型:tensorflow

IO密集型:web,scrapy

 

3、图

图默认已经注册,一组表示 tf.Operation计算单位的对象和tf.Tensor表示操作之间流动的数据单元的对象

获取调用:
tf.get_default_graph()  # 默认的这张图,相当于是给程序分配一段内存

graph = tf.get_default_graph()
print(graph)

 

op、sess或者tensor 的graph属性

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 实现一个加法运算
a = tf.constant(5.0)
b = tf.constant(6.0)
sum1 = tf.add(a, b)

graph = tf.get_default_graph()
print(graph)

with tf.Session() as sess:
    print(sess.run(sum1))
    print(a.graph)
    print(sum1.graph)
    print(sess.graph)

 

 

创建图:tf.Graph()

使用新创建的图:

g = tf.Graph()
with g.as_default():
  a = tf.constant(1.0)
  assert c.graph is g

# 创建一张图
g = tf.Graph()
print(g)
# 使用创建的图
with g.as_default():
    c = tf.constant(3.0)
    print(c.graph)

op:只要使用tensorflow的API定义的函数都是OP

tensor:指代数据

 

4、会话

会话的作用:

  • 运行图的结构
  • 分配资源计算
  • 掌握资源(变量生命周期、队列、线程等)会话一旦结束这些资源就不能用了

 

tf.Session():运行TensorFlow操作图的类,使用默认注册的图(可以指定运行图)

# 只能运行一个图结构,否则会报错
# 默认运行默认图,使用graph指定
with tf.Session(graph=g) as sess:
    print(sess.run(c))

 

会话资源:会话可能拥有很多资源,如 tf.Variable,tf.QueueBase和tf.ReaderBase,会话结束后需要进行资源释放

① sess = tf.Session() sess.run(...) sess.close()

② 使用上下文管理器:with tf.Session() as sess: 

            sess.run(...)

 

config=tf.ConfigProto(log_device_placement=True)

with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
    print(sess.run(sum1))
    print(a.graph)
    print(sum1.graph)
    print(sess.graph)

 

交互式:tf.InteractiveSession()

在命令行中使用,避免开启会话运行的麻烦:

 

5、会话的run()方法

run(fetches, feed_dict=None,graph=None)

  • 运行ops和计算tensor
  • 嵌套列表,元组,namedtuple,dict或OrderedDict(重载的运算符也能运行)
  • feed_dict 允许调用者覆盖图中指定张量的值,提供给placeholder使用

不是op不能运行

a = tf.constant(5.0)
b = tf.constant(6.0)
sum1 = tf.add(a, b)

x = 1
y = 2
sum2 = x + y
with tf.Session() as sess:
    print(sess.run([a, b, sum1]))
    print(sess.run(sum2))  # 会报错,不能运行

但是可以重载运算符打印

sum3 = x + a
with tf.Session() as sess:
    print(sess.run(sum3))

 

feed操作

意义:在程序执行的时候,不确定输入的是什么,提前“占个坑”,主要用于实时训练

语法:placeholder提供占位符,run时候通过feed_dict指定参数

# 训练模型
# 实时地提供数据去进行训练
# placeholder是一个占位符
# 第一个参数是类型,第二个是形状(如2行3列)
plt = tf.placeholder(tf.float32, [2, 3])
with tf.Session() as sess:
    # feed_dict是一个字典
    # 填进一个2行3列的结构
    print(sess.run(plt, feed_dict={plt:[[1,2,3], [4,5,6]]}))

 

 可以指定为None

plt = tf.placeholder(tf.float32, [None, 3])
print(plt)
with tf.Session() as sess:
    # 填进一个任意行3列的结构
    print(sess.run(plt, feed_dict={plt:[[1,2,3], [4,5,6], [7,8,9]]}))

 

返回值异常

  • RuntimeError:如果Session处于无效状态(例如已关闭)。
  • TypeError:如果fetches或feed_dict键是不合适的类型。
  • ValueError:如果fetches或feed_dict键无效或引用 Tensor不存在。

 

6、张量的类型与属性 

Tensorflow基本的数据格式:一个类型化的N维度数组(tf.Tensor)

三部分:名字,形状,数据类型

张量的阶:

 

 张量的数据类型:

 

 张量属性:

graph 张量所属的默认图

op 张量的操作名

name 张量的字符串描述

shape 张量形状

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

a = tf.constant(11.0)
b = tf.constant(2.0)
sum = tf.add(a, b)
pl = tf.placeholder(tf.float32, [2,3])

with tf.Session() as sess:
    print(sess.run(sum))
    print(a.graph) # 所属的图
    print(a.name) # 字符串描述
    print(pl.name) # 字符串描述
    print(a.shape) # 形状
    print(pl.shape) # 形状
    print(sum.eval())
    print("------------")
    print(a.op) # 操作名
    print("------------")

打印出来的形状表示:

0维:()

1维:(5)

2维:(2, 3)(?, 5)

3维:(2,3,5)

 

7、张量的动态形状与静态形状

TensorFlow中,张量具有静态形状和动态形状:区别在于改变时有没有生成一个新的张量数据。

静态形状:

  • 创建一个张量或者由操作推导出一个张量时,初始状态的形状
  • tf.Tensor.get_shape:获取静态形状
  • tf.Tensor.set_shape():更新Tensor对象的静态形状,通常用于在不能直接推断的情况下

动态形状:

  • 一种描述原始张量在执行过程中的一种形状(动态变化)
  • tf.reshape:创建一个具有不同动态形状的新张量

要点:

  • 转换静态形状的时候,1-D到1-D,2-D到2-D,不能跨阶数改变形状
  • 对于已经固定或者设置静态形状的张量/变量,不能再次设置静态形状
  • tf.reshape()动态创建新张量时,元素个数不能不匹配
# 静态形状与动态形状
# 对于静态形状来说,一旦张量形状固定,就不能再次设置,也不能跨维度修改 1D->1D 2D->2D
# 动态形状可以去创建一个新的张量,但是元素个数必须匹配 1D->2D 1D->3D
plt = tf.placeholder(tf.float32, [None, 2])
print(plt)
plt.set_shape([3, 2]) # 不能再次修改
print(plt)
# plt.set_shape([2, 3]) 报错
plt_re = tf.reshape(plt, [2, 3]) # 元素个数要匹配
print(plt_re)
# plt_re = tf.reshape(plt, [4, 2]) 报错

 

8、张量操作--生成张量

z = tf.zeros([3, 2], tf.float32)
o = tf.ones([3, 2], tf.float32)
with tf.Session() as sess:
    print(sess.run([z, o]))

 

# 形状、平均值、标准差、类型
rn = tf.random_normal([2, 3], 1, 1, tf.float32)
with tf.Session() as sess:
    print(sess.run(rn))

 

 正态分布(高斯分布)

 概率密度函数为正态分布的期望值μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布

        

 

9、张量操作--张量变换

c = tf.cast([[1,2,3],[4,5,6]], tf.float32)

 

x = [[1,2,3], [4,5,6]]
y = [[7,8,9], [10,11,12]]
xy1 = tf.concat([x,y], axis=0)
xy2 = tf.concat([x,y], axis=1)
with tf.Session() as sess:
    print(sess.run(xy1))
    print(sess.run(xy2))

0:按行   1:按列

 

提供给tensor运算的数学函数:https://www.tensorflow.org/versions/r1.0/api_guides/python/math_ops

 

10、变量

变量也是一种OP,是一种特殊的张量,能够进行存储持久化,它的值就是张量

tf.Variable(initial_value=None,name=None,trainable=True)

  • 创建一个带值initial_value的新变量

assign(value)

  • 为变量分配一个新值
  • 返回新值

eval(session=None)

  • 计算并返回此变量的值

name属性

  • 表示变量名字

tf.global_variables_initializer()

  • 添加一个初始化所有变量的op
  • 在会话中开启
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

a = tf.constant([1,2,3,4,5])
var = tf.Variable(tf.random_normal([2,3], mean=0.0, stddev=1.0))
print(a, var)
# 变量必须做显式的初始化
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    # 必须运行初始化op
    sess.run(init_op)
    print(sess.run([a, var]))

变量能够持久化保存,而普通的张量op是不行的。

变量op必需要在会话中初始化。

 

11、可视化学习tensorboard

程序图结构---序列化文件--->events文件---tensorboard--->web界面

数据序列化:events文件

  • TensorBoard 通过读取 TensorFlow 的事件文件来运行
  • tf.summary.FileWriter('/tmp/tensorflow/summary/test/', graph=default_graph)
  • 返回filewriter,写入事件文件到指定目录(最好用绝对路径),以提供给tensorboard使用

开启:

  • tensorboard --logdir=/tmp/tensorflow/summary/test/
  • 一般浏览器打开为127.0.0.1:6006
  • 注:修改程序后,再保存一遍会有新的事件文件,打开默认为最新
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

a = tf.constant(3.0)
b = tf.constant(4.0)
c = tf.add(a, b)
var = tf.Variable(tf.random_normal([2,3], mean=0.0, stddev=1.0))
# 变量必须做显式的初始化
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    # 必须运行初始化op
    sess.run(init_op)
    # 把指定的图结构写入事件文件
    file_writer = tf.summary.FileWriter("./summary/", graph=sess.graph)
    print(sess.run([c, var]))

activate MyTensorflow1

tensorboard --logdir="C:\Users\yzz\PycharmProjects\ml02\summary"

 

name参数的作用:在tensorboard使用时显示名字,可以让相同op名字的进行区分。

 

12、线性回归案例

线性回归步骤:

① 准备好1个特征值1个目标值,100个样本:y = 0.7x + 0.8

② 建立模型:随机初始化准备1个权重w 1个偏置b:y_predict = xw + b (模型参数必须用变量定义)

③ 求损失函数:均方误差 loss = (y1-y1`)^2 + ... + (y100-y100`)^2  / 100

④ 优化:梯度下降减少损失:指定学习率

 

用到的API:

矩阵运算 tf.matmul(x, w)

平方 tf.square(error)

均值 tf.reduce_mean(error)

梯度下降优化 tf.train.GradientDescentOptimizer(learning_rate)

  • learning_rate:学习率,一般为0~1,2,3,5,7...100
  • minimize(loss):最小化损失
  • 返回:梯度下降op
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


def mylinearregression():
    """
    自实现一个线性回归预测
    :return: None
    """
    # 1 准备数据 x[100, 1] y[100]
    x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
    y_true = tf.matmul(x, [[0.7]]) + 0.8  # 矩阵相乘必须定义二维的才是个矩阵
    # 2 建立线性回归模型 权重1 偏置1
    # 随机给一个权重和偏置的值,去计算损失,再在当前状态下优化
    # 用变量定义才能优化,同样权重要定义二维的
    weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
    bias = tf.Variable(0.0, name="b")
    y_predict = tf.matmul(x, weight) + bias
    # 3 建立损失函数,均方误差
    # 求误差平方,再求平均值
    loss = tf.reduce_mean(tf.square(y_true-y_predict))
    # 4 梯度下降优化损失
    train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 变量必须做显式的初始化,因此需要定义一个初始化op
    init_op = tf.global_variables_initializer()
    # 通过会话运行程序
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)
        # 打印最先随机初始化的变量权重和偏置,weight和bias是op,必须运行
        print("随机初始化的参数权重为:%f  偏置为:%f" % (weight.eval(), bias.eval()))
        # 运行优化,循环训练
        for i in range(300):
            sess.run(train_op)
            print("第%i次优化的参数权重为:%f  偏置为:%f" % (i, weight.eval(), bias.eval()))
    return None


if __name__ == "__main__":
    mylinearregression()

变量有一个trainable参数,如果设置为False,在优化过程中值不会改变。

bias = tf.Variable(0.0, name="b", trainable=False)

梯度爆炸/梯度消失:

学习率过大,导致权重的值变得非常大,以至于溢出,在一定次数后变成NaN值;

如何解决梯度爆炸(深度神经网络如RNN中更容易出现):

① 调整学习率

② 重新设计网络

③ 使用梯度截断(在训练过程中检查和限制梯度的大小)

④ 使用激活函数

 

13、变量作用域

tf.variable_scope(<scope_name>)创建指定名字的变量作用域

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


def mylinearregression():
    """
    自实现一个线性回归预测
    :return: None
    """
    # 1 准备数据 x[100, 1] y[100]
    with tf.variable_scope("data"):
        x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
        y_true = tf.matmul(x, [[0.7]]) + 0.8  # 矩阵相乘必须定义二维的才是个矩阵
    # 2 建立线性回归模型 权重1 偏置1
    with tf.variable_scope("model"):
        # 随机给一个权重和偏置的值,去计算损失,再在当前状态下优化
        # 用变量定义才能优化,同样权重要定义二维的
        weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
        bias = tf.Variable(0.0, name="b")
        y_predict = tf.matmul(x, weight) + bias
    # 3 建立损失函数,均方误差
    with tf.variable_scope("loss"):
        # 求误差平方,再求平均值
        loss = tf.reduce_mean(tf.square(y_true-y_predict))
    # 4 梯度下降优化损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 变量必须做显式的初始化,因此需要定义一个初始化op
    init_op = tf.global_variables_initializer()
    # 通过会话运行程序
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)
        # 打印最先随机初始化的变量权重和偏置,weight和bias是op,必须运行
        print("随机初始化的参数权重为:%f  偏置为:%f" % (weight.eval(), bias.eval()))
        # 建立事件文件
        tf.summary.FileWriter("./summary/", graph=sess.graph)
        # 运行优化,循环训练
        for i in range(300):
            sess.run(train_op)
            print("第%i次优化的参数权重为:%f  偏置为:%f" % (i, weight.eval(), bias.eval()))
    return None


if __name__ == "__main__":
    mylinearregression()

变量作用域使得代码和图看起来更简洁清晰

可以嵌套使用变量作用域

 

给变量取相同的name会出现:

14、增加变量显示

目的:观察模型的参数、损失值等变量值的变化

① 收集变量

  • tf.summary.scalar(name=’’,tensor) 收集对于损失函数和准确率等单值变量,name为变量的名字,tensor为值
  • tf.summary.histogram(name=‘’,tensor) 收集高维度的变量参数
  • tf.summary.image(name=‘’,tensor) 收集输入的图片张量能显示图片

② 合并变量写入事件文件

  • merged = tf.summary.merge_all()
  • 运行合并:summary = sess.run(merged),每次迭代都需运行
  • 添加:FileWriter.add_summary(summary,i), i表示第几次的值
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


def mylinearregression():
    """
    自实现一个线性回归预测
    :return: None
    """
    # 1 准备数据 x[100, 1] y[100]
    with tf.variable_scope("data"):
        x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
        y_true = tf.matmul(x, [[0.7]]) + 0.8  # 矩阵相乘必须定义二维的才是个矩阵
    # 2 建立线性回归模型 权重1 偏置1
    with tf.variable_scope("model"):
        weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
        bias = tf.Variable(0.0, name="b")
        y_predict = tf.matmul(x, weight) + bias
    # 3 建立损失函数,均方误差
    with tf.variable_scope("loss"):
        loss = tf.reduce_mean(tf.square(y_true-y_predict))
    # 4 梯度下降优化损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 添加权重参数、损失值等在tensorboard观察的情况
    # (1) 收集tensor,一般写在会话之前
    tf.summary.scalar("losses", loss)
    tf.summary.histogram("weights", weight)
    # (2) 合并变量写入事件文件
    # 定义合并tensor的op
    merged = tf.summary.merge_all()

    # 变量必须做显式的初始化,因此需要定义一个初始化op
    init_op = tf.global_variables_initializer()
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)
        # 打印最先随机初始化的变量权重和偏置,weight和bias是op,必须运行
        print("随机初始化的参数权重为:%f  偏置为:%f" % (weight.eval(), bias.eval()))
        # 建立事件文件
        filewriter = tf.summary.FileWriter("./summary/", graph=sess.graph)
        # 运行优化,循环训练
        for i in range(300):
            sess.run(train_op)

            # (3) 运行合并的tensor
            summary = sess.run(merged)
            # 写入
            filewriter.add_summary(summary, i)

            print("第%i次优化的参数权重为:%f  偏置为:%f" % (i, weight.eval(), bias.eval()))

    return None


if __name__ == "__main__":
    mylinearregression()

 

15、模型的保存与加载

保存模型的文件称为检查点文件:checkpoint文件

tf.train.Saver(var_list=None,max_to_keep=5)

  • var_list:指定将要保存和还原的变量。它可以作为一个dict或一个列表传递.
  • max_to_keep:指示要保留的最近检查点文件的最大数量。
  • 创建新文件时,会删除较旧的文件。
  • 如果无或0,则保留所有检查点文件。默认为5(即保留最新的5个检查点文件)

saver.save(sess, '/tmp/ckpt/test/model') 

  • 位置参数要写保存到哪个写文件名(summary摘要文件只需要写保存到哪个目录)
  • 因为sess包含所有的资源,所以要保存sess

saver.restore(sess, '/tmp/ckpt/test/model')

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


def mylinearregression():
    """
    自实现一个线性回归预测
    :return: None
    """
    # 1 准备数据 x[100, 1] y[100]
    with tf.variable_scope("data"):
        x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
        y_true = tf.matmul(x, [[0.7]]) + 0.8  # 矩阵相乘必须定义二维的才是个矩阵
    # 2 建立线性回归模型 权重1 偏置1
    with tf.variable_scope("model"):
        weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
        bias = tf.Variable(0.0, name="b")
        y_predict = tf.matmul(x, weight) + bias
    # 3 建立损失函数,均方误差
    with tf.variable_scope("loss"):
        loss = tf.reduce_mean(tf.square(y_true-y_predict))
    # 4 梯度下降优化损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 收集tensor,一般写在会话之前
    tf.summary.scalar("losses", loss)
    tf.summary.histogram("weights", weight)
    # 定义合并变量的op写入事件文件
    merged = tf.summary.merge_all()

    # 变量必须做显式的初始化,因此需要定义一个初始化op
    init_op = tf.global_variables_initializer()

    # 定义一个保存模型的实例
    saver = tf.train.Saver()

    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)
        # 打印最先随机初始化的变量权重和偏置,weight和bias是op,必须运行
        print("随机初始化的参数权重为:%f  偏置为:%f" % (weight.eval(), bias.eval()))
        # 建立事件文件
        filewriter = tf.summary.FileWriter("./summary/", graph=sess.graph)

        # 加载模型,覆盖模型当中随机定义的参数,从上次训练的参数结果开始
        if os.path.exists("./ckpt/checkpoint"):
            saver.restore(sess, "./ckpt/model")

        # 运行优化,循环训练
        for i in range(500):
            sess.run(train_op)
            summary = sess.run(merged)
            filewriter.add_summary(summary, i)
            print("第%i次优化的参数权重为:%f  偏置为:%f" % (i, weight.eval(), bias.eval()))

        # 模型的保存
        saver.save(sess, "./ckpt/model")

    return None


if __name__ == "__main__":
    mylinearregression()

第二次运行就会从上一次的参数权重和偏置开始

 

16、自定义命令行参数

tf.app.flags.,在flags有一个FLAGS标志,它在程序中可以调用到我们前面具体定义的flag_name

通过tf.app.run()启动main(argv)函数

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# (名字,默认值,说明)
tf.app.flags.DEFINE_integer("max_step", 100, "模型训练的步数")
tf.app.flags.DEFINE_string("model_dir", " ", "模型加载的路径")
# 定义获取命令行参数名字
FLAGS = tf.app.flags.FLAGS

def mylinearregression():
    """
    自实现一个线性回归预测
    :return: None
    """
    # 1 准备数据 x[100, 1] y[100]
    with tf.variable_scope("data"):
        x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
        y_true = tf.matmul(x, [[0.7]]) + 0.8  # 矩阵相乘必须定义二维的才是个矩阵
    # 2 建立线性回归模型 权重1 偏置1
    with tf.variable_scope("model"):
        weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
        bias = tf.Variable(0.0, name="b")
        y_predict = tf.matmul(x, weight) + bias
    # 3 建立损失函数,均方误差
    with tf.variable_scope("loss"):
        loss = tf.reduce_mean(tf.square(y_true-y_predict))
    # 4 梯度下降优化损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 收集tensor,一般写在会话之前
    tf.summary.scalar("losses", loss)
    tf.summary.histogram("weights", weight)
    # 定义合并变量的op写入事件文件
    merged = tf.summary.merge_all()

    # 变量必须做显式的初始化,因此需要定义一个初始化op
    init_op = tf.global_variables_initializer()

    # 定义一个保存模型的实例
    saver = tf.train.Saver()

    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)
        # 打印最先随机初始化的变量权重和偏置,weight和bias是op,必须运行
        print("随机初始化的参数权重为:%f  偏置为:%f" % (weight.eval(), bias.eval()))
        # 建立事件文件
        filewriter = tf.summary.FileWriter("./summary/", graph=sess.graph)

        # 加载模型,覆盖模型当中随机定义的参数,从上次训练的参数结果开始
        if os.path.exists("./ckpt/checkpoint"):
            saver.restore(sess, FLAGS.model_dir)

        # 运行优化,循环训练
        for i in range(FLAGS.max_step):
            sess.run(train_op)
            summary = sess.run(merged)
            filewriter.add_summary(summary, i)
            print("第%i次优化的参数权重为:%f  偏置为:%f" % (i, weight.eval(), bias.eval()))

        # 模型的保存
        saver.save(sess, FLAGS.model_dir)

    return None


if __name__ == "__main__":
    mylinearregression()

在命令行中运行:python d04_线性回归.py --max_step=200 --model_dir="./ckpt/model"

 

posted on 2020-02-08 11:03  三分天涯  阅读(313)  评论(0编辑  收藏  举报