系列博客链接:

(一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html

(二)TensorFlow框架之图与TensorBoard:https://www.cnblogs.com/kongweisi/p/11038517.html

(三)TensorFlow框架之会话:https://www.cnblogs.com/kongweisi/p/11038550.html

(四)TensorFlow框架之张量:https://www.cnblogs.com/kongweisi/p/11039237.html

(五)TensorFlow框架之变量OP:https://www.cnblogs.com/kongweisi/p/11039254.html

本文概述:

  • 应用op的name参数实现op的名字修改
  • 应用variable_scope实现图程序作用域的添加
  • 应用scalar或histogram实现张量值的跟踪显示
  • 应用merge_all实现张量值的合并
  • 应用add_summary实现张量值写入文件
  • 应用tf.train.saver实现TensorFlow的模型保存以及加载
  • 应用tf.app.flags实现命令行参数添加和使用
  • 应用reduce_mean、square实现均方误差计算
  • 应用tf.train.GradientDescentOptimizer实现有梯度下降优化器创建
  • 应用minimize函数优化损失
  • 知道梯度爆炸以及常见解决技巧

1、线性回归原理复习

根据数据建立回归模型,w1x1+w2x2+…..+b = y,通过真实值与预测值之间建立误差,使用梯度下降优化得到损失最小对应的权重和偏置。

最终确定模型的权重和偏置参数。最后可以用这些参数进行预测。

2、案例:实现线性回归的训练

2.1 案例确定

  • 假设随机指定100个点,只有一个特征(这里的x,将其都放在100行1列的数组即张量中,便于与后面的w计算)
  • 数据本身的分布为 y = 0.7 * x + 0.8

这里将数据分布的规律确定,是为了使我们训练出的参数跟真实的参数(即0.7和0.8)比较是否训练准确

2.2 API

运算

  • 矩阵运算

    • tf.matmul(x, w)
  • 平方
    • tf.square(error)
  • 均值
    • tf.reduce_mean(error)

梯度下降优化

  • tf.train.GradientDescentOptimizer(learning_rate)

    • 梯度下降优化
    • learning_rate:学习率,一般为0~1之间比较小的值
    • method:
      • minimize(loss)
    • return:梯度下降op

2.3 步骤分析

  • 1、准备数据的特征值和目标值 inputs
  • 2、根据特征值建立线性回归模型(确定参数个数形状) inference
    • 模型的参数必须使用变量OP创建(为了可训练)
  • 3、根据模型得出预测结果,建立损失 loss
  • 4、梯度下降优化器优化损失 sgd_op

2.4 实现完整功能def inputs(self):        


  def inputs(self):
     """
     获取特征值目标值数据数据
:return:
"""
x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8 return x_data, y_true def inference(self, feature):
"""
根据输入数据建立模型
:param feature:
:param label:
:return:
"""
with tf.variable_scope("linea_model"):
# 2、建立回归模型,分析别人的数据的特征数量--->权重数量, 偏置b
# 由于有梯度下降算法优化,所以一开始给随机的参数,权重和偏置
# 被优化的参数,必须得使用变量op去定义
# 变量初始化权重和偏置
# weight 2维[1, 1],输入的x是[100, 1]的列向量 bias [1]-->这里的偏置直接初始化为0
       # x*w + b ----> y_predict
       # 变量op当中会有trainable参数决定是否训练
self.weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0),
name="weights") self.bias = tf.Variable(0.0, name='biases') # 建立回归公式去得出预测结果
y_predict = tf.matmul(feature, self.weight) + self.bias return y_predict def loss(self, y_true, y_predict):
"""
目标值和真实值计算损失
:return: loss
"""
# 3、求出我们模型跟真实数据之间的损失
# 均方误差公式--->MSE
loss = tf.reduce_mean(tf.square(y_true - y_predict)) return loss def sgd_op(self, loss):
"""
获取训练OP
:return:
"""
# 4、使用梯度下降优化器优化
# 填充学习率:0 ~ 1 学习率是非常小,
# 学习率大小决定你到达损失一个步数多少
# 最小化损失---->返回的这个train_op,是可以训练的,之所以可以训练,是因为之前的变量都是tf.Variable()创建的
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss) return train_op

