tensorflow基础

来源:互联网 发布:网络综艺为什么这么火 编辑:程序博客网 时间:2024/06/08 18:26

环境:windows 7
tensorflow-GPU 1.3

Numpy数组

tensorflow的数据类型是基于numpy的数据类型。实际上,语句np.int32 == tf.int32的结果为True。对于数值类型和布尔类型,Tensorflow和Numpydtype属性完全一致。然而在Numpy中并无tf.string精确对应的类型,这是由于Numpy处理字符串的方式决定的。也就是说,Tensorflow可以从Numpy中完美地导入字符串数组,只是不要在Numpy中显式指定dtype的属性。

import numpy as np
#元素类型为32位整数的0阶张量t_0 = np.array(50,dtype=np.int32)
t_0
array(50)
#元素为字节字符串类型的1阶张量#注意:在numpy中使用字符串,不要显式地指定dtype属性t_1 = np.array([b"apple",b"peach",b"grape"])
t_1
array([b'apple', b'peach', b'grape'],      dtype='|S5')
#元素为布尔类型的1阶张量t_2 = np.array([[True,False,False],                [False,False,True],                [False,True,False]],                 dtype = np.bool)
t_2
array([[ True, False, False],       [False, False,  True],       [False,  True, False]], dtype=bool)

所谓张量即为n维矩阵的抽象,1D张量等价于向量,2D张量等价于矩阵。

张量的形状

这里的“形状”是Tensorflow的专有术语,它同时刻画了张量的阶(维)数以及每一维的长度。例如,列表[2,3]描述了一个两阶张量的形状,
其第一维上的长度为2,第二维上的长度为3.注意,无论是元组(用括号表示),还是列表[用方括号表示],都可以定义张量的形状。

#指定0阶张量(标量)的形状s_0_list = []s_0_tuple = ()
#一个长度为3 的向量的形状s_1 = [3]
#3*2的矩阵s_2 = (3,2)

除了能够将张量的每一维指定为固定 的长度,也可以将None作为某一维的值,使该张量具有可变长度

#具有任意长度的向量形状s_1_flex = [None]
#行数任意,列数为3的矩阵的形状s_2_flex = (None,3)
#第1维长度为2,第二维和第三维长度任意的3阶张量s_3_flex = [2,None,None]

如果需要在数据流图中获取某一张量的形状,可以使用tf.shape OP。
它的输入为希望获取其形状的Tensor对象,输出为一个int32类型的向量

import tensorflow as tf
#...创建某种神秘张量#获取上述张量的形状#shape = tf.shape(mystery_tensor,name="mystery_shape")

Tensorflow的Operation

tensorflow Operation也称Op,是对一些tensor对象执行运算的节点。调用时需要传入计算的所有的tensor的参数以及正确创建Op的任何附加信息

import tensorflow as tfimport numpy as np
#初始化一些计算中需要使用的张量a = np.array([2,3],dtype=np.int32)b = np.array([4,5],dtype=np.int32)#利用tf.add()初始化一个add的Op#变量c指向该Op输出的tensor对象的句柄c = tf.add(a,b)
#创建一个session对象执行上述的数据流图sess = tf.Session()output = sess.run(c)sess.close()
output
array([6, 8])

如c = tf.add(a,b,name=”my_add_op”)赋予了名称的属性,这样可以的tensorBoard等工具可以引用该Op

运算符的重载

这里写图片描述

tensorflow的Graph对象

研究tensorflow的Graph对象,学习如何创建更多的数据流图,以及如何让多个流图协同工作

#创建Graph非常简单,它的构造方法不需要接受任何参数import tensorflow as tf#创建一个新的数据流图g = tf.Graph()

Graph.as_default()方法访问其上下文管理器,为其添加Op。结合with语句,可利用上下文管理器通知Tensorflow
我们需要将一些Op添加到某个特定的Graph对象中

with g.as_default():    #像往常一样的创建一些OP;它们将被添加到Graph的对象g中    a = tf.mul(2,3)    ...

那在之前的例子中并没有指定将Op添加到哪个Graph中?原因是,为了方便起见,当Tensorflow库被加载时,它会自动的创建一个Graph对象,并将
其作为默认的数据流图。因此在Graph.as_default上下文管理器之外定义的任何的Op、Tensor对象都会被自动放置在默认的数据流图中。

#放置在默认的数据流图in_default_graph = tf.add(1,2)#放置在数据流图g中with g.as_default():    in_graph_g = tf.mul()#由于不在with块中,下面的OP将放置在默认的数据流图中also_in_default_graph = tf.sub(5,1)# 如果希望获取默认的数据流图的句柄,可以使用tf.get_default_graphdefault_graph = tf.get_default_graph

如果需要定义多个相互之间不存在依赖的关系模型,则创建多个Graph对象。

