Tensorflow入门-基本概念和用法-demo

Tensorflow入门

TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)
在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量
(tensor)。它灵活的架构可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或
GPU),服务器,移动设备等等。

Tensorflow = tensor + flow 张量流,有点数据流图的含义。

tensorflow 基本用法

  1. 使用图(graph)表示计算任务
  2. 在会话(session)的上下文(context)中执行图
  3. 使用 tensor 表示数据
  4. 通过 变量(Variable)维护状态
  5. 使用 feed 和 fetch 可以为任意的操作(arbitrary operation)赋值或者从中获取数据
  • TensorFlow 是一个编程系统,使用图表示计算任务。图中的节点被称作 op(operation的缩写)。一个 op 获得 0 个(如后续提到的为了占位的placeholder)或者多个(如加法)Tensor。执行计算,产生0个或者多个(如拆分)Tensor。
  • 每个 Tensor 是一个类型化的多维数组。例如,你可以将一小组图像集表示为一个四维的浮点数集,这四个维度分别是 [batch, height, width, channels]。
  • 一个 TensorFlow 图(Graph)描述了计算过程。为了进行计算,图必须在 会话(Session)里被启动。
  • 会话(Session)将图中的 op 分发到 CPU 或者 GPU 之类的 设备 上,同时提供执行 op 的方法。
  • 这些方法执行后,将产生的 tensor 返回。在 python 语言中,返回的 tensor 是 numpy ndarray 对象。

tensorflow 构建图(Graph)

步骤:

  1. 创建源 op :源 op 不需要任何输入。例如常量(constant)。源 op 的输出被传递给其他 op 做运算。
  2. 在会话(Session)中启动图(Graph)。
  3. 关闭Session以释放资源。

以常量的矩阵乘法举例

import tensorflow as tf

# TensorFlow Python 库有一个默认图 (default graph), op 构造器可以为其增加节点. 
# 这个默认图对许多程序来说已经足够用了. 
# 创建一个常量 op, 产生一个 1x2 矩阵. 这个 op 被作为一个节点加到默认图中.
#
# 构造器的返回值代表该常量 op 的返回值.
matrix1 = tf.constant([
        [3., 3.]
])

# 创建另外一个常量 op, 产生一个 2x1 矩阵.
matrix2 = tf.constant([
        [2.],
        [2.]
])

# 创建一个矩阵乘法 matmul op , 把 'matrix1' 和 'matrix2' 作为输入.
# 返回值 'product' 代表矩阵乘法的结果. 
# 1x2矩阵 * 2x1矩阵 应该得到 1*1矩阵
product = tf.matmul(matrix1, matrix2)
# 到此为止,只是构建图完事了。即使运行,也什么都没有。
'''
默认图现在有三个节点, 两个 constant() op, 和一个matmul() op. 
为了真正进行矩阵相乘运算, 并得到矩阵乘法的结果, 必须在会话里启动这个图.
启动图的第一步是创建一个 Session 对象, 如果无任何创建参数, 会话构造器将启动默认图.
'''
'''
# 这里你可能会有一个疑惑,为什么前两个constant()也属于是 op.
起初我也不理解,现在我理解 得到tensor的操作就算是 op.
因为,计算图中节点(op)是代表计算,而计算得到的是tensor.
所以你得到了 matrix1 & matrix2 就是经过了 op 的计算.所以是两个 op.
'''

# 启动默认图.
sess = tf.Session()

# 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数. 
# 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回矩阵乘法 op 的输出.
# 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的.
# 函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行.
# 返回值 'result' 是一个 numpy `ndarray` 对象.
result = sess.run(product)
print(result)
# ==> [[ 12.]]

# 任务完成, 关闭会话.
sess.close()
'''
session对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 “with” 代码块来自动完成关闭动作.

with tf.Session() as sess:
  result = sess.run([product])
  print (result)
'''

运行结果:本地运行时会有很多框架相关的输出,这里我仅截取了计算结果。

[[12.]]

Tensorflow Tensor(张量)

