转载请注明作者和出处: https://blog.csdn.net/weixin_37392582
<https://blog.csdn.net/weixin_37392582>
开发平台: Win10 + Python3.6 + Anaconda3
编  者: 无尾



* 3、TensorFlow计算模型——计算图
<https://blog.csdn.net/weixin_37392582/article/details/79814741#3tensorflow计算模型计算图>
* 3.1、计算图的概念
<https://blog.csdn.net/weixin_37392582/article/details/79814741#31计算图的概念>
* 3.2 计算图的使用
<https://blog.csdn.net/weixin_37392582/article/details/79814741#32-计算图的使用>
* 3.2、TensorFlow数据模型——张量
<https://blog.csdn.net/weixin_37392582/article/details/79814741#32tensorflow数据模型张量>
* 3.2.1、张量的概念
<https://blog.csdn.net/weixin_37392582/article/details/79814741#321张量的概念>
* 3.2.2、张量的使用
<https://blog.csdn.net/weixin_37392582/article/details/79814741#322张量的使用>
* 3.3、TensorFlow运行模型——会话
<https://blog.csdn.net/weixin_37392582/article/details/79814741#33tensorflow运行模型会话>
* 3.4、TensorFlow实现神经网络
<https://blog.csdn.net/weixin_37392582/article/details/79814741#34tensorflow实现神经网络>
* 3.4.1、TensorFlow游乐场及神经网络简介
<https://blog.csdn.net/weixin_37392582/article/details/79814741#341tensorflow游乐场及神经网络简介>
* 3.4.3、神经网络参数与 TensorFlow 变量
<https://blog.csdn.net/weixin_37392582/article/details/79814741#343神经网络参数与-tensorflow-变量>
* 3.4.4、通过 TensorFlow 训练神经网络模型
<https://blog.csdn.net/weixin_37392582/article/details/79814741#344通过-tensorflow-训练神经网络模型>
* 3.4.5、完整神经网络样例程序
<https://blog.csdn.net/weixin_37392582/article/details/79814741#345完整神经网络样例程序>


3、TensorFlow计算模型——计算图

3.1、计算图的概念

  Tensor——张量,在tensorflow中可以被简单理解为多维数组,表明了它的数据结构
Flow——中文翻译“流”,直观地表达了张良之间通过计算相互转换的过程

  Tensorflow时一个通过计算图的形式来表述计算的变成系统。每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系。

  如果一个运算的输入依赖于另外一个运算的输出,那么这两个运算有依赖关系。
  

3.2 计算图的使用

Import tensorflow as tf - 导入tensorflow库,用tf来简介“tensorflow”,使得程序更加简洁。


定义了一个常量constant a,因为没有制定计算图,所以a所属默认的计算图(default_graph),通过a.graph可以查看a的所属图。

可以通过tf.Graph来生成新的计算图,不同计算图上的张量和运算不会共享,如下,以下代码示意了如何在不同计算图上定义和使用变量:
In [4]: import tensorflow as tf In [5]: g1 = tf.Graph() In [6]: with
g1.as_default():...: v = tf.get_variable('v',shape= [1],initializer =
tf.constant_initializer(1.0)) In [7]: g2 = tf.Graph() In [8]: with
g2.as_default():...: v = tf.get_variable('v',shape = [1],initializer =
tf.constant_initializer(0)) In [12]: 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"))) [ 1.] In [13]: 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"))) [ 0.]
上面代码产生了两个计算图,各自定义了一个名字为“v”的变量,图g1中初始化为1,图g2中初始化为0,可以看出,运行不同的计算图时,变量v的值也是不一样的。


计算图不仅仅可以用来隔离张量和计算,还提供了管理张量和计算的机制。通过tf.Graph.device函数来指定运行计算的设备。这为TensorFlow使用GPU提供了机制。下面的程序可以将加法计算跑在GPU上。
In [17]: a = tf.constant([1.,2.],name = 'a') In [18]: b = tf.constant([2.,3.
],name ='b') In [19]: g = tf.Graph() In [20]: with g.device('/gpu:0'): ...:
result = a + b

TensorFlow中维护的集合列表。在一个计算图中,可以通过集合(collection)来管理不同类别的资源。比如通过tf.get_collection函数将资源假如一个或多个集合中,然后通过tf.get_collection获取一个集合里面的所有资源。这里的资源可以是张良、变量或者运行TensorFlow程序所需要的队列资源,等等。

下面时最常用的几个自动维护的集合。


