一、计算图
1、实现const + const
用图形表示如下:
其表示两个常量相加,与后边的placeholder相比,placeholder更加灵活:先贴出这种常量的代码:
import tensorflow as tf
node1 = tf.constant(1.0,dtype=float32)
node2 = tf.constant(2.0)
add_two_node = tf.add(node1,node2)
sess = tf.Session()
print(sess.run(add_two_node))
其运行结果:3.0
刚开始使用python语言,同时也是开始学习tensorflow,感觉这样也太麻烦了,一个常量,非得整个constant函数来初始化,搞的太繁琐了,要是直接node1=1,不就完事了吗???
2、使用placeholder实现a+b
与前面的相比,感觉这个图形表示还是一样:
根据上面这个图片,与前面两个const
相加比较,这里的a和b就是两个变量,可以任意赋值,计算两者相加的结果,而上面的方法
node1和node2已经是定值(无法再次赋值),这里也贴出使用placeholder的参考代码:
import tensorflow as tf
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_two = a + b
sess = tf.Session()
print(sess.run(adder_two,{a:1,b:5}))
print(sess.run(adder_two,(a:[1,1],b:[1,2])))
计算结果如下:6.0
[2. 3.]
相比C语言,这些东西实在有些拐弯抹角,不过确实好用
3、较复杂的计算图---示例一
计算图如下:
用公式表示: add_and = (a + b) * y
直接在上面的placeholder上边的代码添加:
# -- coding:utf-8 --
# 简单测试
import input_data
mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
import tensorflow as tf
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
add_two = a+b
add_triple = add_two * 3
sess = tf.Session()
print(sess.run(add_two,{a:1,b:5}))
print(sess.run(add_two,{a:[1,1],b:[1,2]}))
print(sess.run(add_triple,{a:[1,1],b:[1,2]}))
# -- coding:utf-8 -- 这行代码使其支持中文注释
在上面计算a+b的基础上添加的两行代码:
add_triple = add_two*3
print(sess.run(add_triple,{a:[1,1],b:[1,2]}))
运行结果如下:6.0
[2. 3.]
[6. 9.]
4、较复杂的计算图-----示例二
# -- coding:utf-8 --
# 简单测试
import input_data
mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
import tensorflow as tf
W = tf.Variable([.3],dtype=tf.float32)
b = tf.Variable([-.3],dtype=tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W * x + b
sess = tf.Session()
#init = tf.global_variables_initializer()
init = tf.initialize_all_variables()
sess.run(init)
print(sess.run(linear_model,{x:[1,2,3,4]}))
官方的参考使用:
init = tf.global_variables_initializer()
运行出现错误,与我安装的tensorflow的版本不同。
这里使用了tf.Variable()来声明一个变量,但是这个变量在使用W = tf.Variable(...)后,其还没有被初始化,只是定义W的type和初始值,当后面调用
tf.initializer_all_variables()完成对所有的以tf.Variable(...)声明的变量的初始化了。该代码运行结果如下:
[ 0. 0.30000001 0.60000002 0.90000004]
即是:[1,2,3,4]*0.3-0.3
上面说到,关于constant、placeholder和Variable三种变量的使用,constant-----不能改变了,placeholder----随时可以改变 ,Variable使用什么改变刚开始指定的值呢???
如下:
fixW = tf.assign(W, [-1.])
fixb = tf.assign(b, [1.])
sess.run([fixW, fixb])
改变W和b的值:W=-1 and b=1
二、tf.train API
关于训练学习相关的API,用官方的一个例子说明:
# -- coding:utf-8 --
import tensorflow as tf
# Model parameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# Model input and output
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)
# loss
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
# training data
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]
# training loop
init = tf.initialize_all_variables()
#init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
sess.run(train, {x: x_train, y: y_train})
# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
还是为了在我的机器上运行,修改了的init,看上去,这个程序有点跟Makefile的理解流程相似:
首先看到1000次循环,要计算train,然后往前看train=optimizer.minimize(loss):就是最小化损失函数loss,然后又往前看损失函数的公式,看到这里就根据提供的初值计算损失函数公式,当然这里有一个关于梯度的学习:
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
按照流程的思路,这两句包含太多的东西,其中好多东西都交给的tensorflow底层实现。为了得到loss函数的最小值,那么用什么方法--------高中都学过使用导数求一个函数的极小点(当然不一定可以求到极小点,只要足够小即可),那么就从最开始给定的x、y值求,然后以0.01的步长向loss减小的方向移动,直到1000次循环结束。
最后两行代码:
# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
当1000次循环结束后,我们得到了W、b(目的就是为了得到W、b),相当于我们就得到了一个函数f(x) = W*x + b,(学习一个函数,使输入是x,经过f(x)函数,输入y),这两行代码意思就是根据x_train的值计算y的值,然后y与y_train比较得出loss大小。
(参考tensorflow官方网站:https://www.tensorflow.org/get_started/get_started)可能需要翻墙