构建图的运算过程的输出结果时一个Tensor,主要由三个属性组成:Name、Shape、Type。

  • Name 代表的是张量的名字,也是张量的唯一标识,我们可以在每个 op 上添加 name 属性来对节点进行命名,Name 的值表示的是该张量来自于第几个输出结果(编号从0开始)。
  • Shape 代表的是张量的维度。
  • Type 表示的是张良的类型,每个张量都会有唯一的类型。我们需要注意的是要保证参与运算的张量的类型保持一致,否则会出现类型不匹配的错误。

常见的张量类型:

数据类型Python类型描述
DT_FLOATtf.float3232位浮点数
DT_DOUBLEtf.float6464位浮点数
DT_INT64tf.int6464位有符号整型
DT_INT32tf.int3232位有符号整型
DT_INT16tf.int1616位有符号整型
DT_INT8tf.int88位有符号整型
DT_UINT8tf.uint88位无符号整型
DT_STRINGtf.string可变长度的字节数组.每一个张量元素都是一个字节数组
DT_BOOLtf.bool布尔型
DT_COMPLEX64tf.complex64由两个32位浮点数组成的复数:实数和虚数
DT_QINT32tf.qint32用于量化Ops的32位有符号整型
DT_QINT8tf.qint8用于量化Ops的8位有符号整型
DT_QUINT8tf.quint8用于量化Ops的8位无符号整型

Tensorflow 变量(Variables)

变量 Variables 维护图执行过程中的状态信息.
通常会将一个统计模型中的参数表示为一组变量.
例如, 你可以将一个神经网络的权重作为某个变量存储在一个 tensor 中. 在训练过程中, 通过重复运行训练图, 更新这个 tensor.

Tensorflow fetch/feed

fetch:为了取回操作的输出内容,可以使用 session 对象的 run() 方法调用执行图时,传入一些 tensor,这些 tensor 会帮助你取回结果。

demo:

import tensorflow as tf

input1 = tf.constant(1.0)
input2 = tf.constant(2.0)
input3 = tf.constant(3.0)

intermed = tf.add(input1, input2)
res2 = tf.multiply(input3, intermed)

with tf.Session() as sess:
    res3 = sess.run([intermed, res2])
    print(res3, type(res3), type(res3[0]))

不同于上面代码的 sess.run(product) ,这里想输出哪些 tensor 直接全部放入到 [] 中,然后将 [] 作为参数传入 a = sess.run([...]) 即可取回操作的输出内容。使用 print(a) 输出查看。

简单理解:fetch 利用 […] 就是输出一些中间结果。

运行结果:省略框架相关输出

[3.0, 9.0] <class 'list'> <class 'numpy.float32'>

feed:使用一个 tensor 值临时替换一个操作的输出结果。可以提供 feed 数据作为 run() 调用的参数。

feed 只在调用它的方法内有效,方法结束,feed 就会消失。最常见的用例是将某些特殊的操作指定为 “feed” 操作,标记的方法是使用 tf.placeholder() 为这些操作创建占位符。

placeholder 是一个数据初始化容器,它与变量最大的不同在于 placeholder 定义的是一个模板,这样我们就可以在 session 运行阶段,利用 feed_dict 的字典结构给 placeholder 填充具体的内容,而无需每次都提前定义好变量的值,大大提高了代码的利用率。

demo:

import tensorflow as tf

input1 = tf.placeholder(tf.float32)  # 占位符,先占位
input2 = tf.placeholder(tf.float32)  # 占位符,先占位
output = tf.multiply(input1, input2)

with tf.Session() as sess:  
    # 执行图
    result = sess.run([output], feed_dict={input1:[7.], input2:[2.]})
    print(result)

运行结果:

[array([14.], dtype=float32)]

tensorflow 一个完整例子

本代码没有实际意义:

import tensorflow as tf
import numpy as np

import matplotlib.pyplot as plt

# 定义数据: 使用numpy生成200个随机点
# array = numpy.linspace(start, end, num=num_points)
# 将在start和end之间生成一个相等间隔的序列,共有num_points个元素。包括start和end
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.02, x_data.shape)
y_data = np.square(x_data) + noise

