TensorFlow的一般使用流程
构造图:Tensor(类似向量)的使用+operations(图节点)+Graph(构造图)。
张量的使用,存储中间结果;
Tensor("name",shape,dtype)
;构建时并不持有值,运行时持有有效值。计算图:
tf.session
(会话)+Tensor的执行要通过sess.run(graph)
来执行。
import tensorflow as tf
a = tf.constant([1.0, 2.0],name="a")
b = tf.constant([2.0, 23.0],name="b")
result = a+b
print(a.graph is tf.get_default_graph())
True
g1 = tf.Graph()
with g1.as_default():
v = tf.get_variable("v", [1], initializer=tf.zeros_initializer())
g2 = tf.Graph()
with g2.as_default():
v = tf.get_variable("v", [1], initializer=tf.ones_initializer())
with tf.Session(graph=g1)as sess:
#tf.initialize_all_variables().run()
tf.global_variables_initializer().run()
with tf.variable_scope("",reuse=True):
print(sess.run(tf.get_variable("v")))
with tf.Session(graph=g2)as sess:
#tf.initialize_all_variables().run()
tf.global_variables_initializer().run()
with tf.variable_scope("",reuse=True):
print(sess.run(tf.get_variable("v")))
[0.]
[1.]
- Session创建会话一般有两种形式,如下:
python
创建一个会话
sess = tf.Session()
使用这个创建来得到关心的运算的结果
sess.run(…)
关闭会话使得本次运行中使用得到的资源被释放
sess.close()
创建一个会话,并通过python的上下文管理器来管理这个会话
with tf.Session() as sess
使用这个创建来得到关心的运算的结果
sess.run(…)
使用这种形式不在需要closs来关闭释放资源,上下文退出时自动关闭。
```python
import tensorflow as tf
a = tf.constant([1.0, 2.0],name="a")
b = tf.constant([2.0, 23.0],name="b")
result = a+b
<div class="se-preview-section-delimiter"></div>
#计算result的值可以有以下的方法
sess = tf.Session()
with sess.as_default():
print('method1 = ',result.eval())
print('method2 = ',sess.run(result))
print('method3 = ',result.eval(session=sess))
sess = tf.InteractiveSession()#可以省去将产生的会话注册为默认会话的过程
print('method4 = ',result.eval())
sess.close()
<div class="se-preview-section-delimiter"></div>
method1 = [ 3. 25.]
method2 = [ 3. 25.]
method3 = [ 3. 25.]
method4 = [ 3. 25.]
- ConfigProto Protocol Buffer来配置需要生成的会话,具体的实现方式如下:
python
config = tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True)
sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)
- 第一个参数 ` allow_soft_placement=True ` 当以下任意一个条件成立时,GPU的运算可以放到CPU上运行。
- 1.计算无法再GPU上运行;
- 2.没有GPU资源;
- 3.运算输入包含对CPU结果的引用。
- 第二个参数 ` log_device_placement ` 为true时,日志会将记录没给个节点被安排在了那个设备上以方便调试。
- TensorFlow的计算图不仅仅可以用来隔离张量和计算,它还提供了管理张量和计算的机制。
- 计算图可以通过 tf.Graph.device函数来指定运行计算的设备。
```python```
g = tf.Graph()
<div class="se-preview-section-delimiter"></div>
# 指定计算运行的设备
with g.device('/gpu:0'):
result = a + b
<div class="se-preview-section-delimiter"></div>
- TensorFlow中自动维护的集合列表(collection)
- 比如通过 tf.add_to_collection 函数可以将资源加入一个 或多个集合中,然后通过 tf.get_collection 获取一个集合里面的所有资源(如张量,变量,或者运行TensorFlow程序所需的队列资源等等)
**集合名称** | **集合内容** | **使用场景** |
---|---|---|
**tf.GraphKeys.VARIABLES** | 所有变量 | 持久化 TensorFlow 模型 |
**tf.GraphKeys.TRAINABLE_VARIABLES** | 可学习的变量(一般指神经网络中的参数) | 模型训练、生成模型可视化内容 |
**tf.GraphKeys.SUMMARIES** | 日志生成相关的张量 | TensorFlow 计算可视化 |
**tf.GraphKeys.QUEUE_RUNNERS** | 处理输入的 QueueRunner | 输入处理 |
**tf.GraphKeys.MOVING_AVERAGE_VARIABLES** | 所有计算了滑动平均值的变量 | 计算变量的滑动平均值 |
神经网络参数与TensorFlow变量
- 神经网络中的参数的保存和更新通过变量tf.Variable,一般给使用随机数给变量赋初始值。比如:
python
weights = tf.Variable(tf.random_normal([2, 3], mean=0, stddev=2) # 均值为0,标准差为2的随机数
biases = tf.Variable(tf.zeros([3]) #
w2 = tf.Variable(weights.initialized_value()) # 初始值与weights一样
w3 = tf.Variable(weights.initialized_value()*2.0) # 初始值是weights的2倍
- TensorFlow随机数生成函数
| 函数名 | 随机数分布 | 主要参数 |
| :- | :- | -: |
| tf.random_normal | 正态分布 | 平均值、标准差、取值类型 |
| tf.truncated_normal | 满足正态分布的随机值,但若随机值偏离平均值超过2个标准差,则这个数会被重新随机 | 平均值、标准差、取值类型 |
| tf.random_uniform | 平均分布 | 最大、最小值、取值类型 |
| tf.random_gamma | Gramma分布 | 形状参数alpha、尺度参数beta、取值类型 |
- TensorFlow常数生成函数
| 函数名 | 功能 | 样例 |
| :- | :- | -: |
| tf.random_normal | 正态分布 | 平均值、标准差、取值类型 |
| tf.truncated_normal | 满足正态分布的随机值,但若随机值偏离平均值超过2个标准差,则这个数会被重新随机 | 平均值、标准差、取值类型 |
| tf.random_uniform | 平均分布 | 最大、最小值、取值类型 |
| tf.random_gamma | Gramma分布 | 形状参数alpha、尺度参数beta、取值类型 |
```python
import tensorflow as tf
<div class="se-preview-section-delimiter"></div>
# 声明w1,w2两个变量。通过seed设定随机种子,保证每次得到相同结果
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
<div class="se-preview-section-delimiter"></div>
#将输入的特征向量定义为一个变量,但实际上并未被运行,未初始化
x = tf.constant([[0.7, 0.9]])
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
sess = tf.Session()
sess.run(w1.initializer) # 初始化w1
sess.run(w2.initializer) # 初始化w2
print(sess.run(y))
<div class="se-preview-section-delimiter"></div>
#sess.close()
with sess.as_default():
tf.global_variables_initializer().run() # 全
print(sess.run(y))
<div class="se-preview-section-delimiter"></div>
[[3.957578]]
[[0.40506378]]
- 所有的变量都会被自动的加入
GraphKeys.VARIABLES
集合,通过tf.global_variables
可以拿到所有当前计算图的所有变量。 - 通过将变量的参数
trainable
设置为true,变量就会被加入在GraphKeys.TRAINABLE_VARIABLES
,一般是需要优化的参数和其他参数(比如迭代次数);TF中的神经网络优化算法会将GraphKeys.TRAINABLE_VARIABLES
集合中的变量作为默认的优化对象。 - 类似张量,维度(shape)是通过设置
tf.assign(wq, w2, validate_shape=False)
更改,但很少更改;类型(type)不可以更改 - tf中每轮迭代选取的数据通过常量表示,神经网络可能需要经过几百万轮次甚至几亿轮的迭代,这样计算图将会无比巨大,利用效率低。tf提供了placeholder机制用于提供数据,相当于定义了一个位置,这个位置中的程序在程序运行时再指定。
import tensorflow as tf
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1))
<div class="se-preview-section-delimiter"></div>
# 定义了placeholder作为存放数据输入的地方,维度不一定需要指定,但指定了可以降低出错的概率
x = tf.placeholder(tf.float32, shape=(1,2),name="input")
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
<div class="se-preview-section-delimiter"></div>
# placeholder需要feed_dict给相关定位赋数据,这里x可以很方便的每次给计算图提供一个batch的测试数据
sess = tf.Session()
with sess.as_default():
tf.global_variables_initializer().run()
print(sess.run(y, feed_dict={x:[[0.7, 0.9]]}))
<div class="se-preview-section-delimiter"></div>
[[-0.5766313]]
- 在得到一个batch的前向传播结果之后,需要定义一个损失函数来刻画当前的预测值与真实答案之间的差距,然后通过反向传播算法来调整神经网络参数的取值使得差距可以被缩小
python
定义损失函数来刻画预测值与真实值得差距,交叉熵常用的损失函数
cross_entropy = -tf.reduce_mean(y_*tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
learning_rate = 0.001
定义了反向传播的优化方法
train_step = \
tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
“`