TensorFlow 学习

记录自己学习TensorFlow的过程,因为正在做的项目需要将机器学习与esp32结合使用,想要将机器学习的过程也放在esp32上实现。因为tensorflow lite可以实现代码向嵌入式设备的转换,所以开始学习tensorflow。目前内容都基于郑泽宇、顾思宇老师的著作:《TensorFlow实战Google深度学习框架》

一、基础知识:

简而言之,TF是一种开源计算框架,该框架可以很好的实现各种深度学习的算法。

  • 最大优势之一:对于大规模模型训练,可以简单实现并行,同时用不同的硬件资源,同步或异步地更新模型状态和参数。将一个串行的TF算法转变为并行成本也很低。
  • 缺点:有些复杂,实现同样功能pytorch的代码量可能只有十分之一。

1.1 计算模型--计算图

  • tensor是张量,可以理解为多维数组
  • flow是流动,因为张量之间通过计算互相转化

TF中所有计算,都会被转化为计算图上的节点。节点之间的边(连线),描述了计算之间的以来关系。

40

 这里表示了a+b。a,b指向加法算子add,add依赖于a,b但是ab不依赖与add。

TF会自动将定义的计算转化为计算图上的节点

在TF中系统会自动维护一个默认的计算图,可以通过tf.get_default_graph获取

a= tf.constant([1,2],name="a")
print(a.graph is tf.get_default_graph())

 还可以通过tf.Graph创建新的计算图,并且不用图上的张量和运算不会共享。

# 在计算图g1中,定义变量v,设初值为0
g1=tf.Graph()
with g1.as_default():
    v=tf.get_variable("v",shape=[1],initializer=tf.zeros_initializer)

# 在计算图g2,也定义变量v,但设初值为1
g2=tf.Graph()
with g2.as_default():
    v=tf.get_variable("v",shape=[1],initializer=tf.ones_initializer)

# 读取g1计算图中的v
with tf.Session(graph=g1) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("",reuse=True):
        print(sess.run(tf.get_variable("v")))
        
# 读取g2计算图中的v
with tf.Session(graph=g2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("",reuse=True):
        print(sess.run(tf.get_variable("v")))

shape=[1]代表变量的大小,若为shape[1,4],会产生四个变量。

计算图还可以通过tf.Graph.device指定运行计算的设备。下面的程序将加法计算跑在GPU上:

g=tf.Graph()
with g.device('/gpu:0'):
    result = 1 + 2

1.2 数据模型——张量

1.2.1 张量概念

零阶张量表示标量,也就是一个数。一阶张量为向量,也就是一个一维数组。但张量在TF中的实现并不是直接采用数组的形式,他只是对运行算结果的引用。在张量中并没有真正保存数字,他保存的是如何得到这些数字的计算过程。例如运行如下计算加法的代码并不会的道家发的结果,而是对结果的引用:

a= tf.constant([1,2],name="a")
b= tf.constant([2,3],name="b")
result=tf.add(a,b,name="add")
print(result)

 结果如下:

Tensor("add:0", shape=(2,), dtype=int32)

从结果可以看出:一个张量中主要保存了三个属性:名字,维度,类型。

名字不仅是一个张量的唯一标识符,它同样也给出了这个张量是如何计算出来的。因为TF所有计算都可以通过计算图的模型来建立,而计算图上的每一个节点代表了一个计算,计算的结果就保存在张量之中。所以张量和计算图上节点所代表的计算结果是对应的。这样张量的命名就可以通过:'node:src_output' 的形式来给出。node为节点的名称,src_output表示当前张量来自节点的第几个输出。比如上面代码的结果:“add:0”代表add节点的第一个输出。

维度,上面结果中的shape=(2,)说明张量是一个一维数组,这个数组的长度为2。

类型,每一个张量会有一个唯一的类型。TF会对所有参与运算的张量进行类型的检查,不匹配时会报错。如下:一个是整数,一个是浮点

import tensorflow as tf
a = tf.constant([1,2],name='a')
b = tf.constant([3.0,2.0],name='b')
result = a+b

可以通过a = tf.constant([1,2],name='a',dtype=tf.float32)对a的类型进行改变。

TF中共有十四种不同类型:

  • tf.float32,tf.float64.
  • tf.int8,tf.int16,tf.int32,tf.int64,tf.uint8(八位无符号整型)
  • tf.bool
  • tf.complex64,tf.complex128

1.2.2 张量的使用

张量使用主要可以分为两大类:

  1. 对中间计算结果的引用:以下为使用张量和不适用张量记录中间结果的代码对比:
#使用张量记录中间结果:
a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

#直接计算
result = tf.constant([1.0,2.0],name="a")+tf.constant([2.0,3.0],name="b")

a,b就是对于常量生成这个运算结果的引用。当计算的复杂度增加时,通过张量来引用中间结果可以大大提升代码可阅读性

    2.当计算图构造完成后,张量用来获得计算结果,也就是会得到真实的数字,虽然张良本身没有存储具体数字,但是根据之后将会介绍的会话(session),就可以得到具体的数字。

1.3 运行模型--会话(session)

会话用来执行定义好的计算。session拥有并管理TF程序运行时的所有资源。当计算完成之后需要关闭会话来帮助系统回收资源。

利用会话的一般格式:

  1. 创建会话
  2. 用run计算出会话中感兴趣的值
  3. 结束会话
a=tf.constant(1,name="a")
b=tf.constant(2,name="b")
result=a+b

with tf.Session() as sess:  #不必再调用session.close
    print(sess.run(result))

还可以用eval方法直接计算一个张量的值。

注意:

  • eval是张量的方法,run是会话的方法,而会话一般属于默认运算图(如果没有指定)。
  • TF会自动生成默认运算图,但不会自动生成默认的会话,必须指定。
a=tf.constant(1,name="a")
b=tf.constant(2,name="b")
result=a+b

sess=tf.Session()
print(result.eval(session=sess)) # 必须有session=sess选项,No default session.
sess.close()
a=tf.constant(1,name="a")
b=tf.constant(2,name="b")
result=a+b

sess=tf.InteractiveSession() # 该函数自动将生成的会话注册为默认会话
print(result.eval())
sess.close()

注意:

  1. 指定会话,在会话中run
  2. 指定会话,在会话中eval目标张量
  3. 指定默认会话,直接eval目标张量
sess = tf.Session()
with sess.as_default():

with版本的设置默认会话。

ConfigProto Protocol Buffer可以增强配置

该结构可以配置并行的线程数,GPU分配策略,运算超时时间等参数。

其中最常用的是以下两个参数:

  • 布尔型参数log_device_placement

当其为true时,日志将会记录在每个节点被安排在哪个设备上,方便调试。

  • 布尔型参数allow_soft_placement

默认为False,当其为true时,只要以下任意一个条件成立,GPU上的运算都会放到CPU上运行:

  1. 运算在GPU上无法运行
  2. 没有指定GPU资源,比如只有一个GPU,但运算指定在第二个GPU上执行
  3. 运算输入包含对CPU运算结果的引用。
config = tf.ConfigProto(allow_soft_placement=True,
                       log_device_placement=True)
sess1 = tf.InteractiveSession(config=config) # 创建默认会话
sess2 = tf.Session(config=config) # 创建一般会话

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值