Tensorflow基础
Tensorflow基础1 深度学习深度学习,如深度神经网络、卷积神经网络和递归神经网络已被应用 计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域 并获取了极好的效果。机器学习与深度学习的简单区别:机器学习深度学习应用场景指纹识别、特征物体检测等...
Tensorflow基础
1 深度学习
深度学习,如深度神经网络、卷积神经网络和递归神经网络已被应用 计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域 并获取了极好的效果。
机器学习与深度学习的简单区别:
机器学习 | 深度学习 | |
应用场景 | 指纹识别、特征物体检测等领域 | 应用于文字识别、人脸技术、语义分析、智能监控等领域。 |
数据量 | 机器学习能够适应各种数据量,特别是数据量较小的场景 | 需要大量数据才能完美理解 |
执行时间 | 执行时间更少 | 包含有很多参数需要很多时间 |
解决问题方法 | 遵循标准程序以解决问题。它将问题拆分成数个部分,对其进行分别解决,而后再将结果结合起来以获得所需的答案 | 以集中方式解决问题,而不必进行问题拆分。 |
2 深度学习框架之Tensorflow
Tensorflow特点如下:
(1)真正的可移植性:引入各种计算设备的支持包括CPU/GPU/TPU,以及能够很好地运行在移动端, 如安卓设备、ios、树莓派等等 ;
(2)多语言支持:Tensorflow 有一个合理的c++使用界面,也有一个易用的python使用界面来构建和 执行你的graphs,你可以直接写python/c++程序;
(3)高度的灵活性与效率:TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库 能够灵活进行组装图,执行图。随着开发的进展,Tensorflow的效率不算在提高 ;
(4)支持:TensorFlow 由谷歌提供支持,谷歌投入了大量精力开发 TensorFlow,它希望 TensorFlow 成为机器学习研究人员和开发人员的通用语言
镜像下载地址https://pypi.org/project/tensorflow/1.14.0/#files
3 op,图和会话
3.1 op
operation(op):用来专门运算的操作节点,只要用tensorflow的API定义的函数都是op。计算都是使用tensor去计算的,op只是一个载体,tensor是一个被载的物体
类型 | 示例 |
---|---|
标量运算 | Add、Sub、Mul、Div、Exp、Log、Greater、Less、Equal |
向量运算 | Concat、Slice、Splot、Constant、Rank、Shape、Shuffle |
矩阵运算 | Matmul、MatrixInverse、MatrixDeterminant |
带状态的运算 | Variable、Assign、AssignAdd |
神经网络组件 | SoftMax、Sigmoid、ReLU、Convolution2D、MaxPooling |
存储、恢复 | Save、Restore |
队列及同步运算 | Enqueue、Dequeue、MutexAcquire、MutexRelease |
控制流 | Merge、Switch、Enter、Leave、NextIteration |
3.2 图
graph(图):整个程序的结构,包含了一组op和tensor。没有特别的作用,就是指代整个程序结构,分配内存。默认已经注册,一组表示 tf.Operation计算单位的对象和tf.Tensor 表示操作之间流动的数据单元的对象
图是可以创建的,相当于单独分配一个内存存储另外一个图即程序的结构,就相当于两部分互不干扰
①获取调用: tf.get_default_graph() op、sess或者tensor 的graph属性
②图的创建:tf.Graph() 使用新创建的图
g = tf.Graph()
with g.as_default():
a = tf.constant(1.0)
assert c.graph is g
Tensorflow的程序有个特点,很多with(上下文管理器),比如使用设备是with,在某个设备下面进行计算也是with,使用会话进行计算,使用这张图也是with。
3.3 会话
(1)会话:运行TensorFlow操作图的类,使用默认注册的图(可以指定运行图)。tf.Session()
注意:会话当中只能运行一个图
会话资源:会话可能拥有很多资源,如 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)可以看到程序在哪里进行运算
③交互式:tf.InteractiveSession()
(2)会话的run()方法:
run(fetches, feed_dict=None,graph=None) 运行ops和计算tensor
嵌套列表,元组, namedtuple,dict或OrderedDict(重载的运算符也能运行)
feed_dict 允许调用者覆盖图中指定张量的值,提供给 placeholder使用
返回值异常:① RuntimeError:如果它Session处于无效状态(例如已关闭)②TypeError:如果fetches或feed_dict键是不合适的类型③ValueError:如果fetches或feed_dict键无效或引用 Tensor不存在。
整个框架的设计思想:数据在整个图的结构里面进行运算流动
Tensorflow Feed操作
意义:在程序执行的时候,不确定输入的是什么,提前“占个坑”
语法:placeholder提供占位符,run时候通过feed_dict指定参数
4 张量
4.1 张量
tensor(张量):就是指代tensorflow中的数据,可以把一个张量想象成一个n维的数组或列表。一个张量有一个静态类型和动态类型的维数,张量可以在图中的节点之间流通.其实张量更代表的就是一种多位数组。
张量由三部分,名字(它用于键值对的存储,用于后续的检索,如Const: 0),形状(描述数据的每一维度的元素个数,如(1,2)),数据类型(如int32)组成。
(1)阶:张量的维数来被描述为阶,但是张量的阶和矩阵的阶并不是同一个概念,张量的阶(有时是关于如顺序或度数或者是n维)是张量维数的一个数量描述。
阶 | 数学实例 | Python | 例子 |
---|---|---|---|
0 | 纯量 | (只有大小) | t = 66 |
1 | 向量 | (大小和方向) | t = [6.6,8.8] |
2 | 矩阵 | (数据表) | t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] |
3 | 3阶张量 | (数据立体) | t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]] |
n | n阶 | .... |
(2)数据类型
(3)张量的属性:
graph | 张量所属的默认图 |
op | 张量的操作名 |
name | 张量的字符串描述 |
shape | 张量形状 |
(4)TensorFlow中,张量具有静态形状和动态形状。张量的动态形状与静态形状:
①静态形状: 创建一个张量或者由操作推导出一个张量时,初始状态的形状
tf.Tensor.get_shape:获取静态形状
tf.Tensor.set_shape():更新Tensor对象的静态形状,通常用于在不能直接推断的情况下
②动态形状: 一种描述原始张量在执行过程中的一种形状
tf.reshape:创建一个具有不同动态形状的新张量
③注意:
1)对于静态形状来说,一旦张量形状固定了,不能在此设置静态形状,不能跨维度修改,1-D到1-D,2-D到2-D。
2)动态形状可以去创建一个新的张量,tf.reshape()动态创建新张量时,元素个数不能不匹配,1-D到2-D,1-D到3-D
3)动态形状和静态形状的区别在于:有没有生成一个新的张量数据
4.2 张量的操作
(1)常用生成张量
①生成固定值张量
tf.zeros(shape, dtype=tf.float32, name=None) 创建所有元素设置为零的张量。此操作返回一个dtype具有形状shape和所有元素设置为零的类型的张量
tf.zeros_like(tensor, dtype=None, name=None) 给tensor定单张量(),此操作返回tensor与所有元素设置为零相同的类型和形状的张量。
tf.ones(shape, dtype=tf.float32, name=None) 创建一个所有元素设置为1的张量。此操作返回一个类型的张量,dtype形状shape和所有元素设置为1。
tf.ones_like(tensor, dtype=None, name=None) 给tensor定单张量(),此操作返回tensor与所有元素设置为1 相同的类型和形状的张量。
tf.fill(dims, value, name=None) 创建一个填充了标量值的张量。此操作创建一个张量的形状dims并填充它value。
tf.constant(value, dtype=None, shape=None, name='Const') 创建一个常数张量。
②创建随机张量
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 从截断的正态分布中输出随机值,和 tf.random_normal() 一样,但是所有数字都不超过两个标准差
tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 从正态分布中输出随机值,由随机正态分布的数字组成的矩阵
(2)张量变换
①改变类型
tf.string_to_number(string_tensor, out_type=None, name=None) 将输入Tensor中的每个字符串转换为指定的数字类型。
tf.to_double(x, name='ToDouble')
tf.to_float(x, name='ToFloat')
tf.to_bfloat16(x, name='ToBFloat16')
tf.to_int32(x, name='ToInt32')
tf.to_int64(x, name='ToInt64')
tf.cast(x, dtype, name=None)
②形状和变换
tf.shape(input, name=None) 返回张量的形状
tf.size(input, name=None)
tf.rank(input, name=None)
tf.reshape(tensor, shape, name=None)
tf.squeeze(input, squeeze_dims=None, name=None ) 默认将input中维度是1的那一维去掉。可以使用squeeze_dims参数,来指定需要去掉的位置。
tf.expand_dims(input, dim, name=None) 作用与squeeze相反,添加一个指定维度
③切片与扩展
tf.concat(concat_dim, values, name='concat')
5 变量
变量也是一种OP,是一种特殊的张量,能够进行存储持久化,它的 值就是张量
5.1 Variable类
tf.Variable.init(initial_value, trainable=True, collections=None, validate_shape=True, name=None) 创建一个带值的新变量initial_value
initial_value:A Tensor或Python对象可转换为a Tensor.变量的初始值.必须具有指定的形状,除非 validate_shape设置为False.
trainable:如果True,默认值也将该变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES,该集合用作Optimizer类要使用的变量的默认列表
collections:图表集合键列表,新变量添加到这些集合中.默认为[GraphKeys.VARIABLES]
validate_shape:如果False允许使用未知形状的值初始化变量,如果True,默认形状initial_value必须提供.
name:变量的可选名称,默认'Variable'并自动获取
5.1 变量的创建
tf.Variable(initial_value=None,name=None) 创建一个带值initial_value的新变量
assign(value) 为变量分配一个新值 返回新值
eval(session=None) 计算并返回此变量的值
name属性表示变量名字
5.2 变量的初始化
tf.global_variables_initializer() 添加一个初始化所有变量的op
注意:要在会话中开启
import tensorflow as tf
a = tf.constant([6,6,6])
var = tf.Variable(tf.random_normal([2,2], mean=0.0, stddev=1.0), name="variable")
print(a, var)
# 显示的初始化op,必须要做
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
# 必须运行初始化op
sess.run(init_op)
print(sess.run([a, var]))
5.3 tensorflow变量作用域
作用:让模型代码更加清晰,作用分明。也相当于上下文环境,相当于定义函数一样
通过tf.variable_scope()创建指定名字的变量作用域。加上with语句就可以在整个itcast变量作用域下就行操作。
加了作用域后的后台显示对比
6 Tensorboard可视化
Tensorboard可视化步骤如上图
(1)数据序列化-events文件:TensorBoard 通过读取 TensorFlow 的事件文件来运行
(2)tf.summary.FileWriter('/tmp/', graph= default_graph) 返回filewriter,写入事件文件到指定目录(最好用绝对路径),以提供给tensorboard使用
(3)开启tensorboard。命令:tensorboard --logdir=/tmp/
一般浏览器打开为127.0.0.1:6006,1.14.0版本打开后如下图
GRAPHS:用于显示程序的结构
SCALARS:一般用于显示0维度值,如准确率,损失
HISROGRAMS:一般用于显示高纬度的值如权重,偏置
SCALARS和HISROGRAMS是需要自己手动指定的
import tensorflow as tf
a = tf.constant(6.0, name="a")
b = tf.constant(8.0, name="b")
c = tf.add(a, b, name="add")
var = tf.Variable(tf.random_normal([2,2], mean=0.0, stddev=1.0), name="variable")
print(a, var)
# 显示的初始化op,必须要做
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
# 必须运行初始化op
sess.run(init_op)
# 把程序的图结构写入事件文件, graph:把指定的图写进事件文件当中
filewriter = tf.summary.FileWriter("./tmp/", graph=sess.graph)
print(sess.run([c, var]))
//总结:①变量op能够持久化保存,普通张量op是不行的
//②当定义一个变量op的时候,一定要在会话当中去运行初始化
//③name参数:在tensorboard使用的时候显示名字,可以让相同op名字的进行区分
该图结构显示如下
图中符号的意义如下:
回归和线性是一个迭代的过程,如果时间非常长,有不想输出日志文件,就可以用Tensorboard观察里面一些值的变化,所以有增加变量显示
6.2 增加变量显示
目的:观察模型的参数、损失值等变量值的变化
(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表示第几次的值
7 模型的保存与加载
在训练或者测试过程中,总会遇到需要保存训练完成的模型,然后从中恢复继续我们的测试或者其它使用。模型的保存和恢复也是通过tf.train.Saver类去实现,它主要通过将Saver类添加OPS保存和恢复变量到checkpoint。它还提供了运行这些操作的便利方法。
tf.train.Saver(var_list=None, reshape=False, sharded=False, max_to_keep=5, keep_checkpoint_every_n_hours=10000.0, name=None, restore_sequentially=False, saver_def=None, builder=None, defer_build=False, allow_empty=False, write_version=tf.SaverDef.V2, pad_step_number=False)
var_list:指定将要保存和还原的变量。它可以作为一个dict或一个列表传递.
max_to_keep:指示要保留的最近检查点文件的最大数量。创建新文件时,会删除较旧的文件。如果无或0,则保留所有检查点文件。默认为5(即保留最新的5个检查点文件。)
keep_checkpoint_every_n_hours:多久生成一个新的检查点文件。默认为10,000小时
(1)保存
调用Saver.save()方法。save(sess, save_path, global_step=None),checkpoint是专有格式的二进制文件,将变量名称映射到张量值。
注意:保存要指定路径和文件名,与事件文件不一样(指定路径就行)。
(2)恢复
方法是restore(sess, save_path),save_path是以前保存参数的路径,我们可以使用tf.train.latest_checkpoint来获取最近的检查点文件(也恶意直接写文件目录)
8 自定义命令行
tf.app.run(),默认调用main()函数,运行程序。main(argv)必须传一个参数。
tf.app.flags,它支持应用从命令行接受参数,可以用来指定集群配置等。在tf.app.flags下面有各种定义参数的类型。第一个也就是参数的名字,路径、大小等等。第二个参数提供具体的值。第三个参数是说明文档
DEFINE_string(flag_name, default_value, docstring)
DEFINE_integer(flag_name, default_value, docstring)
DEFINE_boolean(flag_name, default_value, docstring)
DEFINE_float(flag_name, default_value, docstring)
tf.app.flags.FLAGS,在flags有一个FLAGS标志,它在程序中可以调用到我们前面具体定义的flag_name.
9 tensorflow实现一个简单的线性回归
线性回归模型:W1X1+W2X2+WnXn+bias
线性回归定义:权重与特征乘积相加的和再加一个偏置bias,有多个个特征就有多少权重。
线性回归目的:找到一个合适的参数使得参数与特征组合之后,他预测的值与目标值很相近
实现步骤:
①准备特征值和目标值:这里简单实现使用1个特征值一个目标值,准备100个样本
②建立模型:随机初始化准备权重和偏置,这里准备一个权重一个偏置,y_predict=xw+b xw为两个矩阵相乘
③求损失函数即误差:均方误差为(y-y')^2+...+(y100-y100')^2/100
④梯度下降优化损失过程,tensorflow有实现,调用他的实现,指定学习率。
注意:模型参数必须用变量,因为变量有一个参数默认trainable=true,变量会随着梯度下降的更新与变化。
涉及的API:矩阵相乘运算: tf.matmul(x, w) 平方:tf.square(error) 均值: tf.reduce_mean(error)
梯度下降优化:tf.train.GradientDescentOptimizer(learning_rate) 参数:learning_rate:学习率
方法:minisize(loss)最小优化损失 返回值:梯度下降op
实现代码如下:
import tensorflow as tf
import os
# 定义命令行参数,第一个参数:名字,默认值,说明
tf.app.flags.DEFINE_integer("max_step", 100, "模型训练的步数")
tf.app.flags.DEFINE_string("model_dir", " ", "模型文件的加载的路径")
# 定义获取命令行参数名字
FLAGS = tf.app.flags.FLAGS
with tf.variable_scope("data"):
# 1、准备数据,x 特征值 [100, 1] 100行1列 y 目标值[100]
x = tf.random_normal([100, 1], mean=1.6, stddev=0.6, name="x_data")
# 真实值,假设已经知道是y=0.6x+0.8 矩阵相乘必须是二维的
y_true = tf.matmul(x, [[0.6]]) + 0.8
with tf.variable_scope("model"):
# 2、建立线性回归模型 1个特征,1个权重, 一个偏置 y = x w + b
# 随机给一个权重和偏置的值,让他去计算损失,然后再当前状态下优化,用变量定义才能优化
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
with tf.variable_scope("loss"):
# 3、建立损失函数,均方误差
loss = tf.reduce_mean(tf.square(y_true - y_predict))
with tf.variable_scope("optimizer"):
# 4、梯度下降优化损失 leaning_rate,不能指定太大,一帮有2-3位小数,越小循环训练的次数就要越多
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
# 1、收集tensor
tf.summary.scalar("losses", loss)
tf.summary.histogram("weights", weight)
# 定义合并tensor的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)
# 打印随机最先初始化的权重和偏置
print("随机初始化的参数权重为:%f, 偏置为:%f" % (weight.eval(), bias.eval()))
# 建立事件文件
filewriter = tf.summary.FileWriter("./tmp/event", graph=sess.graph)
# 加载模型,覆盖模型当中随机定义的参数,从上次训练的参数结果开始
if os.path.exists("./tmp/checkpoint"):
saver.restore(sess, FLAGS.model_dir)
# 循环训练 运行优化
for i in range(FLAGS.max_step):
sess.run(train_op)
# 运行合并的tensor
summary = sess.run(merged)
# 添加变量显示
filewriter.add_summary(summary, i)
print("第%d次优化的参数权重为:%f, 偏置为:%f" % (i, weight.eval(), bias.eval()))
# 保存模型
saver.save(sess, FLAGS.model_dir)
更多推荐
所有评论(0)