# 定义两个placeholder存放输入数据
# placeholder里面的shape可以不预先给定,会根据feed时自动计算
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])

# 定义神经网络中间层
# 权值是随时都可以改变的, 所以定义为 Variable
Weights_L1 = tf.Variable(tf.random_normal([1, 10]))
Bias_L1 = tf.Variable(tf.zeros([1, 10]))  # 加入偏置项
wx_add_b = tf.matmul(x, Weights_L1) + Bias_L1
Out_L1 = tf.nn.tanh(wx_add_b)  # 加入激活函数

# 定义神经网络输出层
Weights_L2 = tf.Variable(tf.random_normal([10, 1]))
Bias_L2 = tf.Variable(tf.zeros([1, 1]))  # 加入偏置项
wx_add_b = tf.matmul(Out_L1, Weights_L2) + Bias_L2
predicetion = tf.nn.tanh(wx_add_b)  # 加入激活函数

# 定义损失函数(均方差函数)
loss = tf.reduce_mean(tf.square(y-predicetion))  # 均方误差
# 定义反向传播算法(使用梯度下降算法训练)  调用了自动微分工具
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

# tensorboard
with tf.Session() as sess:
    # 初始化 初始化不是必须的,为什么不是必须的呢?
    sess.run(tf.global_variables_initializer())
    # 训练2000次
    for _ in range(2000):
        sess.run(train_step, feed_dict={x:x_data, y:y_data})
    # 获得预测值
    predicetion_v = sess.run(predicetion, feed_dict={x:x_data})

    plt.figure()
    plt.scatter(x_data,y_data)  # 散点是真实值
    plt.plot(x_data,predicetion_v)  # 曲线是预测值
    plt.show()

附录

np.linspace()

import numpy as np

import matplotlib.pyplot as plt

# 定义数据: 使用numpy生成200个随机点
x_data = np.linspace(-0.5, 0.5, 200)

print(x_data, type(x_data), x_data.shape)

x_data = x_data[:, np.newaxis]

print(x_data, type(x_data), x_data.shape)

执行结果:

[-0.5        -0.49497487 -0.48994975 -0.48492462 -0.4798995  -0.47487437
 -0.46984925 -0.46482412 -0.45979899 -0.45477387 -0.44974874 -0.44472362
      .            .           .           .           .           .
      .            .           .           .           .           .
      .            .           .           .           .           .
  0.43467337  0.43969849  0.44472362  0.44974874  0.45477387  0.45979899
  0.46482412  0.46984925  0.47487437  0.4798995   0.48492462  0.48994975
  0.49497487  0.5       ] <class 'numpy.ndarray'> (200,)
[[-0.5       ]
 [-0.49497487]
 [-0.48994975]
      ...
 [ 0.48994975]
 [ 0.49497487]
 [ 0.5       ]] <class 'numpy.ndarray'> (200, 1)

Process finished with exit code 0

关于 numpy.newaxis 的补充:
numpy.newaxis == None,结合 linspace 能插入新维度
上代码:

print(np.newaxis)
print(type(np.newaxis))

x = np.linspace(0,5,6)  # 6个元素
print(x, x.shape)
#                     (6,1)
y = np.linspace(0,5,6)[:, np.newaxis]
print(y, y.shape)
#                     (1,6)
z = np.linspace(0,5,6)[np.newaxis, :]
print(z, z.shape)

y = np.linspace(0,5,6)[:, np.newaxis] 类似代码简单记忆:一维数组转为二维数组时,np.newaxis 所在维度的 shape 值为1,另一个维度的 shape 值为一维数组长度。
运行结果:

[0. 1. 2. 3. 4. 5.] (6,)
[[0.]
 [1.]
 [2.]
 [3.]
 [4.]
 [5.]] (6, 1)
[[0. 1. 2. 3. 4. 5.]] (1, 6)

np.linspace(0,5,6)[:, np.newaxis] 的shape是 (6,1),np.linspace(0,5,6)[np.newaxis, :] 的shape是 (1,6)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值