Tensorflow使用数据流程图表达计算过程和共享状态,使用节点表示抽象计算,使用边表示数据流。
Tensorflow的设计原则:
- 延迟计算:图的构造和执行分离,并推迟计算图的执行过程。
- 原子op:op是最小的抽象计算单元,支持构造复杂的网络模型。
- 抽象设备:支持CPU,GPU,ASIC多种异构计算设备类型。
- 抽象任务
Session
在这里用到了tf.constant
,这是tensorflow里定义constant tensor的方法。
需要注意的是,即使此刻定义的是常量,由于tensorflow延迟计算的设计,它仅仅停留在计算图的构造阶段,没有计算过程,所以也没有值。
import tensorflow as tf
m1 = tf.constant([[2, 2]])
这里的[[2, 2]]
的shape与numpy相似,
语句 | shape |
---|---|
tf.constant([[2, 2]]) | (1, 2) |
tf.constant([2, 2]) | (2,) |
事实上,此时的m1
:
Tensor("Const_6:0", shape=(1, 2), dtype=int32)
也可以定义m1
的type:
m1 = tf.constant([[2, 2]], dtype=tf.float32)
TIP:在tf中,浮点型多使用 tf.float32
.
同理,再定义一个shape是(2,1)的常量。
m2 = tf.constant([[3], [3]])
对m1
和m2
要做的操作(operation, op)是矩阵乘法。即,
落实在代码上,
dot_operation = tf.matmul(m1, m2)
回头整体看一下构建计算图的过程:
import tensorflow as tf
m1 = tf.constant([[2, 2]])
m2 = tf.constant([[3], [3]])
dot_operation = tf.matmul(m1, m2)
接下来是计算图的执行过程,通过tf.Session()
完成。
tf.Session()
也称为会话,3个步骤来完成会话:
- 创建会话
- 迭代运行
- 关闭会话
with tf.Session() as sess: #创建会话
result = sess.run(dot _operation) #迭代运行
print(result)
#关闭会话
print(reslut)
那么这里,两个print(reslut)
输出的结果会是一样的吗?
NO!
并不一样,第一个print(reslut)
输出:
[[12]]
第二个print(reslut)
输出:
Tensor("MatMul_3:0", shape=(1, 1), dtype=int32)
因为第一个print(reslut)
输出的是在会话里计算后的结果,而第二个print(reslut)
在会话外,依然仅仅是计算图。
placeholder
placeholder中文翻译为占位符,从计算图的角度来说,就是先将位置占好,等运行会话的时候,在这个位置传入数据。
那么从这个概念,可发想tf.placeholder
是数据传入的位置,这个数据既包括x
也可包括监督学习中的ground truth y
。
tf.placeholder(
dtype,
shape=None,
name=None
)
从定义可知,对于tf.placeholder
数据的type是一定要定义的。
TIP:在tf中,多使用浮点型 tf.float32
.
来看一个关于tf.placeholder
的简单例子:
import tensorflow as tf
x1 = tf.placeholder(tf.float32, shape=None)
y1 = tf.placeholder(tf.float32, shape=None)
z1 = x1 + y1
x2 = tf.placeholder(tf.float32, shape=[2, 1])
y2 = tf.placeholder(tf.float32, shape=[1, 2])
z2 = tf.matmul(x2, y2)
with tf.Session() as sess:
z1_value = sess.run(z1, feed_dict={x1: 1, y1: 2})
z1_value, z2_value = sess.run([z1, z2], feed_dict={x1: 1, y1:2, x2: [[2], [2]], y2: [[3, 3]]})
print(z1_value)
print(z2_value)
这里值得注意的是
with tf.Session() as sess:
z1_value = sess.run(z1, feed_dict={x1: 1, y1: 2})
z1_value, z2_value = sess.run([z1, z2], feed_dict={x1: 1, y1:2, x2: [[2], [2]], y2: [[3, 3]]})
print(z1_value)
print(z2_value)
可见在sess.run
时,喂入一个字典feed_dict
,这就是数据传入的地方。
Variable
在tensorflow中有2个关于Variable的op,tf.Variable()
和tf.get_variable()
。详细可参见:
tf.get_variable()和tf.Variable()的区别
官方推荐:创建变量的最佳方式是调用 tf.get_variable
函数。
注意 tf.get_variable()
最好配合 reuse
和 with tf.variable_scope()
使用。
tf.get_variable(
name,
shape=None,
dtype=None,
initializer=None,
regularizer=None,
trainable=None,
collections=None,
caching_device=None,
partitioner=None,
validate_shape=True,
use_resource=None,
custom_getter=None,
constraint=None,
synchronization=tf.VariableSynchronization.AUTO,
aggregation=tf.VariableAggregation.NONE
)
W = tf.Variable(<initial-value>, name=<optional-name>)
且需注意,tf.Variable
一定要定义初始值,而tf.get_variable()
不需要。
例子:
import tensorflow as tf
var = tf.Variable(0)
add_operation = tf.add(var, 1)
update_operation = tf.assign(var, add_operation)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for _ in range(3):
sess.run(update_operation)
print(sess.run(var))
Activation
y_relu = tf.nn.relu(x)
y_sigmoid = tf.nn.sigmoid(x)
y_tanh = tf.nn.tanh(x)
y_softplus = tf.nn.softplus(x)
实战篇
如同上一篇博文,对于一个model,从搭建到运行共7步。
-
通过占位符,占住输入和标签。
-
定义参数变量及初始化。这里需要说明一下,由于版本的更新,现在的tensorflow已经可以在搭建网络的同时定义参数了,所以这一步可以忽略。
现在可以看作所有参数的初始化语句。
-
定义模型。
-
定义损失函数。
-
定义精度。
-
定义优化算法。
-
训练模型。
1. regression
除了对模型的搭建及运行,还有一步非常重要,就是数据导入。
这里简单用numpy制作一些简易数据。
import numpy as np
x = np.linspace(-1, 1, 100).reshape(-1, 1)
noise = np.random.normal(0, 0.1, size=x.shape)
y = np.power(x, 2) + noise
注意:对于x的reshape非常重要。如果没有reshape这一步,x是一个shape为(100,)的标量,在训练时会报错。
接下来,按上述步骤来:
- 通过占位符,占住输入和标签。
tf_x = tf.placeholder(tf.float32, x.shape)
tf_y = tf.placeholder(tf.float32, y.shape)
- 初始化所有参数。
init = tf.global_variable_initializer()
- 定义模型。
l1 = tf.layers.dense(tf_x, 10, activation=tf.nn.relu)
output = tf.layers.dense(l1, 1)
- 定义损失函数。
loss = tf.losses.mean_squared_error(tf_y, output)
- 定义精度。
暂且不管
- 定义优化算法。
optimizer = tf.train.AdamOptimizer()
train_op = optimizer.minimize(loss)
- 训练模型
plt.ion()
with tf.Session() as sess:
sess.run(init)
for step in range(100):
_, l, pred = sess.run([train_op, loss, output], feed_dict={tf_x:x, tf_y: y})
if step%5 == 0:
plt.cla()
plt.scatter(x, y)
plt.plot(x, pred, "r-", lw=5)
plt.pause(0.1)
网友评论