2.5 学习率的设置、步长的设置与梯度爆炸

学习率越大,训练到较好结果的步长越小;学习率越小,训练到较好结果的步长越大。

但是学习过大会出现梯度爆炸现象。关于梯度爆炸/梯度消失 ?

在极端情况下,权重的值变得非常大,以至于溢出,导致 NaN 值
如何解决梯度爆炸问题(深度神经网络当中更容易出现)
1、重新设计网络
2、调整学习率
3、使用梯度截断(在训练过程中检查和限制梯度的大小)
4、使用激活函数

2.6 变量的trainable设置观察

trainable的参数作用,指定是否训练

weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0), name="weights", trainable=False)

3、增加其他功能

  • 增加命名空间
  • 变量Tensorboard显示
  • 模型保存与加载
  • 命令行参数设置

3.1 增加命名空间

使得代码结构更加清晰,Tensorboard图结构清楚

with tf.variable_scope("lr_model"):

3.2 增加变量显示

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

  • 1、收集变量

    • tf.summary.scalar(name=’’,tensor) 收集对于损失函数和准确率等单值变量(标量),name为变量的名字,tensor为值
    • tf.summary.histogram(name=‘’,tensor) 收集高维度的变量参数(矢量)
    • tf.summary.image(name=‘’,tensor) 收集输入的图片张量能显示图片
  • 2、合并变量写入事件文件
    • merged = tf.summary.merge_all()
    • 运行合并:summary = sess.run(merged),每次迭代都需运行
    • 添加:FileWriter.add_summary(summary,  i),   i表示第几次的值
 def merge_summary(self, loss):

        # 1、收集张量的值
tf.summary.scalar("losses", loss) tf.summary.histogram("w", self.weight)
tf.summary.histogram('b', self.bias) # 2、合并变量
merged = tf.summary.merge_all() return merged # 生成事件文件,观察图结构
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph) # 运行收集变量的结果
summary = sess.run(merged) # 添加到文件
file_writer.add_summary(summary, i)

3.3 模型的保存与加载

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

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

使用

例如:
指定目录+模型名字
saver.save(sess, '/tmp/ckpt/test/myregression.ckpt')
saver.restore(sess, '/tmp/ckpt/test/myregression.ckpt')

如要判断模型是否存在,直接指定目录

checkpoint = tf.train.latest_checkpoint("./tmp/model/")

saver.restore(sess, checkpoint)

3.4 命令行参数使用

  • 2、 tf.app.flags.,在flags有一个FLAGS标志,它在程序中可以调用到我们

前面具体定义的flag_name

  • 3、通过tf.app.run()启动main(argv)函数
# 定义一些常用的命令行参数
# 训练步数
tf.app.flags.DEFINE_integer("max_step", 0, "训练模型的步数")
# 定义模型的路径
tf.app.flags.DEFINE_string("model_dir", " ", "模型保存的路径+模型名字") # 定义获取命令行参数
FLAGS = tf.app.flags.FLAGS # 开启训练
# 训练的步数(依据模型大小而定)
for i in range(FLAGS.max_step):
sess.run(train_op)

完整代码

# 用tensorflow自实现一个线性回归案例

