附录5:TensorFlow基础(一)
目录
- TensorFlow简介
- 什么是tensorflow
- tensorflow的核心
- Numpy与TensorFlow
- Tensorflow基本操作
- 初步认识tensorflow与tensorboard
- constant
- Variable
- placeholder
- assign,gridents,cast
TensorFlow简介
什么是tensorflow
这是一个来自Google的深度学习框架,热度逐年上升,在深度学习领域的生态环境很好。后来facebook的AI实验室不甘示弱,开源了pytorch和caffe2,pytorch侧重于科研,caffe2侧重于工业生产。pytorch借鉴了torch,torch本身是一个很好的框架,但不支持最普及的python语言,而是在lua上;
第一个DL框架Caffe的依赖过多,不易安装及个性化搭建自己的实验模型;pytorch书写简便,更加符合python哲学,但在分布式GPU上没有tensorflow高效;
- tensorflow兼容于Android,Windows,iOS,Linux,而且有优秀的可视化工具tensorboard;
- Checkpoints用于实验状态的保存和恢复;
- Autograd自动梯度计算,在caffe中,如果要自定义一个层,则需要开发者自己去实现梯度的计算,tensorflow解决了caffe的局限性;
- tensorflow目前已合并了高层框架keras,这使tensorflow更加简单易用;
注意
pytorch与tensorflow的autograd并不是自动计算梯度;
在pytorch中,通过计算图,调用方法backward才会依次对计算图中的各个张量计算出梯度;
在tensorflow中,则是用tensorflow.gradient()计算梯度;
tensorflow的核心
tensorflow的核心为graph(计算图)和session(会话),计算图是一个有向无环图;深度学习实验的流程总是为:
1.定义计算图;
2.在session中执行运算;
基于这样的理念,实现了定义与执行的分离。张量tensor在图中通过操作符 operator(简写为op)进行传递和变换(流动),由此得名tensorflow;
事实上,一个单独的operator其实也是一个非常小的计算图;所谓多GPU并行计算,其实就是人为地把原计算图中并行的一些operator组合(子计算图)设置到不同GPU上计算,再将结果汇合进行后续计算;
补充一点,operator,variable,constant都是计算图,variable,constant可以理解为一种特殊的operator,tensor只存在于计算图的执行中;
Tensor即张量:
- 0-dim张量:标量或数值;
- 1-dim张量:向量;
- 2-dim张量:矩阵;
… - n-dim张量:n维矩阵;
Numpy与TensorFlow
回忆pytorch笔记本,相似地,ndarray在CPU上计算,tensor可以在GPU上计算,且包括自动计算梯度;
Tensorflow基本操作
tensorflow不同版本间,其使用方式差异较大,本篇的操作基于tensorflow1.x;
如果要安装支持GPU计算的tensorflow,需要指明安装tensorflow-gpu
;
初步认识tensorflow与tensorboard
首先,导入numpy与tensorflow:
import tensorflow as tf
import numpy as np
import tensorflow.keras as kerastf.__version__ # 1.13.1
keras.__version__ # 2.2.4-tf# 检查是否可用GPU
tf.test.is_gpu_available()
创建两个矩阵:
matrix_1=np.zeros((5,3))
matrix_1
"""
array([[0., 0., 0.],[0., 0., 0.],[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]])
"""matrix_2=tf.zeros((5,3))
# 发现是取不到值的,只是初步定义了一个对象
# 本质上matrix_2是一个张量也是一个计算图
matrix_2
"""
<tf.Tensor 'zeros:0' shape=(5, 3) dtype=float32>
"""# 对张量施加op,其实是对op再次叠加op
tf.reshape(matrix_2,(1,15))
"""
<tf.Tensor 'Reshape:0' shape=(1, 15) dtype=float32>
"""
通过上面实例可以知道,在会话执行前,所有op都是在定义计算图,下面再定义一个简单的计算图:
a=tf.add(3,5,name="Add")
# a不仅是一个张量,其实已经是一个计算图
print(a)
"""
Tensor("Add:0", shape=(), dtype=int32)
"""
经过tensorboard可视化后有:
在定义计算图时,使用了tf.add
,并赋予名称"Add",该op依赖于另外两个op:x和y,即常量3和5,在定义时,tensorflow已经自动使用constant初始化,并为其命名为x和y;
常量constant也叫做源op,源op不需要输入计算图作为依赖:
sourceop = tf.constant(3,name="sop")
a
与matrix_2
一样,取不到结果,因为还没有执行计算图;执行计算图使用tf.Session:
sess=tf.Session()
# 可以简单理解为:sess可以把当前张量(计算图)依赖的张量(子图)逐步找到并执行
print(sess.run(a))
print(sess.run(matrix_2))
sess.close()# 考虑书写规范
with tf.Session() as sess:print(sess.run(a))
使用writer可以将感兴趣的对象写入日志:
a=tf.constant(2)
b=tf.constant(3)
x=tf.add(a,b)with tf.Session() as sess:# 将感兴趣的对象(比如计算图)写入日志,需在运行sess前初始化writerwriter=tf.summary.FileWriter("./graphs/const_add",sess.graph)print(sess.run(x))#关闭writerwriter.close()
sess.graph就是当前会话中的所有计算图:
print(sess.graph)
"""
<tensorflow.python.framework.ops.Graph object at 0x7f3f540cc710>
"""
日志可视化需要tensorboard,使用命令行解析日志,在浏览器端可视化,用法举例如下(注意输入的是绝对路径):
tensorboard --logdir=/home/baijingyi/python37/MASK/graphs/const_add
另外,必须用谷歌浏览器才能访问tensorboard开启的进程;
为了便于管理计算图,可以为op赋予名称name:
a=tf.constant([2,3],name='a') #[2,]
b=tf.constant([2,3],name='b') # [2,]# 注意tf.multiply是张量逐个元素相乘,tf.matmul才是矩阵乘法
x=tf.multiply(a,b,name='dot_product') #[2,]
另外,我可以将要执行的计算图加入列表,即变成fetch,再执行:
x=tf.constant(2)
y=tf.constant(3)add_op=tf.add(x,y)
mul_op=tf.multiply(x,y)
useless=tf.multiply(x,add_op)
pow_op=tf.pow(add_op,mul_op)with tf.Session() as sess:z,n=sess.run([pow_op,useless])
计算图为:
额外补充,计算图中,非源op是没有箭头的(在低版本的tensorflow中没有箭头,高版本的tensorflow计算图中,每个op都有箭头指向);
前面曾经提到,可以将计算图分解到不同的设备上并行计算,只需要为目标op在定义时指明设备,在会话中写入配置tf.ConfigProto(log_device_placement=True)
:
#指定设备
#定义图
with tf.device('/gpu:2'):a=tf.constant([i for i in range(6)],dtype=tf.float32,name='a')b=tf.constant([i for i in range(6)],dtype=tf.float32,name='b')c=tf.multiply(a,b)#构建session
with tf.Session(#在sess中写入配置,让任务必须在指定gpu上完成config=tf.ConfigProto(log_device_placement=True)
) as sess:sess.run(c)
constant
constant是tensorflow中构造常量的op,属于源op;
tf.constant(value,dtype=None,shape=None,name='Const',verify_shape=False)
其中,参数verify_shape默认为False,如果修改为True表示检查value的形状与shape是否相符,如果不符会报错;
常量分三种,一种是人为定义,一种是随机采样,另一种是zeros,ones一类的常量;
1.人为定义的常量
a = tf.constant([2, 2], name="a")
b = tf.constant([[0, 1], [2, 3]], name="b")
2.从随机分布中采样
tensorflow已实现的常用随机分布常量有:
tf.random_normal(shape,mean=0.0,stddev=1.0,dtype=tf.float32,seed=None,name=None)tf.truncated_normal(shape,mean=0.0,stddev=1.0,dtype=tf.float32,seed=None,name=None)tf.random_uniform(shape,minval=0,maxval=None,dtype=tf.float32, seed=None,name=None)tf.random_shuffle(value,seed=None,name=None)tf.random_crop(value,size,seed=None,name=None)tf.multinomial(logits,num_samples,seed=None,name=None)tf.random_gamma(shape,alpha,beta=None,dtype=tf.float32,seed=None, name=None)
实例如下:
x=tf.random_normal([5,3],mean=0.0,stddev=1.0)with tf.Session() as sess:print(sess.run(x))"""
[[-0.544223 0.3129832 -1.1097211 ][-0.96931726 -0.97435105 2.201063 ][-1.8638048 0.17048389 0.6574646 ][ 0.2907467 -0.95708215 -0.63632256][-0.4043712 -0.3576785 -0.70155025]]
"""
3.zeros与ones
tf.zeros和tf.ones实质上也是常量的范畴:
x=tf.zeros([5,3])
Variable
变量是一种更特殊的op,根据前面内容已经知道常量是一个op,而变量是一个类,它可以用源op或者其他常规op作为参数;
在使用变量前必须进行初始化,否则不会为变量分配计算资源。初始化方式一般有三种,每种初始化都需加入会话执行才生效;
对于以下变量:
# 使用变量前必须初始化,只有初始化变量后,计算机才会为变量分配资源
a=tf.Variable(6,name="a")
b=tf.Variable(8,name="b")
- 最简单的方法,把全部变量都进行初始化
init=tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init)
- 构造Variable的fetch,初始化变量子集
init_ab=tf.variables_initializer([a,b],name="init_ab")
with tf.Session() as sess:sess.run(init_ab)
- 初始化单个变量
W=tf.Variable(tf.zeros([5,3]))
with tf.Session() as sess:sess.run(W.initializer)
对于完成了初始化的变量,可以使用sess.run获取其值,但是每次都sess.run比较麻烦,且耗费资源,可以通过实例方法eval()
获取到值(eval适用于所有op,它本质上是sess.run的简化写法):
W=tf.Variable(tf.zeros([5,3]))
with tf.Session() as sess:sess.run(W.initializer)print(W.eval())"""
[[0. 0. 0.][0. 0. 0.][0. 0. 0.][0. 0. 0.][0. 0. 0.]]
"""
以上实例都是用源op作为Variable的参数,也可以用常规op输入:
a=tf.add(3,5)
x=tf.Variable(a)init=tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init)print(x.eval()) # 8
placeholder
placeholder是一个占位符,用于存放训练数据:
tf.placeholder(dtype,shape=None,name=None)
placeholder通常与sess.run中的feed_dict配合使用,placeholder用于提前声明,feed_dict用于执行传入实际的数据,feed_dict传入python格式的数据,被placeholder自动转换为tensorflow的张量格式:
a=tf.placeholder(tf.float32, shape=[3])
b=tf.constant([1,2,3],dtype=tf.float32)
c=a+b # 等价于tf.add(a,b)with tf.Session() as sess:print(sess.run(c,# feed_dict用字典形式保存传入的数据feed_dict={a:[6,7,8]}))
一般来说,待学习的参数用Variable定义,训练数据用placeholder定义
assign,gridents,cast
tf.assign
assign(ref,value,validate_shape=None,name=None)
同样是一个op,此操作用value覆盖了输入张量ref的值,validate_shape用于检查两者的shape是否一致;
tf.gridents
回顾pytorch笔记本,必须在执行backward后,计算图才会被反向计算,得到张量的梯度,tensorflow也一样,如果不调用gridents,计算图是不会反向传播的,也就不存在参数的更新;
对于tf.gradient:
tf.gradients(ys,xs,name='gradients',stop_gradients=None# 还有其他很多参数,简单起见就只讨论以上参数
)ys:目标函数,需要被微分的计算图
xs:需要计算梯度的对象
stop_gradients:终止计算梯度的对象
实例如下:
a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b]) # 目标函数是3*a
with tf.Session() as sess:print(sess.run(g))
# 结果:[3.0, 1.0]a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[a])
with tf.Session() as sess:print(sess.run(g))
# 结果:[3.0, 1.0]a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[b])
with tf.Session() as sess:print(sess.run(g))
# 结果:[1.0, 1.0]
对于第2个例子,设置a终止梯度计算,即计算图寻找完依赖子图a后就不再计算梯度,因此,计算图递进到a+2*a
,所以a的梯度为3,b的梯度为1;
对于第3个例子,设置b终止了梯度计算,即计算图寻找完依赖子图b后就不再计算梯度,因此计算图停留在a+b
,a的梯度只有1,b也只有自己的梯度1;
tf.cast
cast(x, dtype, name=None)x:待转换的张量
dtype:目标数据类型
name:定义操作的名称
附录5:TensorFlow基础(一)相关推荐
- 深度学习(11)TensorFlow基础操作七: 向前传播(张量)实战
深度学习(11)TensorFlow基础操作七: 向前传播(张量)实战 1. 导包 2. 加载数据集 3. 转换数据类型 4. 查看x.shape, y.shape, x.dtype, y.dtype ...
- TensorFlow基础剖析
TensorFlow基础剖析 一.概述 TensorFlow 是一个使用数据流图 (Dataflow Graph) 表达数值计算的开源软件库.它使用节点表示抽象的数学计算,并使用 OP 表达计算的逻辑 ...
- 资源 | Intel发布AI免费系列课程3部曲:机器学习基础、深度学习基础以及TensorFlow基础
翻译 | AI科技大本营(公众号ID:rgznai100) 校对 | 成龙 编辑 | 明明 Intel于近期发布了三门AI系列的免费课程,分别是关于机器学习基础.深度学习基础.TensorFlow基础 ...
- TF学习:Tensorflow基础案例、经典案例集合——基于python编程代码的实现
TF学习:Tensorflow基础案例.经典案例集合--基于python编程代码的实现 目录 Tensorflow的使用入门 1.TF:使用Tensorflow输出一句话 2.TF实现加法 3.TF实 ...
- [Python人工智能] 三.TensorFlow基础之Session、变量、传入值和激励函数
从本篇文章开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇文章讲解了TensorFlow基础和一元直线预测的案例:本篇文章将详细介绍Session.变量.传入值和激励函数 ...
- [Python人工智能] 二.TensorFlow基础及一元直线预测案例
从本篇文章开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇文章讲解了TensorFlow的安装过程和神经网络基础概念.这篇文章将分享TensorFlow基础并介绍一元直线 ...
- 深度学习(10)TensorFlow基础操作六: 数学运算
深度学习(10)TensorFlow基础操作六: 数学运算 1. Operation type 2. + - * / % // 3. tf.math.log & tf.exp 4. log2, ...
- 深度学习(9)TensorFlow基础操作五: Broadcasting
深度学习(9)TensorFlow基础操作五: Broadcasting 1. 操作思想 2. 具体例子 3. 理解 (1) How to understand? (2) Why Broadcasti ...
- 深度学习(8)TensorFlow基础操作四: 维度变换
深度学习(8)TensorFlow基础操作四: 维度变换 1. View 2. 示例 3. Reshape操作可能会导致潜在的bug 4. tf.transpose 5. Squeeze VS Exp ...
- 深度学习(7)TensorFlow基础操作三: 索引与切片
深度学习(7)TensorFlow基础操作三: 索引与切片 一. 基础索引 1. Basic indexing 2. Numpy-style indexing 3. start : end 4. 切片 ...
最新文章
- 吴恩达邀请9位AI大牛畅想2020:李开复看好医疗教育,LeCun强调自监督学习
- 逃离湾区,下一站是哪里?西雅图 PK 奥斯汀
- 路由跟踪命令.查看DNS、IP、Mac等
- Selenium实现将淘宝商品加入购物车
- 微信小程序数据拼接_微信小程序 数据预拉取
- H3C 典型数据链路层标准
- java 面试基础总结(二)---多线程
- Win10下 QT的安装配置 (亲测可用)
- 爬虫网页框架代码和媒体对象
- 第六章-网络可靠性设计
- 重拾Java基础知识:IO流
- Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached
- 11——go语言数字类型
- CloudFlare遇到Error 526无效的SSL证书解决方法
- 日语学习 第4篇 部屋(へや)に机(つくえ)と椅子(いす)があります
- HIve 删除乱码分区
- win10 x64中inlineHook SSDT里面的函数
- Perl语言开发工具(持续整理)
- Ultra Edit使用技巧
- Echarts 入门实例--金山打字折线图