tensorflow入门1
1.tensorflow的组成
先来看一个例子,比如我们实现一个简单的加法:
按照python常规的思路,我们可能会先定义一个a,定义一个b,然后add。
import tensorflow as tf
import numpy as np
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
print(y)
结果:
Tensor(“Add:0”, shape=(), dtype=int32)
我们可以看到,显示的结果并不是3,而是一个Tensor(……),这是啥呢?为啥不是3?看来tensorflow并不是这么简单啊,那让我们先来看看实现一个完整的加法如何操作。
import tensorflow as tf
import numpy as np
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
with tf.Session() as sess:
print(sess.run(y))
3
可以看到后面加上了with就可以运行出结果了,那么这个with又是啥?其实,这就是会话,作用就是运算程序的图。
所以一个简单的tensorflow数据计算流程是要包括:
1、tensor(张量):即数据
2、operation(op):运算的操作节点,类似加减乘除。
3、graph(图):整个程序的结构,给程序分配内存的地方。
4、会话:运算出程序的结果,这也是和python不同的地方。
简单的说,就是我们需要把tensor放到op中,然后进行运算,最后通过会话得出结果。
2.图
1、图的获取:
graph=tf.get_default_graph()
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
可以看到结果中有一段为地址符,所以也就说明图相当于给争端程序分配内存。
在举个例子:
import tensorflow as tf
import numpy as np
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
graph=tf.get_default_graph()
with tf.Session() as sess:
print(sess.run(y))
print(a.graph)
print(b.graph)
print(y.graph)
运行结果:
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
可以看到a,b,y都是在一张图中,所以地址相同。
总之:
创建一张图要包含一组op和tensor
op:只要是使用tensorflow的API定义的函数都是op(即tf.xxx()中的xxx就是op)。举个例子:tf.add(),tf.constant(),中的add,constant都叫做op。
tensor(张量):指的是数据。
例如:a=tf.constant(1),中的a就是一个tensor类型的数据,如果将a打印出来,结果不是数字,而是a的类型(tensor)。计算的时候使用tensor计算而不是op。可以把op认为是载体,tensor就是被载物。
2、图的创建
tf.Graph()
当程序比较复杂的时候,可以创建两个或者多个图,在上面代码的基础上创建一个图:
import tensorflow as tf
import numpy as np
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
graph=tf.get_default_graph()
with tf.Session() as sess:
print(sess.run(y))
print(a.graph)
print(b.graph)
print(y.graph)
graph2=tf.Graph()
print(graph2)
运行结果:
3
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
<tensorflow.python.framework.ops.Graph object at 0x0000012A6F9ED978>
<tensorflow.python.framework.ops.Graph object at 0x0000012A6FB79CF8>
可以看出新创建的一个图与其他的地址不同。
3.会话
会话是用来运行图的结果的。主要作用有:
1、运行图的结构
2、分配资源计算
3、掌握资源(tensor变量的资源、队列、线程等)
操作方法:
tf.Session()
但是它默认运行一张图,不可以运行另一张图的内容。比如拿上面的代码举例子,如果运行:
sess.run(graph2)
就会报错。应为运行的为另一张图的内容。如果想要运行多张图,需要修改为:
with tf.Session(graph=图的名称) as sess:
有了会话之后需要运行:
sess.run()
才可以得出最后的运行结果。
4.会话的run()
通过上面的例子科一发现,tensor只有在会话中run之后才会得出结果,接下来了解一下run()
run()的参数:
run(fetchs,feed_dict=None,graph=None)
有两个比较重要的参数:
fetchs:表示的是元组(即你想要输入数组的形状)
feed_dict:允许调用者覆盖图中指定张量的值,提供给placeholder(占位符)使用。
啥意思?有点懵……没关系,一步一步来。
1、fetchs的问题
我们之前在run()中运行的是一个数,比如y,那我们同时运行多个数字呢?这时候就需要用到fetchs,看例子:
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
with tf.Session() as sess:
print(sess.run([a,b,y]))#同时运行a,b,y
[1, 2, 3]
结果就是一个一维数组,把a,b,y的值都运行了出来。
而此时的fetchs形状就是一维数组,这就是fetchs的作用。
此外,run()具有重载的机制,默认为tensor类型,比如:
a=tf.constant(1)
b=3
c=b+a
with tf.Session() as sess:
print(sess.run(c))
一个python中的整型数b和tensor类型a相加得到的是tensor。
2、feed_dict的问题
了解它之前,我们先来了解一下placeholder(占位符),它的作用就是让你指定接下来输入的数据是什么样子的……还是来看例子。
def placeholder(dtype,shape=None,name=None)
重要的参数有dtype、shape,分别指的是数据的类型和数据的形状
a=tf.placeholder(tf.float32,[2,2])#意思就是feed_dict中输入的数据是tf.float32类型,形状为2行2列。
with tf.Session() as sess:
print(sess.run(a,feed_dict={a:[[1,2],[3,4]]}))#feed_dict是一个字典,输入数据,类型与a一致
[[1. 2.]
[3. 4.]]
所以,简单的说,feed_dict的作用就是在你输入数据不确定的情况下,提前占个坑。用placeholder提供占位。
5.张量
由本文开始的例子可以看到,打印出的结果为:
import tensorflow as tf
import numpy as np
a=tf.constant(1)
b=tf.constant(2)
y=tf.add(a,b)
print(y)
Tensor(“Add:0”, shape=(), dtype=int32)
包括三部分:即op,数据形状、数据类型。
至于形状和类型有哪些,这个和python大同小异……不一一列举了,直接百度吧……
举个简单的例子:
import tensorflow as tf
import numpy as np
a=tf.placeholder(tf.float32,[2,2])
b=tf.placeholder(tf.float32,1)
c=tf.constant(3)
print(a.shape)
print(b.shape)
print(c.shape)
(2, 2)
(1,)
()
可以看出来,a是二维数据2行2列,b是一维数组,c是0维。
张量中最最最最最最重要的是数据形状的改变,一般有静态形状和动态形状两种。
静态形状指的是在张量形状不确定的情况下,可对数据形状改变,但是张量的形状一旦确定,则不能改变。
tensor.set_shape()
什么叫不确定的数据形状呢?比如:
a=tf.placeholder(tf.float32,[None,2])#不确定是几行2列,因为有None
这时候我们就可以对其进行静态修改,但是注意因为只有行是不确定的,所以只能改变行,不能改变列。比如,我们改成3行2列。
a.set_shape([3,2])
这样就可以改成3行2列,这样数据的形状就确定了,不能再修改了。
那么如果我想进行修改怎么办呢?我想改成1行6列(只能修改成1行6列或者2行3列或者6行一列,因为得保证数量同),咋办?这就需要用到动态形状。
动态形状指的是创建一个新的张量,注意,是创建,不是修改,这一点和python中的reshape不同。
tf.reshape()
比如,我们想修改 创建成1行6列的:
a_reshape=tf.reshape(a,[1,6])
那么改成1行5列行不?不行!!!。
注意:创建后的张量一定要保持元素数量的匹配,也就是说原先是3行2列的,有6个元素。那么修改后的也必须是6个元素,可以是1行6列,6行1列,2行3列。
本文地址:https://blog.csdn.net/weixin_44010678/article/details/107162102