TensorFlow基础概念和编程(第一讲)

╰+攻爆jí腚メ 2022-04-13 05:54 636阅读 0赞

TensorFlow基本概念

A machine learning platform for everyone to solve real problems

TensorFlow = Tensor + Flow;

Tensor 张量:代表的是一种多维数组的数据结构

Flow 流:张量之间通过计算而转换的过程

TensorFlow是一个通过计算图的形式表达计算的编程系统,每一个计算都是计算图上的一个点,节点之间的边描述了计算之间的关系。

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

计算图是一个有向图,由以下内容组成:

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

TensorFlow有两种边:

  • 常规边(实线):代表数据依赖关系。一个节点的运算输出成为另一个节点的输入,两个节点之间有tensor流动(值传递)
  • 特殊边(虚线):不携带值,表示两个节点之间的控制相关性。比如,happens-before关系,源节点必须在目的节点执行前完成执行

20181127200155488.jpg

计算图实例

  1. import tensorflow as tf
  2. node1 = tf.constant(3.0, tf.float32, name="node1")
  3. node2 = tf.constant(4.0, tf.float32, name="node2")
  4. node3 = tf.add(node1, node2)
  5. print(node3)

内部会生成一个流图,不会显示,可以利用tensorboard显示。print输出的是“Tensor(“Add_1:0”, shape=(), dtype=float32)”,证明输出的不是一个确定的数据,而是一个张量的结构。为了能够输出我们想要看到的那种数据类型,想要加上一点代码:

  1. import tensorflow as tf
  2. #name虽然可以不填,但是为了方便,我们一般都直接写上
  3. node1 = tf.constant(3.0, tf.float32, name="node1")
  4. node2 = tf.constant(4.0, tf.float32, name="node2")
  5. node3 = tf.add(node1, node2)
  6. print(node3)
  7. #创建对话并显示运算结果
  8. sess = tf.Session()
  9. print(sess.run(node1))
  10. print(sess.run(node3))
  11. #关闭session
  12. #如果下面不进行其他操作了,可以关闭session,可以把相关的资源释放出来,关闭之后就不能再调用session了。需要重新创建对话
  13. sess.close()
  14. #分别输出3.0和7.0

Tensor张量

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

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

  • 零阶张量表示标量,也就是一个数
  • 一阶张量为向量,也就是一维数组
  • n阶张量可以理解为一个n维数组
  • 张量并没有真正保存数字,它保存的是计算过程,前面的node打印出来就可以看出来

张量的属性:“Tensor(“Add_1:0”, shape=(), dtype=float32)”:

  • 这个“Add_1:0”其实是“node:src_output”的具体表现;node表示节点名称,src_output表示来自节点的第几个输出
  • 形状:张量的维度信息,shape=(),表示是标量
  • 类型:每一个张量会有一个唯一的类型
  • TensorFlow会对参与运算的所有张量进行类型的检查,发现类型不匹配时会报错

张量的形状:








































形状 维数 例子

0

() 0-D 4
1 (D0) 1-D [2, 3]
2 (D1,D1) 2-D [[2],[3]]
3 (D0,D1,D2) 3-D [[[1],[2]],[[3]]]
N (D0,D1….Dn-1) n-D n阶的张量

小插曲:直接用get_shape()函数获得…,观察的话太麻烦了…

获取张量中的向量

  1. import tensorflow as tf
  2. tens1 = tf.constant([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], name="tens1")
  3. print(tens1)
  4. sess = tf.Session()
  5. print(sess.run(tens1)[1,1,0])
  6. sess.close()
  7. #输出为Tensor("tens1_1:0", shape=(2, 2, 2), dtype=int32)
  8. #7

张量的类型

TensorFlow支持14种不同的类型

实数:tf.float32, tf.float64

整数:tf.int8, tf.int16, tf.int32, tf.int64

布尔:tf.bool

复数:tf.complex64,tf.complex128

默认类型:不带小数点的数会被默认为int32,带小数点的会被默认为float32。

下面这段代码会报错,因为张量在执行的过程中会对类型进行严格的检查,如果不同类型是不能进行操作的

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

operation

  • 计算中的节点就是操作,一次加法是一次操作,一次乘法也是一次操作,构建一些变量的初始值也是一个操作
  • 每个运算操作都有属性,它在构建图的时候需要确定下来
  • 操作可以和计算设备绑定,指定操作在某设备上执行
  • 操作之间存在顺序关系,这些操作就是依赖“边”
  • 如果操作A的输入是操作B执行的结果,那么操作A就依赖于操作B