# 定义一些常用的命令行参数
# 训练步数
tf.app.flags.DEFINE_integer("max_step", 0, "训练模型的步数")
# 定义模型的路径
tf.app.flags.DEFINE_string("model_dir", " ", "模型保存的路径+模型名字") FLAGS = tf.app.flags.FLAGS class MyLinearRegression(object):
"""
自实现线性回归
"""
def __init__(self):
pass def inputs(self):
"""
获取特征值目标值数据数据
:return:
"""
x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8 return x_data, y_true def inference(self, feature):
"""
根据输入数据建立模型
:param feature:
:param label:
:return:
"""
with tf.variable_scope("linea_model"):
# 2、建立回归模型,分析别人的数据的特征数量--->权重数量, 偏置b
# 由于有梯度下降算法优化,所以一开始给随机的参数,权重和偏置
# 被优化的参数,必须得使用变量op去定义
# 变量初始化权重和偏置
# weight 2维[1, 1] bias [1]
# 变量op当中会有trainable参数决定是否训练
self.weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0),
name="weights") self.bias = tf.Variable(0.0, name='biases') # 建立回归公式去得出预测结果
y_predict = tf.matmul(feature, self.weight) + self.bias return y_predict def loss(self, y_true, y_predict):
"""
目标值和真实值计算损失
:return: loss
"""
# 3、求出我们模型跟真实数据之间的损失
# 均方误差公式
loss = tf.reduce_mean(tf.square(y_true - y_predict)) return loss def merge_summary(self, loss): # 1、收集张量的值
tf.summary.scalar("losses", loss) tf.summary.histogram("w", self.weight)
tf.summary.histogram('b', self.bias) # 2、合并变量
merged = tf.summary.merge_all() return merged def sgd_op(self, loss):
"""
获取训练OP
:return:
"""
# 4、使用梯度下降优化器优化
# 填充学习率:0 ~ 1 学习率是非常小,
# 学习率大小决定你到达损失一个步数多少
# 最小化损失
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss) return train_op def train(self):
"""
训练模型
:param loss:
:return:
""" g = tf.get_default_graph() with g.as_default(): x_data, y_true = self.inputs() y_predict = self.inference(x_data) loss = self.loss(y_true, y_predict) train_op = self.sgd_op(loss) # 收集观察的结果值
merged = self.merge_summary(loss) saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 在没训练,模型的参数值
print("初始化的权重:%f, 偏置:%f" % (self.weight.eval(), self.bias.eval())) # 加载模型
checkpoint = tf.train.latest_checkpoint("./tmp/model/")
# print(checkpoint)
if checkpoint:
print('Restoring', checkpoint)
saver.restore(sess, checkpoint)
# 开启训练
# 训练的步数(依据模型大小而定)
for i in range(FLAGS.max_step): sess.run(train_op) # 生成事件文件,观察图结构
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph) print("训练第%d步之后的损失:%f, 权重:%f, 偏置:%f" % (
i,
loss.eval(),
self.weight.eval(),
self.bias.eval())) # 运行收集变量的结果
summary = sess.run(merged) # 添加到文件
file_writer.add_summary(summary, i) if i % 100 == 0:
# 保存的是会话当中的变量op值,其他op定义的值不保存
saver.save(sess, FLAGS.model_dir) if __name__ == '__main__':
lr = MyLinearRegression()
lr.train()

注释更详细的版本:

