使用 TensorFlow, 你必须明白 TensorFlow:(真的很重要,多看几遍!!)
- 使用图 (graph) 来表示计算任务.
- 在会话 (Session) 的上下文 (context) 中执行图.
- 使用 tensor 表示数据.
- 通过 变量 (Variable) 维护状态.
- 使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据.
为了在Python中进行高效的数值计算,我们通常会使用像NumPy一类的库,将一些诸如矩阵乘法的耗时操作在Python环境的外部来计算,这些计算通常会通过其它语言并用更为高效的代码来实现。但遗憾的是,每一个操作切换回Python环境时仍需要不小的开销。如果你想在GPU或者分布式环境中计算时,这一开销更加可怖,这一开销主要可能是用来进行数据迁移。
TensorFlow也是在Python外部完成其主要工作,但是进行了改进以避免这种开销。其并没有采用在Python外部独立运行某个耗时操作的方式,而是先让我们描述一个交互操作图,然后完全将其运行在Python外部。这与Theano或Torch的做法类似。
图中的节点被称之为 op (operation)。一个 TensorFlow 图描述了计算的过程. 为了进行计算, 图必须在会话里被启动。会话将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法. 这些方法执行后, 将产生的 tensor 返回. 在 Python 中, 返回的 tensor 是 numpy ndarray 对象;
TensorFlow 程序通常被组织成一个构建阶段和一个执行阶段。
在构建阶段, op 的执行步骤 被描述成一个图. 在执行阶段, 使用会话执行执行图中的 op.
例如, 通常在构建阶段创建一个图来表示和训练神经网络, 然后在执行阶段反复执行图中的训练op.
先导入各种需要的包
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
先来一个栗子
看不懂没关系,感受一下 [捂脸]
#create data
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data*0.5+0.3
#create tensorflow structure
weights = tf.Variable(tf.random_uniform([1],-1.0,1.0))
biases = tf.Variable(tf.zeros([1]))
y = weights*x_data+biases
loss = tf.reduce_mean(tf.square(y-y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)#步长 一般<1
train = optimizer.minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(401):
sess.run(train)
if step%20==0:
print(step,sess.run(weights),sess.run(biases))
# weight 是tensor 无法直接输出,只能用sess.run输出
结果:
0 [0.33718207] [0.534774]
20 [0.4442017] [0.329881]
40 [0.4861154] [0.30743548]
60 [0.49654502] [0.30185023]
80 [0.4991403] [0.3004604]
100 [0.4997861] [0.30011457]
120 [0.49994674] [0.30002853]
140 [0.49998677] [0.3000071]
160 [0.49999675] [0.30000177]
180 [0.4999992] [0.30000043]
200 [0.4999998] [0.30000013]
220 [0.4999998] [0.30000013]
240 [0.4999998] [0.30000013]
260 [0.4999998] [0.30000013]
280 [0.4999998] [0.30000013]
300 [0.4999998] [0.30000013]
320 [0.4999998] [0.30000013]
340 [0.4999998] [0.30000013]
360 [0.4999998] [0.30000013]
380 [0.4999998] [0.30000013]
400 [0.4999998] [0.30000013]
Session会话控制
为了真正进行运算, 并获取结果, 你必须在会话里启动这个图.
matrix1 = tf.constant([[3,3]])
matrix2 = tf.constant([[2],[2]])
#matmul = matrix multiply
product = tf.matmul(matrix1,matrix2)
#method1
sess = tf.Session()
result = sess.run(product)
# product代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回矩阵乘法 op 的输出.
print(result)
sess.close()
#method2 推荐
with tf.Session() as sess:
result = sess.run(product)
print(result)
输出:
[[12]]
Variable
如果定义了变量,一定要初始化并激活,sess.run(init)后才激活成功。
state = tf.Variable(0,name = 'counter')
print(state.name)
one = tf.constant(1)
new_value = tf.add(state , one)
update = tf.assign(state,new_value)
# assign()和add()操作是图所描绘的表达式的一部分,
# 所以在调用run()执行表达式之前, 它并不会真正执行赋值操作.
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for _ in range(3):
sess.run(update)
print(sess.run(state)) # print(state)没用,要先把run指针放到state上去。
输出:
counter_6:0
1
2
3
为了取回 op 的输出内容, 可以在使用 Session 对象的 run() 调用 执行图时, 传入一些 tensor, 这些 tensor 会帮助你取回结果. 在之前的例子里, 我们只取回了单个节点 state, 但是你也可以取回多个 tensor。
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.multiply(input1, intermed)
with tf.Session() as sess:
result = sess.run([mul, intermed])
print(result)
输出:
[21.0, 7.0]
Feed
- run()的时候用feed_dict传进去
- 每一次用不同的值代替它
TensorFlow 还提供了 feed 机制, 该机制可以临时替代图中的任意操作中的 tensor,可以对图中任何操作提交补丁, 直接插入一个 tensor。
feed 使用一个 tensor 值临时替换一个操作的输出结果. 你可以提供 feed 数据作为 run() 调用的参数. feed 只在调用它的方法内有效, 方法结束, feed 就会消失. 最常见的用例是将某些特殊的操作指定为 "feed" 操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符.
input1 =tf.placeholder(tf.float32)
input2 =tf.placeholder(tf.float32)
output = tf.multiply(input1,input2)
with tf.Session() as sess:
print(sess.run(output,feed_dict={input1:[7.],input2:[2.]}))
输出:
[14.]
activate function 把输入掰弯
eg:relu sigmoid tanh
cnn中推荐relu,rnn中推荐relu,tanh
题外话:np.newaxis的作用
# np.newaxis分别是在行或列上增加维度,原来是(5,)的数组,
# 在行上增加维度变成(1,5)的二维数组,在列上增加维度变为(5,1)的二维数组
a=np.array([1,2,3,4,5])
b=a[np.newaxis,:]
c=a[:,np.newaxis]
print(a.shape,b.shape,c.shape)
print(a)
print(b)
print(c)
输出:
(5,) (1, 5) (5, 1)
[1 2 3 4 5]
[[1 2 3 4 5]]
[[1]
[2]
[3]
[4]
[5]]
打造第一个神经网络
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size])) ### ????
biases = tf.Variable(tf.zeros([1,out_size])+0.1)
Wx_plus_b = tf.matmul(inputs,Weights)+biases
if activation_function==None:
outputs = Wx_plus_b
else:outputs = activation_function(Wx_plus_b)
return outputs
#create data
x_data = np.linspace(-1,1,300)[:,np.newaxis]
noise = np.random.normal(0,0.05,x_data.shape)
y_data = np.square(x_data)-0.5 +noise
xs = tf.placeholder(tf.float32,[None,1])
ys = tf.placeholder(tf.float32,[None,1])
# create graph
l1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
prediction = add_layer(l1,10,1,activation_function=None)
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction),reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(loss)
init = tf.global_variables_initializer()
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data,y_data)
plt.ion()
#plt.show()#静态的
with tf.Session() as sess:
sess.run(init)
for i in range(1001):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
##可以是一部分的x_data,y_data,mini-batch
if i%50==0:
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
'''
predict_value = sess.run(prediction,feed_dict={xs:x_data})
try:ax.lines.remove(lines[0])
except Exception:pass
lines = ax.plot(x_data,predict_value,'r-',lw=5)#红色线宽=5
plt.pause(0.1)
'''
predict_value = sess.run(prediction,feed_dict={xs:x_data})
ax.plot(x_data,predict_value,'r-',lw=5)#红色线宽=5
输出:
6.1317863
0.056988537
0.008828914
0.004499426
0.0036805507
0.003411163
0.0032926842
0.003222807
0.003188555
0.0031720304
0.003157696
0.0031499555
0.0031452782
0.0031413904
0.003138115
0.0031350984
0.0031322953
0.003129168
0.0031263472
0.003123648
0.0031211614
菜鸟一只,如有错误,恳请指正。
看了一天tensorflow,脑阔疼~