【tensorflow】模块—基础—计算图、张量、session、constant、variable、placeholder、feed

Tensorflow基础

TensorFlowTM是一一个开放源代码软件库,用于进行高性能数值计算借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、GPU、TPU) 和设备(桌面设备、服务器集群、移动设备、边缘设备等).

TensorFIlowTM最初是由Google Brain团队(隶属于Google的AI部门)中的研究人员和工程师开发的,可为机器学习和深度学习提供强力支持.

TensorFlow的概念

TensorFlow = Tensor F low

  • Tensor张量

    • 数据结构:多维数组
  • Flow流
    • 计算模型:张量之间通过计算而转换的过程

TensorF low是一个通过计算图的形式表述计算的编程系统

  • 每一个计算都是计算图上的一个节点
  • 节点之间的边描述了计算之间的关系

计算图(数据流图)的概念

计算图是- -个有向图,由以下内容构成:

  • 一组节点,每个节点都代表一个操作,是一种运算
  • -组有向边,每条边代表节点之间的关系(数据传递和控制依赖)

TensorF low有两种边:

  • 常规边(实线) :代表数据依赖关系。-个节点的运算输出成为另-个节点的输入,两个节点之间有tensor流动(值传递)
  • 特殊边(虚线) :不携带值,表示两个节点之间的控制相关性。比如,happens-before关系, 源节点必须在目的节点执行前完成执行
#一个简单的计算图node1=tf.constant(3.0,tf.float32,name='node1')node2=tf.constant(4.0,tf.float32,name='node2')node3=tf.add(node1,node2)print(node3)  #输出一个张量结构#result:Tensor("Add:0", shape=(), dtype=float32)
#建立对话并显示结果sess=tf.Session()print("运行sess.run(node1)的结果",sess.run(node1))#result:运行sess.run(node1)的结果 3.0#更新变量并返回计算结果print("运行sessrun(node3):",sess.run(node3))#关闭sessionsess.close()  #释放内存资源#result:运行sessrun(node3): 7.0

张量的概念

在TensorFlow中, 所有的数据都通过张量的形式来表示

从功能的角度,张量可以简单理解为多维数组

  • 零阶张量表示标量(scalar) ,也就是一-个数;
  • 一阶张量为向量(vector) ,也就是一维数组;
  • n阶张量可以理解为- -个n维数组;

张量并没有真正保存数字,它保存的是计算过程

张量的属性

Tensor("Add:O", shape=(), dtype=float32)
  • 名字(name)

    'node:soc_ output”: node节点名称,src_ _output来自节点的第几个输出

    "Add:0"表示节点的名字交’Add’, 0 0 0来自节点的第 个输出

  • 形状(shape):可选的

    张量的维度信息,shape=(), 表示是标量

  • 类型(type):可选的

    每一个张量会有一个唯一的类型

    TensorF I ow会对参与运算的所有张量进行类型的检查,发现类型不匹配时会报错

张量的形状

三个术语描述张量的维度:阶(rank)、形状(shape)、、 维数(dimens ion number)

形状 维数 例子
0 () 0-D 4
1 ( D 0 D0 D0) 1-D [ 2 , 3 , 5 ] [2,3,5] [2,3,5]
2 ( D 0 , D 1 D0,D1 D0,D1) 2-D [ [ 2 , 3 ] , [ 3 , 4 ] ] [[2,3],[3,4]] [[2,3],[3,4]]
3 ( D 0 , D 1 , D 2 D0,D1,D2 D0,D1,D2) 3-D [ [ [ 7 ] ] , [ [ 3 ] ] , [ [ 2 ] ] , [ [ 4 ] ] ] [[[7]],[[3]],[[2]],[[4]]] [[[7]],[[3]],[[2]],[[4]]]
N ( D 0 , D 1 , . . . , D n − 1 D0,D1,...,Dn-1 D0,D1,...,Dn−1) n-D 形为 ( D 0 , 1 D 1... , D n − 1 ) (D0,1D1...,Dn-1) (D0,1D1...,Dn−1)的张量
tens1=tf.constant([[[1,2,2],[2,2,3]],                 [[3,5,6],[5,4,3]],                  [[7,0,1],[9,1,9]],                  [[11,12,7],[1,3,14]]],name='tens1') #名字在可视化的时候可以显示#语句中包含[]{}()括号中间换行的不需要使用多行链接符print(tens1)#result:Tensor("tens1:0", shape=(4, 2, 3), dtype=int32)print(tens1.get_shape())#result:(4, 2, 3)