看代码:(tensorboard的相关知识后面再进行补充)

  1. import tensorflow as tf
  2. #清除default graph和不断增加的节点
  3. tf.reset_default_graph()
  4. #定义变量A
  5. a = tf.Variable(1, tf.int32, name='a')
  6. b = tf.add(a, 1, name='b')
  7. c = tf.multiply(a, 2, name='c')
  8. d = tf.subtract(c, b, name='d')
  9. #logdir改写自己机器上的合适路径
  10. logdir = r'D:\picture'
  11. #生成一个写日志的writer,并在当前的TensorFlow计算图写上日志
  12. writer = tf.summary.FileWriter(logdir, tf.reset_default_graph())
  13. writer.close()

TensorFlow运行模型—会话

会话拥有并管理TensorFlow程序运行时的所有资源,当所有计算完成之后需要关闭会话帮助系统回收资源。

会话的模式除了上面直接创建一个会话之后还有一种模式:

  1. import tensorflow as tf
  2. node1 = tf.constant(3.0, tf.float32, name="node1")
  3. node2 = tf.constant(4.0, tf.float32, name="node2")
  4. node3 = tf.add(node1, node2)
  5. #创建一个会话,并通过Python的上下文管理器来管理这个会话
  6. with tf.Session() as sess:
  7. #使用这创建的会话来运行关心的结果
  8. print(sess.run(node3))
  9. #不需要再次调用Session.close()函数,在上下文管理器结束的时候系统会默认关闭和释放资源

指定默认的会话

TensorFlow不会自动生成默认的会话,需要手动指定。当默认的会话被指定之后可以通过tf.Tensor.eval()函数来计算一个张量的取值。

  1. import tensorflow as tf
  2. node1 = tf.constant(3.0, tf.float32, name="node1")
  3. node2 = tf.constant(4.0, tf.float32, name="node2")
  4. node3 = tf.add(node1, node2)
  5. sess = tf.Session()
  6. #创建一个会话,设置这个会话作为默认的会话
  7. with sess.as_default():
  8. #使用这创建的会话来运行关心的结果
  9. print(node3.eval())

交互环境下设置默认会话

在交互模式下,Python脚本或者jupyter编辑器下,通过设置默认会话来获取张量的取值更加方便。tf.InteractiveSession使用这个函数会自动将生成的会话注册为默认会话

  1. import tensorflow as tf
  2. node1 = tf.constant(3.0, tf.float32, name="node1")
  3. node2 = tf.constant(4.0, tf.float32, name="node2")
  4. node3 = tf.add(node1, node2)
  5. #创建一个会话,设置这个会话作为默认的会话
  6. sess = tf.InteractiveSession()
  7. print(node3.eval())
  8. sess.close()

tensorflow的基本运算

常量和变量

常量在运行过程中不会改变的单元,在TensorFlow中无需进行初始化操作,创建语句:

constant_name = tf.constant(value)

变量是在运行过程中值会改变的单元,在TensorFlow中须进行初始化操作。创建语句:

name_variable = tf.Variable(value.name)

个别变量的初始化:

init_op = name_variable.initializer()

所有变量的初始化:

init_op = tf.global_variables_initializer()

  1. import tensorflow as tf
  2. node1 = tf.Variable(3.0, tf.float32, name="node1")
  3. node2 = tf.Variable(4.0, tf.float32, name="node2")
  4. node3 = tf.add(node1, node2, name='add')
  5. sess = tf.Session()
  6. #变量初始化
  7. init = tf.global_variables_initializer()
  8. #必须要先运行初始化,如果没有这句话会报错,还是没有初始化
  9. sess.run(init)
  10. print(sess.run(node3))

变量的赋值

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

特殊的情况下需要人工赋值的,可用变量赋值语句:

update_op = tf.assign(variable_to_be_updateed, new_value)

  1. #通过变量赋值输出1、2、3、4、5...10
  2. import tensorflow as tf
  3. value = tf.Variable(0, name='value')
  4. one = tf.constant(1, name='one')
  5. new_value = tf.add(value, one)
  6. #将new_value赋值给value
  7. update_value = tf.assign(value, new_value)
  8. init = tf.global_variables_initializer()
  9. with tf.Session() as sess:
  10. sess.run(init)
  11. #运行十次
  12. for _ in range(10):
  13. #run一下updatevalue
  14. sess.run(update_value)
  15. print(sess.run(value))