1.正确的实践--创建新的数据流图,忽略默认的数据流图import tensorflow as tfg1 = tf.Graph()g2 = tf.Graph()with g1.as_default():    #定义g1中的OP、张量等    ...with g2.as_default():    #定义g2中的OP、张量等    ...2.正确的实践--获取默认数据流图的句柄import tensorflow as tfg1 = tf.get_default_graph()g2 = tf.Graph()with g1.as_default():    #定义g1中的OP、张量等    ...with g2.as_default():    #定义g2中的OP、张量等    ...3.错误是实践--将默认数据流图和用户创建的数据流图混合使用import tensorflow as tfg2 = tf.Graph() #定义默认数据流图的OP、张量等...with g2.as_default():    #定义g2中的OP、张量等    ...

此外,从其他Tensorflow脚本中加载之前定义的模型,并利用Graph.as_graph_defaul
和tf.import_graph_def()函数将其赋值给Graph对象也是可行的。

tensorflow Session

Session类负责数据流图的执行
构造方法tf.Session()接收3给可选参数
》》》target指定了所要使用的执行引擎。对于大多数应用,该参数取为默认的空字符串。
在分布式设置中使用Session对象时,该参数用于连接不同的tf.train.Server实例
》》》graph参数指定了将要在Session对象中加载的Graph对象,其默认值为None,表示
使用当前默认数据流图。当使用多个数据流图时,最好的方法是显式传入你希望
运行的Graph对象(而非在一个with语句块内创建Session对象)
》》》config参数允许用户指定配置Session对象所需的项目,如限制CPU或GPU是使用
数目,为数据流图设置优化参数以及日志选项等。

#在典型的Tensorflow程序中创建Session对象时无需改变任何默认构造参数import tensorflow as tf#创建Op、Tensor对象(使用默认数据流图)a = tf.add(2,5)b = tf.multiply(a,3)#利用默认数据流图启动一个Session对象sess = tf.Session()#与默认等价sess = tf.Session(graph=tf.get_default_graph())sess.run(b)    #返回21sess.close()   #关闭,释放资源

Seesion.run()方法接受一个fetches,以及其他三个可选参数:feed_dict、options和run_metadata。

1.fetches参数
fetches参数接受任意的数据流图元素(OP或者Tensor对象),后者指定了用户希望执行的对象。如果请求对象为Tensor对象,则run()的输出将为一numpy数组;如果请求对象为一OP,则输出将为None。
在上面的例子中,我们将fetches参数取为张量b(tf.multiply Op的输出)。tensorflow便会得到通知,Session对象应当找到为计算b的值所需的全部的节点,顺序执行这些节点,然后将b的值输出。
除了利用fetches获取Tensor对象输出外,还将看到这样的例子:有时也会赋予fetches一个指向某一个Op的句柄,这是在运行中一种有价值的用法。
tf.initialize_all_variables()便是这样的例子,它会准备将要使用的所有Tensorflow Variable对象。

#执行初始化Variable对象所需的计算,但返回值为Nonesess.run(tf.initialize_all_variables())

2.feed_dict参数
参数feed_dict用于覆盖数据流图中的Tensor对象值,它需要python字典对象作为输入。字典的“键”为指向要被覆盖的Tensor的对象的句柄,而字典的“值”可以是数字、字符串、列表、numpy数组。

import tensorflow as tfa = tf.add(2,5)b = tf.multiply(a,3)sess = tf.Session()#定义一个字典将a的值替换为15replace_dict = {a:15}#运行Session对象,将replace_dict赋值给feed_dictoutput = sess.run(b,feed_dict=replace_dict)sess.close()   #关闭,释放资源
output
45

feed_dict极为有用,这意味着在一个规模较大的数据流图,可以用一些虚构的值对某些部分进行测试。

Session资源的关闭

Session对象调用完后,需要调用其close()方法,将那些不再需要的资源释放

#创建Session对象sess = tf.Session()#运行该数据流图...#关闭数据流图,释放资源sess.close()将Session对象作为上下文管理器加以使用,这样当代码离开其作用域后,该Session对象自动关闭with tf.Session as sess:    #运行该数据流图    ... #Session对象自动关闭

利用占位节点添加输入

之前定义的数据流图并未使用真正的“输入”,它总是相同的数组5和3.我们真正希望做的是从客户那里接纳输入值,这样便可以对数据流图中所描述的变换以各种不同类型数值进行复用,借助占位符可以达到目的。利用tf.placeholder Op可以创建占位符

import tensorflow as tfimport numpy as np#创建一个长度为2,数据类型为int32的占位符a = tf.placeholder(tf.int32,shape=[2],name="my_input")#将该占位符向量视为其他任意Tensor对象,加以使用b = tf.reduce_prod(a,name="prob_b")c = tf.reduce_sum(a,name="sum_c")#完成数据流图的定义d = tf.add(b,c,name="add_d")