获取张量的元素

  • 阶为1的张量等价于向量;
  • 阶为2的张量等价于矩阵,通过t[i, j]获取元素;
  • 阶为3的张量,通过t[i, j, k]获取元素;
tens2 = tf. constant ([[[1, 2], [2, 3]], [[3,4], [5, 6]]])sess = tf. Session()print (sess. run(tens2)[1, 1,0])sess. close()#result:5

张量的类型

TensorF low支持14种不同的类型

  • 实数tf. float32,tf. float64
  • 整数tf. int8, tf. int16, tf. int32,tf. int64,tf. uint8
  • 布尔tf. bool
  • 复数tf. comp I ex64,tf. comp lex128

默认类型:

  • 不带小数点的数会被默认为int32
  • 带小数点的会被默认为f loat32

注意:TensorFlow会对参与运算的所有张量进行类型的检查,发现类型不匹配时会报错。张量对类型的要求很高,栗子

a = tf. constant([1, 2],name="a")    #整型b = tf. constant([2.0, 3.0],name="b") #浮点型result=a  b

结果报错:

>ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("b:0", shape=(2,), dtype=float32)'

操作

  • 计算图中的节点就是操作(Operation)

    • -次加法是一个操作
    • -次乘法也是一个操作
    • 构建一些变量的初始值也是一一个操作
  • 每个运算操作都有属性,它在构建图的时候需要确定下来
  • 操作可以和计算设备绑定,指定操作在某个设备上执行
  • 操作之间存在顺序关系,这些操作之间的依赖就是“边”
  • 如果操作A的输入是操作B执行的结果,那么这个操作A就依赖于操作B
#本例用到了TensorBoard,具体使用后面讲解tf.reset_default_graph() #清除default graph 和不断增加的节点(对当前对话图进行重置,只能看到下面的)#定义变量aa = tf.Variable(1, name="a")#定义操作b为a 1b = tf.add(a, 1, name="b")#定义操作c为*4c = tf.multiply(b, 4, name="c")#定义d为c-bd = tf.subtract(c, b, name="d")# # Logdir改为自己机器上的合适路径# logdir='D:/1og'   # #生成一个写日志的writer,并将当前的TensorFLow计算图写入日志。# writer = tf. summary. FileWriter(logdir ,tf.get_ default_ _graph())# writer . close()   

会话Session

会话拥有并管理TensorF low程序运行时的所有资源

当所有计算完成之后需要关闭会话帮助系统回收资源

#定义计算图tens1 = tf.constant([1,2,3])#创建一个会话sess = tf.Session()#使用这个创建好的会话来得到关心的运算的结果。比如可以调用sess. run(result)print(sess.run(tens1))#关闭会话使得本次运行由使用到的资源可以被释放sess.close()#result:[1 2 3]

需要明确调用Sess ion. close ()函数来关闭会话并释放资源

当程序因为异常退出时,关闭会话函数可能就不会被执行从而导致资源泄漏

所以可以进行如下操作:

会话典型模式1

#定义计算图tens1 = tf.constant([1,2,3])#创建一个会话sess = tf.Session()try:    #使用这个创建好的会话来得到关心的运算的结果。比如可以调用sess. run(result)    print(sess.run(tens1))except:    print("Exception!")#关闭会话使得本次运行由使用到的资源可以被释放finally:    sess.close()

会话典型模式2

node1 = tf.constant(3.0,tf.float32 ,name="node1" )node2 = tf.constant(4.0, tf.float32, name="node2" )result = tf.add( node1, node2)#创建一个会话,并通过Python中的上下文管理器来管理这个会话with tf.Session() as sess:    #使用这创建好的会话来计算关心的结果    print(sess.run(result))    #不需要再调用Session.cLose()函数来关闭会话#当上下文退出时会话关闭和资源释放也自动完成了