占位符 placeholder

tensorflow中的Variable变量类型,在定义时需要初始化,但有些变量定义时并不知道其数值,只有当真正开始运行程序的时候才由外部输入,比如训练数据,这时候需要占位符。tf.placeholder占位符,是TensorFlow中特有的一种数据结构,类似动态变量,函数的参数,或者C语言中格式化输出时的‘%’占位符。占位符的函数接口如下:

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

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

Feed提交数据和Fetch提取数据

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

  1. import tensorflow as tf
  2. a = tf.placeholder(tf.float32, name='a')
  3. b = tf.placeholder(tf.float32, name='b')
  4. c = tf.multiply(a, b, name='c')
  5. init = tf.global_variables_initializer()
  6. with tf.Session() as sess:
  7. #下面这句话和上面的初始化语句可以直接注掉,因为placeholder不是Variable,所以可以不应运行初始化
  8. sess.run(init)
  9. #通过feed_dict的参数传递,按字典格式
  10. result = sess.run(c, feed_dict={a:8.0, b:3.5})
  11. print(result)

多个操作可以通过一次Feed完成执行:看代码

  1. import tensorflow as tf
  2. import numpy as np
  3. a = tf.placeholder(tf.float32, name='a')
  4. b = tf.placeholder(tf.float32, name='b')
  5. c = tf.multiply(a, b, name='c')
  6. d = tf.subtract(a, b, name='d')
  7. init = tf.global_variables_initializer()
  8. with tf.Session() as sess:
  9. sess.run(init)
  10. #通过feed_dict的参数传递,按字典格式
  11. result = sess.run([c,d], feed_dict={a:[8.0, 2.0, 3.0], b:[3.5, 2.0, 4.0]})
  12. rc,rv = sess.run([c,d], feed_dict={a:[8.0, 2.0, 3.0], b:[3.5, 2.0, 4.0]})
  13. print(result)
  14. print(np.array(result).shape)
  15. print(result[0])

TensorBoard可视化初步

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

  1. #在TensorBoard中查看图结构
  2. import tensorflow as tf
  3. #清除default_graph和不断增加的节点
  4. tf.reset_default_graph()
  5. #logdir改成自己机器上的合适路径
  6. logdir = 'D:\picture'
  7. #定义一个简单的计算图,实现向量加法的操作
  8. input1 = tf.constant([1.0,2.0,3.0], name='input1')
  9. input2 = tf.Variable(tf.random_uniform([3]), name='input2')
  10. output = tf.add_n([input1, input2], name='add')
  11. #生成一个写日志的writer,并将当前的TensorFlow计算图写入日志
  12. writer = tf.summary.FileWriter(logdir, tf.get_default_graph())
  13. writer.close()

启动TensorBoard

在Anaconda Prompt中先进入日志存放的目录(非常重要!!!),然后返回至上一层,继续敲命令。

命令:tensorboard —logdir=path,Google浏览器,其他浏览器不太好,一般我们画的都是图示,所以要到graph中去找。

单变量线性回归—TensorFlow实战

简单的线性回归:这里就不介绍了…

使用TensorFlow进行算法设计与训练的核心步骤

  • 准备数据
  • 构建模型
  • 训练模型
  • 进行预测

看例子:随机生成一个近似采样随机分布,使得w=2.0, b=1,并加入一个噪声,噪声的最大振幅为0.4;

  1. #在jupyter中,使用matplotlib显示图像需要设置为inline模式,否则不会显示图像
  2. %matplotlib inline
  3. import matplotlib.pyplot as plt
  4. import numpy as np
  5. import tensorflow as tf
  6. #设置随机数种子,为了得到相同的随机数
  7. np.random.seed(5)
  8. #直接采用等差数列的方式,生成100个点,每个点的取值在-1,1之间
  9. x_data = np.linspace(-1, 1, 100)
  10. #y = 2*x + 1 + 噪声,其中噪声的纬度应与x_data一致
  11. #实参前面加上*就相当于拆包,单个*表示将元组拆成一个个单独的实参
  12. y_data = 2 * x_data + 1.0 + np.random.randn(*x_data.shape) * 0.4
  13. #画出随机生成数据的散点图
  14. plt.scatter(x_data, y_data)
  15. #画出我们想要的线性函数
  16. plt.plot(x_data, 1.0 + 2.0 * x_data, color='red', linewidth=3)