3.2、TensorFlow数据模型——张量

2.1 - 张量的一些基本属性
2.2 - 如何通过张量来保存和获取TensorFlow计算的结果

3.2.1、张量的概念

在TensorFlow程序中,所有的数据都通过张量的形式来表示。从功能的角度上看,张量可以被简单理解为多维数组。

其中零阶张量表示标量(scalar),也就是一个数(或字符串);第一阶张量为向量(vector),也就是一个一维数组;第n阶张量可以理解为一个n维数组。

张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程,只是对TensorFlow中运算结果的引用。比如前面用过的加法
In [24]: print(result) Tensor("add_2:0", shape=(2,), dtype=float32)
可以看到,返回的是一个张量的结构。保存了三个属性:name , shape , dtype。


第一个属性,name。通过“node:src_output”的形式给出。其中,node是节点的名称,src_output表示当前张量来自节点的第几个输出。比如”add_2:0”就说明result这个张量是计算节点“add_2”输出的第一个结果(编号从0开始)。

第二个属性,shape。描述了一个张量的维度信息。比如“shape=(2,)”,说明张量resule是一个一维数组,这个数据的长度为2.

第三个属性,dtype。描述了张量result的类型。参与运算的张量类型需要保持一致。

3.2.2、张量的使用

张量的使用主要可以总结为两大类。

第一类用途是对中间计算结果的引用。当一个计算包含很多中间结果时,使用张量可以提高代码的可读性。
In [25]: a = tf.constant([1.,2.],name = 'a') In [26]: b = tf.constant([2.,3.
],name ='b') In [27]: result = a + b
比如下面这种的可读性就很差
In [28]: result = tf.constant([1.,2.],name = 'a') + tf.constant([2.,3.].name =
'b')
第二类情况是当计算图构造完成之后,张量可以用来获得计算结果,也就是得到真实的数字。
In [29]: tf.Session().run(result) Out[29]: array([ 3., 5.], dtype=float32)
3.3、TensorFlow运行模型——会话


通过TensorFlow中的会话(session)来执行定义好的运算。会话拥有并管理TensorFlow程序运行时的所有资源,当所有计算完成之后需要关闭会话来帮助系统回收资源,否则就可能出现资源泄漏的问题。

有两种会话使用模式。

第一种,明确调用会话生成函数和关闭会话函数。
#创建一个会话 In [31]: sess=tf.Session() #使用会话来得到运算结果 In [32]: sess.run(result) Out[
32]: array([ 3., 5.], dtype=float32) #关闭会话使本次运行中使用到的资源可以被释放 In [33]: sess.close
()
第二种,通过Python的上下文管理器来使用会话。所以计算放在“with”内部,上下文管理器退出的时候会自动释放所有资源。
In [34]: with tf.Session() as sess: ...: sess.run(result)
设定默认会话计算张量的取值:
In [41]: with tf.Session() as sess: ...: with sess.as_default(): ...:
print(result.eval()) [3. 5.] In [47]: with tf.Session() as sess: ...:
print(sess.run(result)) [3. 5.] In [48]: with tf.Session() as sess: ...:
print(result.eval(session = sess)) [3. 5.]
通过tf.InteracticeSession函数,自动将生成的会话注册为默认会话。
In [52]: sess = tf.InteractiveSession() In [53]: print(result.eval()) [ 3. 5.]
In [54]: sess.close()
3.4、TensorFlow实现神经网络

结合神经网络的功能进一步介绍如何通过TensorFlow来实现神经网络。

4.1 - 通过TensorFlow游乐场来简单介绍神经网络的主要功能以及计算流程。
4.2 - 介绍神经网络的前向传播算法(forward-propagation),并给出使用TensorFlow的代码实现。
4.3 - 介绍如何通过TensorFlow中的变量来表达神经网络的参数。
4.4 - 将介绍神经网络反向传播算法的原理以及TensorFlow对反向传播算法的支持
4.5 - 给出一个完整的TensorFlow程序在随机的数据上训练一个简单的神经网络

3.4.1、TensorFlow游乐场及神经网络简介