指定默认的会话

TensorFlow不会自动生成默认的会话,需要手动指定

当默认的会话被指定之后可以通过tf.Tensor.eval函数来计算一个张量的取值

node1=tf.constant(4.0,tf.float32,name='node1')node2 = tf.constant(4.0,tf.float32, name= "node2")result = tf .add(node1, node2)sess = tf .Session()with sess.as_default():  #as_default设置为默认会话    print(result.eval())  #.eval()获取张量结构中的值,是内置函数 

下面代码也可以完成相同的功能

sess=tf.Session()#下面两个命令具有相同的功能print(sess.run(result))print(result.eval(session=sess))  

交互式环境下设置默认会话

在交互式环境下,Python脚本或者Jupyter编辑器下,通过设置默认会话来获取张量的取值更加方便。

tf. Interact iveSession使用这个函数会自动将生成的会话注册为默认会话

node1=tf.constant(4.0,tf.float32,name='node1')node2 = tf.constant(4.0,tf.float32, name= "node2")result = tf .add(node1, node2)sess = tf. InteractiveSession()   #这也是一个默认会话print(result.eval())       #默认会话,里面不需要加会话参数了sess.close()

常量constant

在运行过程中值不会改变的单元,在TensorF low中无须进行初始化操作

创建语句:constant_ name = tf. constant (value)

a = tf.constant(1.0, name='a')b = tf.constant(2.5, name='b')c = tf.add(a, b, name='c')sess = tf .Session( )c_value = sess.run(c) print(c_value)sess. close( )

变量 variable

变量初始化

在运行过程中值会改变的单元,在TensorF low中须进行初始化操作

创建语句:name_variable = tf. Variable (value,name)#注意V是大写

个别变量初始化:init_op = name_variable. initializer ()

所有变量初始化:init_op = tf.global_variables_initializer()

#变量node1  =tf.Variable(5.0,tf.float32,name='node1')node2  = tf.Variable(4.0,tf.float32, name= "node2")result = tf.add(node1, node2,name='add')sess = tf .Session( )#变量初始化init=tf.global_variables_initializer() sess.run(init)      #将前面所定义的变量初始化 #如果不执行sess.run(init),前面的都是静态图:node1,node2,result,init;系统会报错 print(sess.run(result))

注意:

以上代码在Session对话变量后,增加了一个init初始化变量,并调用会话的run命令对参数进行初始化。

变量的赋值

  • 与传统编程语言不同,TensorFlow中的变量定义后,一般无需人工赋值,系统会根据算法模型,训练优化过程中自动调整变量对应的数值
  • 后面在将机器学习模型训练时会更能体会,比如权重We i ght变量w,经过多次迭代,会自动调

epoch = tf.Variable(O,name=' epoch' ,trainable=False)这个变量不参加训练

  • 特殊情况需要人工更新的,可用变量赋值语句

update_ op = tf.assign(variable_ _to_ be_ updated, new_ value)(需要被更新的变量,新值)

栗子:

#通过变量赋值输出1、2、3...10value = tf .Variable(0, name="value")one = tf . constant(1)new_value = tf .add(value, one)update_value = tf.assign(value, new_value)init = tf.global_variables_initializer()  #所有变量初始化with tf .Session() as sess:    #打开Session会话    sess. run(init)            #运行变量初始化    for _ in range(10):         sess. run(update_value )   #运行 update_value操作(更新value的值)        print(sess . run(value))   #打印运行结果

作业题

如何通过Tensor Flow的变量赋值计算:1 2 3 … 10=?

#如何计算1 2 3 。。 10value=tf.Variable(0,name='value')    #动态变量value,设初始值为0one=tf.constant(1)                   #常量为1new_value=tf.add(value,one,name='new_value')   #变量 1update_value=tf.assign(value,new_value)        #将变量 1赋值给valueres=tf.Variable(0,name='res')       #变量,用作结果和,初始值为0temp_value=tf.add(res,value)        # res value ,加法操作update_res_value=tf.assign(res,temp_value)  #将 res value  重新赋值给resinit=tf.global_variables_initializer()with tf.Session() as sess:    sess.run(init)    for _ in range(10):        sess.run(update_value)     #变量value更新一次        sess.run(update_res_value) #和res更新一次        print(sess.run(res))