# 导包
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # 定义model训练的步数 step
tf.app.flags.DEFINE_integer("max_step", 0, "训练模型的步数")
# 定义model的路径 load + 名字
tf.app.flags.DEFINE_string("model_dir", " ", "模型保存的路径+模型名字") # 获取上述二者, 在运行的时候指定--->下面的参数要修改对应的FLAGS.max_step和FLAGS.model_dir
FLAGS = tf.app.flags.FLAGS # 命令行指令, 一定要写模型名字。。。
# python xx.py --max_step=xx --load="xx+模型名字" class MyLR:
def __init__(self):
# # 学习率
self.learning_rate = 0.1
# # 训练次数
# self.MAX_STEP = 300 def input(self):
'''
获取训练需要的数据
:return: x_data, y_true
'''
x_data = tf.random_normal(shape=[100, 1], mean=0., stddev=1.)
# 矩阵乘法
y_true = tf.matmul(x_data, [[0.5]]) + 1.2 return x_data, y_true def model(self, x_data):
'''
建模,假设是一个一元一次线性方程
y = x*w + b
:param x_data:
:return: self.weight, self.bais
'''
# 增加命名空间:
# 1.代码清晰
# 2.实现共享变量
with tf.variable_scope("lr_model"): # op变量,可训练,可保存
self.weight = tf.Variable(
initial_value=tf.random_normal(shape=[1, 1], mean=0., stddev=1.),
trainable=True,
name="weight"
)
self.bais = tf.Variable(
initial_value=0.,
trainable=True,
name="bais"
) # 建模
y_predict = tf.matmul(x_data, self.weight) + self.bais # 这里只返回y_predict即可,前面的权重和偏置已经是实例变量
return y_predict def loss(self, y_true, y_predict):
'''
损失函数
:param y_true:
:param y_predict:
:return: loss
'''
with tf.variable_scope("losses"):
loss = tf.reduce_mean(tf.square(y_true - y_predict))
return loss def sgd_op(self, loss):
'''
SGD(批梯度下降优化)
:param loss:
:return: train_op
'''
train_op = tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate).minimize(loss)
return train_op def mergr_summary(self, loss):
'''
收集张量
:param loss:
:return:
'''
# 1.1收集对于损失函数和准确率等单值变量,标量
tf.summary.scalar("losses", loss) # 1.2收集高维度张量值,矢量
tf.summary.histogram("w", self.weight)
tf.summary.histogram("b", self.bais) # 2.合并变量(OP)---> 再拿到会话中运行
merged = tf.summary.merge_all()
return merged def train(self):
'''
开启训练
:return:
'''
# 1.获取数据
x_data, y_true = self.input() # 2.将数据传入模型,并获取预测值
y_predict = self.model(x_data) # 3.结合预测值和真实值,获取loss
loss = self.loss(y_true, y_predict) # 4.降低损失,获取train_op
train_op = self.sgd_op(loss) # 收集要观察的张量
merged = self.mergr_summary(loss) # 定义一个保存文件的saverOP,默认保存所有变量
# 可以指定要保存的参数,和保存最近的几个checkpoint文件
saver = tf.train.Saver(var_list=None, max_to_keep=5) # 开启会话
with tf.Session() as sess:
# 显示初始化变量OP
sess.run(tf.global_variables_initializer()) # 创建events文件 默认图一定要写上
# 开启tensorboard的命令:tensorboard --logdir="./tmp01/summary/"
file_writer = tf.summary.FileWriter(logdir="./tmp01/summary/", graph=sess.graph) print("未训练的损失: %f, 参数w: %f, b: %f" % (loss.eval(), self.weight.eval(), self.bais.eval())) # 判断model是否存在
checkpoint = tf.train.latest_checkpoint("./tmp01/model/")
if checkpoint:
# 在训练之前,加载model(之前训练的,如果有的话),
# 覆盖原来名字一样(原来的w和b)的OP
saver.restore(sess, checkpoint) # 打印第一次加载的参数
print("第一次加载保存的model的参数w: %f, b: %f" % (self.weight.eval(), self.bais.eval()))
print("以当前model去训练") # 开启训练
for i in range(FLAGS.max_step):
# 这一步是关键哦
# 每次迭代都需要运行收集的张量
_, summary = sess.run(fetches = [train_op, merged]) # 把summary,张量的值写入到events文件当中
file_writer.add_summary(summary, i) print("训练第%f的损失: %d, 参数w: %f, b: %f" % (i, loss.eval(), self.weight.eval(), self.bais.eval())) # 每隔一百步保存一次model, 保存会话, 指定路径+名字
if i % 100 == 0:
saver.save(sess, FLAGS.model_dir) if __name__ == '__main__':
lr = MyLR()
lr.train()