构建模型:

定义训练数据的占位符,x是特征值,y是标签值

x = tf.placeholder(“float”, name=’x’)

y = tf.placeholder(“float”, name=’y’)

定义模型函数:

def model(x, w, b):

return tf.multiply(x, w) + b

创建变量:

  • TensorFlow变量的声明函数是tf.Variable
  • tf.Variable的作用是保存和更新参数
  • 变量的初始值可以是随机数、常数、或是通过其他变量的初始值计算得到

    构建变量的初始值

    w = tf.Variable(1.0, name=”w0”)
    b = tf.Variable(0.0, name=”b0”)

    pred是预测值,前向计算

    pred = model(x, w, b)

    在jupyter中,使用matplotlib显示图像需要设置为inline模式,否则不会显示图像

    %matplotlib inline
    import matplotlib.pyplot as plt
    import numpy as np
    import tensorflow as tf

    设置随机数种子,为了得到相同的随机数

    np.random.seed(5)

    直接采用等差数列的方式,生成100个点,每个点的取值在-1,1之间

    x_data = np.linspace(-1, 1, 100)

    y = 2*x + 1 + 噪声,其中噪声的纬度应与x_data一致

    实参前面加上就相当于拆包,单个表示将元组拆成一个个单独的实参

    y_data = 2 x_data + 1.0 + np.random.randn(x_data.shape) * 0.4

    画出随机生成数据的散点图

    plt.scatter(x_data, y_data)

    画出我们想要的线性函数

    plt.plot(x_data, 1.0 + 2.0 * x_data, color=’red’, linewidth=3)

    x = tf.placeholder(“float”, name=’x’)
    y = tf.placeholder(“float”, name=’y’)
    def model(x, w, b):

    1. return tf.multiply(x, w) + b

    return tf.multiply(x, w) + b

    构建变量的初始值

    w = tf.Variable(1.0, name=”w”)
    b = tf.Variable(0.0, name=”b”)

    pred是预测值,前向计算

    pred = model(x, w, b)

    迭代次数

    train_epochs = 10

    学习率

    learning_rate = 0.05

    定义损失函数,均方差(MSE)

    loss_function = tf.reduce_mean(tf.square(y-pred))

    定义优化器,选用梯度下降优化器

    optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
    sess = tf.Session()
    init = tf.global_variables_initializer()

    sess.run(init)
    for epoch in range(train_epochs):

    1. #zip函数会将两个一维数组合并为一个一维数组,这样数组中的每个变量都相当于一个元组
    2. for xs,ys in zip(x_data, y_data):
    3. loss = sess.run([optimizer, loss_function], feed_dict={x:xs, y:ys})
    4. b0temp = b.eval(session=sess)
    5. w0temp = w.eval(session=sess)
    6. plt.plot(x_data, w0temp * x_data + b0temp)

    进行训练

    x_test = 3.2
    target = 2 * x_test + 1
    print(target)

    通过模型预测的结果

    result = sess.run(pred, feed_dict={x:x_test})
    print(result)

#最终的输出结果为7.4和7.385617

随机梯度下降法

在梯度下降法中,批量指的是用于单次迭代中计算梯度的样本总数。假定批量是指整个数据集,数据集通常包括很大样本,此外数据集通常包含很多特征。因此一个批量可能是相当巨大。如果是超大批量,则迭代次数可能要花费很多时间。

随机梯度下降法(SGD):每次迭代只使用一个样本,如果进行足够的迭代,SGD也可以发挥作用。“随机”这一术语表示构成各个批量的样本都是随机选择的。

小批量随机梯度下降法(小批量SGD):是介于全批量迭代和SGD之间的折中方案。小批量通常包括10-1000个随机样本。小批量SGD可以减少SGD中的杂乱的样本数量,仍是比较高效的一种方案。

发表评论

表情:
评论列表 (有 0 条评论,636人围观)

还没有评论,来说两句吧...

相关阅读

    相关 TensorFlow基础概念

    首先祝自己生日快乐!! 趁着大学最后的一点时间学习一点新的东西,希望自己能坚持下去。 这里记录一点这几天学习中记录下的一些概念以及注意点。 基础概念 计算图(g