1 2 3 4 … n

# 我还看不明白import tensorflow.compat.v1 as tfvalue = tf.Variable(0,name="value")sum = tf.Variable(0,name="sum")one = tf.constant(1)tf.disable_v2_behavior()n = tf.placeholder(tf.int32,name='n') new_value = tf.add(value,one)update_value = tf.assign(value,new_value)new_sum = tf.add(sum,value)update_sum = tf.assign(sum,new_sum)    init = tf.global_variables_initializer()with tf.Session() as sess:    sess.run(init)    number = int(input("请输入数字: "))    for i in range(number):        sess.run(update_value)        sess.run(update_sum)    result = sess.run(sum,feed_dict={n:number})    print(result)

占位符placeholder

  • TensorF low中的Var iable变量类型,在定义时需要初始化,但有些变量比如训练数据,这时候需要用到占位符

  • *tf. placeholder占位符,是TensorF I ow中特有的一种数据结构,类似动态变量,函数的参数、或者C语言或者Python语言中格式化输出时的“%”占位符

  • TensorF low占位符P laceholder,先定义一种数据,其参数为数据的Type和Shape

    占位符Placeho lder的函数接口如下:

    tf.placeholder(dtype, shape=None, name=None)

    x = tf.placeholder(tf.float32, [2,3], name='tx')#此代码生成一个2x3的二维数组,矩阵中每个元素的类型都是tf. float32,内部对应的符号名称是tx

Feed 提交数据

如果构建了-个包含placeholder操作的计算图,当在session中调用run方法时,placeholder占用的变量必须通过feed_dict 参数传递进去,否则报错

placeholder不需要做变量初始化

a=tf.placeholder(tf.float32,name='a')b=tf.placeholder(tf.float32, name='b')c=tf.multiply(a,b,name='c')init = tf.global_variables_initializer()with tf.Session() as sess:    sess.run(init)    #变量初始化,在这里,没有用到变量,注释掉这行,也不会报错    #通过feed_dict的参数传值,按字典格式    result = sess.run(c,feed_dict={a:8.0, b:3.5})    print(result)

多个操作可以通过一次feed完成执行

a=tf.placeholder(tf.float32,name='a')b=tf.placeholder(tf.float32, name='b')c=tf.multiply(a,b,name='c')d=tf.subtract(a,b,name='d')init = tf.global_variables_initializer()with tf.Session() as sess:    #sess.run(init)    #通过feed_ dict的参数传值,按字典格式    result = sess.run([c,d], feed_dict={a:[8.0, 2.0, 3.5], b:[1.5, 2.0, 4.0]})    #[c,d]将两个操作放入一个列表    #{a:[8.0, 2.0, 3.5], b:[1.5, 2.0, 4.0]},a & b对应的不再是数值而是向量    print(result)    #取结果中的第一个    print(result[0])
>[array([12.,  4., 14.], dtype=float32), array([ 6.5,  0. , -0.5], dtype=float32)]>[12.  4. 14.]

一次返回多个值分别赋给多个变量

a=tf.placeholder(tf.float32,name='a')b=tf.placeholder(tf.float32, name='b')c=tf.multiply(a,b,name='c')d=tf.subtract(a,b,name='d')init = tf.global_variables_initializer()with tf.Session() as sess:    sess.run(init)    #返回的两个值分别赋值给两个变量    rc,rd = sess.run([c,d], feed_dict={a:[8.0, 2.0, 3.5], b:[1.5, 2.0, 4.0]})    print("value of c=",rc,'value of d=',rd)

结果是

>value of c= [12.  4. 14.] value of d= [ 6.5  0.  -0.5]