调用tf.placeholder()时,dtype参数必须指定,因为需要确保不出现类型不匹配的错误。shape参数可选,其默认值为None,
表示可以接收任意形状的Tensor对象
为了给占位符传入一个实际值,需要使用Session.run()中的feed_dict参数。我们将占位符的输出句柄作为字典的“键”,
希望传入的Tensor对象作为“值”

import tensorflow as tfimport numpy as np#创建一个长度为2,数据类型为int32的占位符a = tf.placeholder(tf.int32,shape=[2],name="my_input")#将该占位符向量视为其他任意Tensor对象,加以使用b = tf.reduce_prod(a,name="prob_b")c = tf.reduce_sum(a,name="sum_c")#完成数据流图的定义d = tf.add(b,c,name="add_d")sess = tf.Session()input_dict = {a : np.array([5,3],dtype = np.int32)}#计算d的值,将input_dict的值传给aoutput = sess.run(d,feed_dict=input_dict)sess.close()
output
23

variable对象

1.创建Variable对象

Tensor对象和Op对象是不可变的,但机器学习任务的本质决定了需要一种机制保存随时间变化的值。Variable对象包含了Session.run()多次调用可持久化的可变张量的值,通过tf.Variable()构造方法完成。

import tensorflow as tf#初始值为3的Variable对象my_var = tf.Variable(3,name="my_variable")add = tf.add(5,my_var)mul = tf.multiply(8,my_var)

Variable对象的初值通常是全0、全1或用随机数填充的阶数较高的张量。为使创建具有这些常见类型初值的张量更加容易,Tensorflow提供了大量的辅助Op

#2X2的0矩阵zeros = tf.zeros([2,2])#长度为6的全1向量ones = tf.ones([6])#3X3X3的张量,其元素服从0~10的均匀分布uniform = tf.random_uniform([3,3,3],minval=0,maxval=10)#3X3X3的张量,其元素服从0均值、标准差为2的正态分布normal = tf.random_normal([3,3,3],mean=0.0,stddev=2.0)# 截尾正态分布tf.truncated_normal()  它不会创建任何均值超过2倍标准差的值#该tensor对象不会返回任何小于3.0或大于7.0的值trunc = tf.truncated_normal([2,2],mean=5.0,stddev=1.0)   #mean士stddev

2.Variable对象的初始化

Variable的状态实际上是由Session管理的,为了使用Variable,必须在一个Session中进行初始化
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
如果需要对Variable的子集进行初始化,可以使用tf.variables_initializer().该函数可以接收一个要进行初始化的Variable的对象

var1 = tf.Variable(0,name="initialize_me")var2 = tf.Variable(1,name="no_initialization")init = tf.variables_initializer([var1],name="init_var1")sess = tf.Session()sess.run(init)

3.Variable对象的修改

要修改Variable的值,可以使用Variable.assign()方法。该方法的作用是为Variable对象赋予新值。要使其生效必须在一个Session中执行

import tensorflow as tf#创建一个初值为1的Variable对象my_var = tf.Variable(1)#创建一个Op,使其每次运行都将该Variable对象乘以2my_var_times_two = my_var.assign(my_var * 2)#初始化Opinit = tf.global_variables_initializer()sess = tf.Session()#初始化Variable对象sess.run(init)#将Variable对象乘以2,并将其返回output1 = sess.run(my_var_times_two)     #输出2#再次相乘output2 = sess.run(my_var_times_two)     #输出4#再次相乘output3 = sess.run(my_var_times_two)     #输出8print(output1,output2,output3)# 自增1sess.run(my_var.assign_add(1))# 自减1sess.run(my_var.assign_sub(1))sess.close()
2 4 8

由于不同的Session对象会独立维护Variable对象的值,因此每一个Session对象都拥有自己的、在Graph对象中定义的Variable对象的当前的值

import tensorflow as tfmy_var = tf.Variable(0)init = tf.global_variables_initializer()# 启动多个Session对象sess1 = tf.Session()sess2 = tf.Session()#sess1的操作sess1.run(init)output1 = sess1.run(my_var.assign_add(5))    #输出5#sess2的操作sess2.run(init)output2 = sess2.run(my_var.assign_add(2))    #输出2sess.close()print(output1,output2)
5 2

如果希望将所有的Variable对象的值重置为初值,则只需再次调用tf.global_variables_initializer()
如果希望将部分的Variable对象的值重置为初值,则只需再次调用tf.variables_initializer()

4.trainable参数

能够自动训练机器学习模型的Optimizer类,意味着这些类将自动修改Variable对象的值,而无需做出显式请求。这个是符合读者的期望。
但是如果要求在Graph对象中的一些Variable对象只可以手动修改,而不允许使用Optimizer类时,可在创建Variable对象时将这些Variable
的参数trainable参数设置为False。

not_trainable = tf.Variable(0,trainable=False)