TensorFLow游乐场(http://playground.tensorflow.org
<http://playground.tensorflow.org>)是一个通过网页浏览器就可以训练的简单神经网络并实现可可视化训练过程的工具。


神经网络解决分类问题主要可以分为以下4个步骤。
1.提取问题中实体的特征向量作为神经网络的输入。不同的实体可以提取不同的特征向量。
2.定义神经网络的结构,并定义如何从神经网络的输入得到输出。这个过程就是神经网络的前向传播算法(4.2介绍)。

3.通过训练数据来调整神经网络中参数的取值,这就是训练神经网络的过程。4.3中介绍TensorFlow中表示神经网络参数的方法,4.4中大致介绍神经网络优化算法的框架,并介绍如何通过TensorFlow实现这个框架。
4.使用训练好的神经网络来预测未知的数据。这个过程和步骤2中的前向传播算法一致。

下面几个小节将介绍如何使用TensorFlow来实现神经网络中的不同步骤。最后 3.4.5 中将给出一个完整的程序来训练神经网络。

略略略–抽空写

—-跳过 3.4.2

3.4.3、神经网络参数与 TensorFlow 变量

声明变量初始化,声明一个 2×3 的矩阵变量的方法:
weights = tf.Variable(tf.random_normal([2,3], stddev = 2)) # 产生一个 2×3 的矩阵、
元素均值是 0,标准差为 2 的随机数, 满足正态分布
除了正态分布的随机数, TensorFlow 还提供了一些其他的随机数生成器。


TensorFlow 也支持通过常数来初始化一个变量。


在神经网络中,偏置项(bias)通常使用常数来设置初始值
biases = tf.Variable(tf.zeros([3]) # 初始值为 0, 长度为3 的变量
TensorFlow 也支持通过其他变量的初始值来初始化新的变量,以下代码给出了具体的方法
w2 = tf.Variable(weights.initialized_value()) w3 = tf.Varibale(weights
.initialized_value() * 2.0) # w2 的初始值被设置成了与 weights 变量相同。w3 = 2×w2
在 TensorFlow 中,一个变量在被使用之前, 这个变量的初始化过程需要被明确地调用。以下代码介绍了如何通过变量实现神经网络地参数并实现前向传播地过程。
import tensorflow as tf w1 = tf.Variable(tf.random_normal([2,3], stddev= 1,
seed=1)) w2 = tf.Variable(tf.random_normal([3,1], stddev= 1, seed= 1)) x = tf
.constant([[0.7, 0.9]]) # 1×2 a = tf.matmul(x, w1) # 1×3 y = tf/matmul(a, w2) #
1×1 sess = tf.Session() #初始化 w1 w2 sess.run(w1.initializer) sess.run(w2
.initializer) sess.close()
3.4.4、通过 TensorFlow 训练神经网络模型

反向传播算法训练神经网络。
定义损失函数刻画预测值与真实值的差距,反向传播使差距缩小。
# 定义损失函数 cross_entropy = -tf.reduce_mean(y_ * tf/log(tf.clip_by_value(y, 1e-10,
1.0))) # 定义学习率 learning_rate = 0.01 #定义反响传播算法 train_step = tf.train
.AdamOptimizer(learning_rate).minimize(cross_entropy)
3.4.5、完整神经网络样例程序
# -*- coding: utf-8 -*- """ Created on Thu Apr 12 15:58:38 2018 @author: 无尾君
""" import tensorflow as tf from numpy.random import RandomState batch_size = 8
w1 = tf.Variable(tf.random_normal([2,3], stddev= 1, seed= 1)) w2 =
tf.Variable(tf.random_normal([3,1], stddev= 1, seed= 1)) x =
tf.placeholder(tf.float32, shape= (None,2), name= 'x-input') y_ =
tf.placeholder(tf.float32, shape= (None,1), name= 'y-input') a = tf.matmul(x,
w1) y = tf.matmul(a, w2) cross_entropy = -tf.reduce_mean(y_ *
tf.log(tf.clip_by_value(y,1e-10, 1.0))) train_step = tf.train.AdamOptimizer(
0.001).minimize(cross_entropy) rdm = RandomState(1) dataset_size = 128 X =
rdm.rand(dataset_size,2) Y = [[int(x1+ x2 < 1)] for (x1, x2) in X] with
tf.Session()as sess: tf.global_variables_initializer().run()
print(sess.run(w1)) print(sess.run(w2)) STEPS =5000 for i in range(STEPS):
start = (i * batch_size) % dataset_size end = min(start + batch_size,
dataset_size) sess.run(train_step, feed_dict = {x: X[start:end], y_:
Y[start:end]})if i % 1000 ==0: total_cross_entropy = sess.run(cross_entropy,
feed_dict = {x: X, y_: Y}) print("After %d training step(s), cross entropy on
all data is %g" % (i, total_cross_entropy))