TensorBoard: TensorFlow可视化工具

  • TensorBoard是TensorF low的可视化工具
  • 通过TensorF low程序运行过程中输出的日志文件可视化TensorFIow程序的运行状态
  • TensorBoard和TensorF low程序跑在不同的进程中

案例:在TensorBoard中查看图的结构

#清除default graph和不断增加的节点tf.reset_default_graph()#logdir改为自己机器上的合适路径logdir='D:/1og'#定义一个简单的计算图,实现向量加法的操作input1 = tf .constant([1.0, 2.0,3.0],name="input1")input2 = tf .Variable(tf.random_uniform([3]), name="input2")output = tf .add_n([input1, input2],name="add")#生成一个写日志的writer,并将当前的TensorFlow计算图写入日志。writer = tf.summary.FileWriter(logdir,tf.get_default_graph())#(日志的路径,得到图的信息)writer.close( )

启动TensorBoard

TensorBoard不需要额外安装,在TensorF I ow安装时已自动完成

在Anaconda Prompt中先进入日志存放的目录(非常重要! ! ! )

再运行TensorBoard,并将日志的地址指向程序日志输出的地址

命令: tensorboard --logdir=/path/log

启动服务的端口默认为6006;使用-- port参数可以改编启动服务的端口teng

机器学习相关术语

训练

训练模型表示通过有标签样本来学习(确定) 所有权重和偏差的理想值

在监督式学习中,机器学习算法通过以下方式构建模型:

  • 检查多个样本并尝试找出可最大限度地减少损失的模型
  • 这-过程称为经验风险最小化

损失

  • 损失是对糟糕预测的惩罚:损失是一个数值,表示对于单个样本而言模型预测的准确程度

  • 如果模型的预测完全准确,则损失为零,否则损失会较大

  • 训练模型的目标是从所有样本中找到一-组平均损失“较小”的权重和偏差

定义损失函数

L 1 L_1 L1​损失:基于模型预测的值与标签的实际值之差的绝对值

平方损失:一种常见的损失函数,又称为L2损失

均方误差(MSE)指的是每个样本的平均平方损失

M S E = 1 N ∑ ( x , y ) ∈ D ( y − p r e d i c t i o n ( x ) ) 2 MSE=\frac{1}{N}\sum_{(x,y)\in D}(y-prediction(x))^2 MSE=N1​(x,y)∈D∑​(y−prediction(x))2

模型训练与降低损失

训练模型的迭代方法

推理:执行预测 特征 模型-预测函数 计算损失 标签 计算参数更新

模型训练要点

  • 首先对权重w和偏差b进行初始猜测
  • 然后反复调整这些猜测
  • 直到获得损失可能最低的权重和偏差为止

收敛(训练停止)

在学习优化过程中,机器学习系统将根据所有标签去重新评估所有特征,为损失函数生成一-个新值,而该值又产生新的参数值。

通常,您可以不断迭代,直到总体损失不再变化或至少变化极其缓慢为止。这时候,我们可以说该模型已收敛

梯度下降法

梯度:一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向( 此梯度的方向)变化最快,变化率最大。

学习率

沿着负梯度方向进行下一步探索,前进多少合适?

用梯度乘以一个称为学习速率(有时也称为步长)的标量,以确定下一-个点的位置

例如:如果梯度大小为 2.5 2.5 2.5, 学习速率为 0.01 0. 01 0.01,则梯度下降法算法会选择距离前一;个点 0.025 0.025 0.025的位置作为下一个点

超参数

  • 在机器学习中,超参数是在开始学习过程之.前设置值的参数,而不是通过训练得到的参数数据

  • 通常情况下,需要对超参数进行优化,选择- -组好的超参数,可以提高学习的性能和效果

  • 超参数是编程人员在机器学习算法中用于调整的旋钮

  • 典型超参数:学习率、神经网络的隐含层数量…
    ————————————————————————————————

tensorflow的套路

  1. 变量,常数修改成tensorflow支持运算的格式—张量
  2. 变量初始化、常量初始化
  3. 创建会话Session,使常量、变量、运算操作有执行区域(占据内存)
  4. Session中执行操作

来源:https://www.icode9.com/content-4-761151.html

(0)

相关推荐