Tensorflow定义计算图,并且可以把计算图分成几块在不同GPU上运行。
并且支持分布式训练,把计算均摊在数百个服务器上来训练超大规模的神经网络。
Creating Your First Graph and Running It in a Session
实例上下面的代码不进行任何计算,它只是创建一个计算图。
import tensorflow as tf
reset_graph()
x = tf.Variable(3, name="x")
y = tf.Variable(4, name="y")
f = x*x*y + y + 2 ###<tf.Tensor 'add_1:0' shape=() dtype=int32>
要计算上面的代码,需要打开一个session,session是把上面这个操作放到devices中,例如CPU,GPU。最后需要sess.close释放资源。如下
sess = tf.Session()
sess.run(x.initializer)
sess.run(y.initializer)
result = sess.run(f)
print(result)
每次都需要sess.run()显然太麻烦,还有一种简单的方式。在with块中,session被当成默认的session.并且结束会自动释放资源。
with tf.Session() as sess:
x.initializer.run()
y.initializer.run()
result = f.eval()
x.initializer.run() is equivalent to calling tf.get_default_session().run(x.initializer)
还有一种更简单的方式来初始化。
init = tf.global_variables_initializer()
with tf.Session() as sess:
init.run()
result = f.eval()
当使用InteractiveSession时,和常规的Session不同的是,会自动将InteractiveSession设置为默认的Session,不需要with框架,但是需要在最后关闭以释放资源。
sess = tf.InteractiveSession()
init.run()
result = f.eval()
print(result)
sess.close()
Managing Graphs
任何设置的节点都会自动添进默认的图表。
x1 = tf.Variable(1)
x1.graph is tf.get_default_graph()
有时候需要管理多个独立的图表,这时候需要创建一个新Graph并且临时得把这个图放入一个with块中,使得这个图为默认图。
graph = tf.Graph()
with graph.as_default():
x2 = tf.Variable(2)
x2.graph is graph ###true
x2.graph is tf.get_default_graph() ###Flase
在实验中,你有可能会运行同样得一条指令多次,这样会导致你的默认图中拥有很多重复的节点。 有两种方法应对这种情况:
- 重启spyder
- 使用如下指令
tf.reset_default_graph()
Lifecycle of a Node Value
当你评估一个节点时(一个节点代表一个数值),tensorflow会自动的确定此节点所依赖的所有节点,并且首先为这些节点评估。参考如下代码
w = tf.constant(3)
x = w + 2
y = x + 5
z = x * 3
with tf.Session() as sess:
print(y.eval()) # 10
print(z.eval()) # 15
首先这个代码评估y,它发现y依赖x,x依赖w,所以这个session首先evaluate,w,然后x,最后y。在评估z的时候还是会从头评估w和x,不会利用之前的结果,也就是说这行代码评估w,x两次。要想只评估一次,需要使用如下代码
with tf.Session() as sess:
y_val, z_val = sess.run([y, z])
print(y_val) # 10
print(z_val) # 15
所有节点的值在图运行之间都会被丢弃,除了variable values,它的值是由Session提供。
多个Session之间不会共享状态,即使他们运行的是同一张图,每一个Session都会拥有每一个变量的副本。在分布式tensorflow中,变量的状态存储在服务器上(Server),而不是session中,因此可以共享变量。
Linear Regression with TensorFlow
以下代码相比于直接使用numpy的直接计算,tensorflow可以把以下代码放在GPU中运行。直接使用fetch_california_housing这个函数会出错,先把如下代码放入linux中运行,得到cal_housing_py3.pkz文件,放入data_home='H:\paper\DeepLearning\Tensorflow\hand on with tensorflow\california_housing'中,即可运行成功。这里把numpy转成tensorflow 的节点
import numpy as np
from sklearn.datasets import fetch_california_housing
reset_graph()
housing = fetch_california_housing(data_home='H:\paper\DeepLearning\Tensorflow\hand on with
tensorflow\california_housing')####假如数据下载不成功则自
行下载,然后添加
m, n = housing.data.shape
housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]
X = tf.constant(housing_data_plus_bias, dtype=tf.float32, name="X")
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name="y")
XT = tf.transpose(X)
theta = tf.matmul(tf.matmul(tf.matrix_inverse(tf.matmul(XT, X)), XT), y)
with tf.Session() as sess:
theta_value = theta.eval()
使用numpy计算
X = housing_data_plus_bias
y = housing.target.reshape(-1, 1)
theta_numpy = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
print(theta_numpy)
使用sklearn进行计算
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(housing.data, housing.target.reshape(-1, 1))
print(np.r_[lin_reg.intercept_.reshape(-1, 1), lin_reg.coef_.T])
Implementing Gradient Descent
Manually Computing the Gradients
- random_uniform() 函数在图中创建一个产生tensor的节点,给定Shape和值的范围,可以产生带有随机数的tensor。与numpy的rand()类似。
- assign()为variable赋上一个新值。下面例子中θ(next step) = θ –η∇θMSE(θ)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaled_housing_data = scaler.fit_transform(housing.data)
scaled_housing_data_plus_bias = np.c_[np.ones((m, 1)), scaled_housing_data]
reset_graph()
n_epochs = 1000
learning_rate = 0.01
X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name="X")
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name="y")
theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0, seed=42), name="theta")
y_pred = tf.matmul(X, theta, name&#