首先祝自己生日快乐!! 趁着大学最后的一点时间学习一点新的东西,希望自己能坚持下去。

这里记录一点这几天学习中记录下的一些概念以及注意点。

基础概念

  • 计算图(graph)

这是TensorFlow中最为重要的概念,整个TensorFlow是一个通过计算图的形式来进行表述计算的变成系统,每一次计算都是这个图上的一个节点,节点之间的连线是计算之间的依赖关系,数据,或者说Tensor就是沿着这些边 “流动” 的。

对于一个TensorFlow程序来说,一般可以划分为两个阶段,第一个阶段定义图中所有的计算,第二个阶段执行计算。

TensorFlow程序中,系统会自动维护一个默认的计算图,当然也可以自己创建新的计算图,不同的图之间的张量和计算都不会共享。

  • 张量(tensor)

在TensorFlow系统中,所有的数据都会以张量(tensor)的形式表示,从功能上来说,可以简单的将张量理解为多维数组,但是实际的实现不是数组的形式,而是计算结果的引用,也就是说,不是直接保存数字,而是保存一个张量的结构,有名字,维度和类型:

import tensorflow as tf

a = tf.constant([1], name='a')
b = tf.constant([2], name='b')

add_op = tf.add(a, b, name="add1")
print(add_op)

输出:

Tensor("add1:0", shape=(1,), dtype=int32)Tensor("Add:0", shape=(1,), dtype=int32)

第一个add表示是从 add1 计算节点输出的, 后边的0表示该节点的第一个输出, 第二个属性是形状, 像上例中的(1,)就表示输出的是结果是一个一维数组,第三个属性是类型,每个张量都会有一个唯一的类型,TensorFlow会对所有参与计算的张量类型进行类型检查。

  • 会话(session)

使用会话可以执行定义好的计算,也就是之前提到的执行计算部分,会话是用来管理资源的,在计算关闭之后会回收系统资源。一般两种方式:

一:

sess = tf.Session()
....
sess.run()
....
sess.close()

二:这里与Python是一致的,会自动关闭会话并释放资源

with tf.Session() as sess:
    ....
    sess.run()
    ....

暂时想到的内容就这么多,如果以后发现有什么概念很重要的话再进行补充,接下来记录一些我这几天学习中觉得有点重要的内容吧!

不同节点的创建格式

这个问题看起来可能比较简单,实际上因为TensorFlow与之前敲的Python代码还是有点不一样的,所以很容易写的时候突然一个小点就想不起来(我是这样的。。),所以还是都放在一起记录一下:

  • constant(常量节点)

调用格式如下:

constant ( 
    value ,  # 必填项 形式与Numpy数组创建的初始值一致,比如 1, [1, 2], [[1, 2], [3, 4]]等等
    dtype = None ,  # 指定类型,这个类型一定要注意 ,对我这样的新手真的超级坑的,下面详细讲
    shape = None ,  # 指定形状, 当然 一般省略
    name = 'Const' ,  # 名称 
    verify_shape = False # 默认值式False 如果改成 True 则检查value 和dtype是否一致 否抛出错误
)

这里重点说一下TensorFlow的类型,一定要尽量指定清楚类型, 因为类型的检查真的很严格,比如:

a = tf.constant(1, dtype= tf.float32)
# a = tf.constant(1)
b = tf.constant(1.5)

add_op1 = a + b

很简单的两个常量相加 ,如果写成注释的形式结果会报错 类型不匹配,这里不要想当然,一般我们写别的代码,虽然两种的类型分别是float 和int 仍然会进行自动的转化,向精度更高的float转化,Numpy中也是如此,但是TensorFlow中不是!!,我这几天学习的过程中总是烦这个错误,所以记一下,希望看到的人注意这个地方,TensorFlow中进行运算时候一般都用tf.float32类型,所以就算是 2,3 这样的整数,最好也是直接写成 2.0, 3.0这样的形式,避免出错。

  • Variable(变量)

如果计算中的值进行改变,那么就要使用到变量,变量的定义如下,注意变量在使用之前要先进性初始化:

Variable(
    initial_value=None,
    trainable=True,
    collections=None,
    validate_shape=True,
    caching_device=None,
    name=None,
    variable_def=None,
    dtype=None,
    expected_shape=None,
    import_scope=None,
    constraint=None

然鹅我目前只是用到其中一小部分参数来定义变量,(具体的可以看这位大佬的记录:TensorFlow中的变量 )这里我要说的是,注意变量的初始值,变量都是用来改变的嘛,举个例子来说,线性回归 tensorflow还有人维护吗_数组 定义线性模型的时候 这里的 tensorflow还有人维护吗_Tensorflow_02tensorflow还有人维护吗_数组_03就定义成变量 ,然后在过程中修改参数来完成拟合的过程, 所以设置初始值的时候,除了像定义常量一样直接指定具体值,更多是传入随机数值,使用TensorFlow或者Numpy的随机函数创建,或者直接使用 tf.zeros([2, 3]) 这样指定全X数组,关于随机值之类的函数我的另一篇中记录了。

举个例子,计数器的实现:

state = tf.Variable(0, name='counter')
delta = tf.constant(1, name='delta')

add_op = tf.add(state, delta)
ass_op = tf.assign(state, add_op)

init_op = tf.global_variables_initializer()  # 注意初始化全局的变量函数已经更新了 有些教程中还是在使用之前的

with tf.Session() as sess:
    sess.run(init_op)
    for _ in range(5):
        sess.run(ass_op)
        print(sess.run(state))
  • placeholder(占位符)

听这个名字已经表示了它存在的意义,就像是形参一样,先定义好类型,使用的时候再具体传入数值。

调用格式如下:

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

这里的参数列表就简单多了,少了必要的初始值(当然,这也是placeholder存在的意义),对于这个shape ,如果不确定维数(一般都不会确定),可以使用 None 代替,例如 shape = [None, 2] 这样就表示某行2列的常量了,在session中运行的时候,要使用字典的形式传入具体值,例如:

a = tf.placeholder(shape=(None, 2), dtype=tf.float32)  # 未指定行的维数
b = tf.placeholder(shape=(None, 2), dtype=tf.float32)

a_data = np.array([[1.0, 2.0]])     # 使用Numpy生成数据
b_data = np.array([[3.0, 4.0]])

add_op1 = tf.add(a, b)

with tf.Session() as sess:
    print(sess.run(add_op1, feed_dict={a: a_data, b: b_data}))  # 注意如何使用字典形式传入数据

注意辨析Variable和placeholder之间的区别,在实际使用中比较清楚各自的作用,Variable一般用来要进行更新优化的值,比如模型的参数或者偏置之类的,而placeholder则是一般在 会话中传入真实的训练样本。

以上~