(第一章第六部分)TensorFlow框架之实现线性回归小案例的更多相关文章

  1. (第一章第二部分)TensorFlow框架之图与TensorBoard

    系列博客链接: (一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html 本文概述: 说明图的基本使用 应用tf.Grap ...

  2. NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译

    NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译   第一章第二节Mapping a class with XML ...

  3. (第二章第二部分)TensorFlow框架之读取图片数据

    系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html 本文概述: 目标 说明图片 ...

  4. 第一章-第六题(帮人抢票,帮人选课这些软件是否合法 你怎么看?)--By梁旭晖

    我觉得这些软件是合法的,符合道德规范的. 计算机当初设计的初衷就是简化甚至替代人类的工作.而软件作为计算机硬件的驱动着,其设计就是体现这些原则. 现在互联网上的订票,选课类型的网站还是有很多的,比如: ...

  5. 《java入门第一季》之UDP协议下的网络编程小案例

    需求,一台电脑发送数据,其他电脑都可以收到该数据.使用广播地址. 发送端: import java.io.BufferedReader; import java.io.IOException; imp ...

  6. (第二章第四部分)TensorFlow框架之TFRecords数据的存储与读取

    系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html (第二章第二部分)Tens ...

  7. (第二章第三部分)TensorFlow框架之读取二进制数据

    系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html (第二章第二部分)Tens ...

  8. 微信小程序(六)-项目实例(原生框架 MINA基配搭建)==01-头搜索框tabbar

    项目实例(原生框架 MINA) 1.新建小程序项目 1.用自已的小程序APPID 2.清除整理项目中初建默认无关的代码 1.app.json 中删除logs,同时删除pages下的losgs文件夹 2 ...

  9. (第二章第一部分)TensorFlow框架之文件读取流程

    本章概述:在第一章的系列文章中介绍了tf框架的基本用法,从本章开始,介绍与tf框架相关的数据读取和写入的方法,并会在最后,用基础的神经网络,实现经典的Mnist手写数字识别. 有四种获取数据到Tens ...

随机推荐

  1. PC端实用正版软件推荐

    首先介绍一下背景,我本人是一个软件工程师,所以对电脑上很多软件使用都有要求,这里将个人觉得好用的一些软件分享给大家: 1. Typora 对于长写本地笔记.网络博客的人,对 MarkDown 格式应该 ...

  2. Python数据结构之“栈”与“队列”

    栈(Stacks): ·定义:是一种只能通过访问其一端来实现的数据存储于检索的线性数据结构,具有后进先出(last in first out,LIFO)的特征 ·主要操作: 1. Stack():建立 ...

  3. SP5971 LCMSUM - LCM Sum

    一个基于观察不依赖于反演的做法. 首先 \(\rm lcm\) 是不好算的,转化为计算 \(\rm gcd\) 的问题,求: \[\sum\limits_{i = 1} ^ n \frac{in}{\ ...

  4. [免费下载应用]iNeuKernel.Ocr 图像数据识别与采集原理和产品化应用

    目       录 1..... 应用概述... 2 2..... 免费下载试用... 2 3..... 视频介绍... 2 4..... iNeuLink.Ocr图像数据采集应用... 2 5... ...

  5. root登陆530 Permission denied、530 Login incorrect解决

    感谢大佬:https://blog.51cto.com/3241766/2316986?source=dra 背景:由于云平台上22端口不对外放开,sftp使用不了,故选择ftp服务 操作系统版本: ...

  6. uniapp自定义顶部搜索框兼容微信小程序

    zhuanzai:  uniapp自定义顶部搜索框兼容微信小程序 自定义组件 navbarvue (胶囊底部高度 - 状态栏的高度) + (胶囊顶部高度 - 状态栏内的高度) = 导航栏的高度 < ...

  7. 推荐一款仿iPhone桌面的代码. ___王朋.

    Demo:https://files.cnblogs.com/files/sixindev/LxGridView-master.zip 这是作者原来的效果图,很多东西还需要慢慢学习.作者用的很多类,根 ...

  8. kubectl详解

    kubectl详解 目录 kubectl详解 一.陈述式管理 1. 陈述式资源管理方法 2. k8s相关信息查看 2.1 查看版本信息 2.2 查看资源对象简写 2.3 查看集群信息 2.4 配置ku ...

  9. 大白话讲解IOC和AOP

    IOC和AOP 什么是IOC IoC(Inversion of control)控制反转,它是一种思想,而Spring Framework实现了这一思想.Ioc也称为依赖注入(DI). IOC控制反转 ...

  10. Solution -「六省联考 2017」「洛谷 P3750」分手是祝愿

    \(\mathcal{Description}\)   Link.   有 \(n\) 盏编号为 \(1\sim n\),已知初始状态的灯,每次操作选取 \(x\in[1,n]\),使得所有编号为 \ ...