Up and Running with TensorFlow(第九章)
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="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
gradients = 2/m * tf.matmul(tf.transpose(X), error)
training_op = tf.assign(theta, theta - learning_rate * gradients)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for epoch in range(n_epochs):
if epoch % 100 == 0:
print("Epoch", epoch, "MSE =", mse.eval())
sess.run(training_op)
best_theta = theta.eval()
Using autodiff
使用如下自动计算的梯度
gradients = tf.gradients(mse, [theta])[0]
The gradients() function takes an op (in this case mse) and a list of variables (in this
case just theta), and it creates a list of ops (one per variable) to compute the gradi‐
ents of the op with regards to each variable.
a=tf.gradients(mse, [theta])[0] ,b=tf.gradients(mse, [theta])
代替上方手动计算的梯度
gradients = 2/m * tf.matmul(tf.transpose(X), error)
Using an Optimizer
事实上可以更加简单
把gradients = ...和 training_op = ... 替换成如下
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(mse)
完整代码如下
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="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(mse)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for epoch in range(n_epochs):
if epoch % 100 == 0:
print("Epoch", epoch, "MSE =", mse.eval())
sess.run(training_op)
best_theta = theta.eval()
print("Best theta:")
print(best_theta)
Feeding Data to the Training Algorithm
使用Mini-batch Gradient Descent 时,需要在每次迭代的时候,用下一个mini-batch去替代X和y,为此,我们使用placeholder,placeholder不做任何计算,他们只输出你让他们输出的值。引入placeholder函数,指定了输出tensor的数据类型。也可以指定其shape,假如shape中存在None,那么代表着任意的尺寸。
reset_graph()
A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5
with tf.Session() as sess:
B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})
B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})
print(B_val_1) ##[[6. 7. 8.]]
print(B_val_2) ##[[ 9. 10. 11.]
##[12. 13. 14.]]
上面代码中,当评估B时,需要传出feed_dict参数来指定placeholder的值
按照上面房价预测的例子,只需要修改几行代码
n_epochs = 1000
learning_rate = 0.01
reset_graph()
X = tf.placeholder(tf.float32, shape=(None, n + 1), name="X")
y = tf.placeholder(tf.float32, shape=(None, 1), 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="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(mse)
init = tf.global_variables_initializer()
n_epochs = 10
batch_size = 100
n_batches = int(np.ceil(m / batch_size))
def fetch_batch(epoch, batch_index, batch_size):
np.random.seed(epoch * n_batches + batch_index) # not shown in the book###设置种子
indices = np.random.randint(m, size=batch_size) # not shown取值[0,m)
X_batch = scaled_housing_data_plus_bias[indices] # not shown
y_batch = housing.target.reshape(-1, 1)[indices] # not shown
return X_batch, y_batch
with tf.Session() as sess:
sess.run(init)
for epoch in range(n_epochs):
for batch_index in range(n_batches):
X_batch, y_batch = fetch_batch(epoch, batch_index, batch_size)
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
best_theta = theta.eval() ###输出最佳值
Saving and Restoring Models
通过在construction phase 中(构建图的过程)创建Saver 节点,即所有变量节点都被创建。然后在execution phase 中,每当你需要保存模型的时候就运行save() 方法,只需要传入会话以及路径。
在linux中使用如下代码,中间每100个epoch存一次,以防数据丢失。
n_epochs = 1000 # not shown in the book
learning_rate = 0.01 # not shown
X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name="X") # not shown
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name="y") # not shown
theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0, seed=42), name="theta")
y_pred = tf.matmul(X, theta, name="predictions") # not shown
error = y_pred - y # not shown
mse = tf.reduce_mean(tf.square(error), name="mse") # not shown
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate) # not shown
training_op = optimizer.minimize(mse) # not shown
init = tf.global_variables_initializer()
saver = tf.train.Saver() ####saver = tf.train.Saver({"weights": theta})
with tf.Session() as sess:
sess.run(init)
for epoch in range(n_epochs):
if epoch % 100 == 0:
print("Epoch", epoch, "MSE =", mse.eval()) # not shown
save_path = saver.save(sess, "/tmp/my_model.ckpt")
sess.run(training_op)
best_theta = theta.eval()
save_path = saver.save(sess, "/tmp/my_model_final.ckpt")
with tf.Session() as sess:
saver.restore(sess, "/tmp/my_model_final.ckpt")
best_theta_restored = theta.eval() # not shown in the book
np.allclose(best_theta, best_theta_restored) ###true
当用作存储模型的时候,下面用作取出模型的with块需要注释。当为了取出模型的时候,上面用作训练的with块需要被注释。
中间可以每100个epoch保存一次模型。即:还是要写construction phase ,也需要在最后添加Saver,然而在with中,不需要sess.run(init),只需要取出模型就可以了。
Saver默认是存储或者取回所有的变量,以及变量的名字。假如需要更多控制,可以指定哪些变量需要存储或取回,以及他们使用什么名字。以下代码以名字‘weights’存储或者取回theta。在构建阶段添加
saver = tf.train.Saver({"weights": theta})
.meta文件中存储着图的结构。
直接从空的图表中恢复存储的图
reset_graph()
# notice that we start with an empty graph.
saver = tf.train.import_meta_graph("/tmp/my_model_final.ckpt.meta") # this loads the graph structure
theta = tf.get_default_graph().get_tensor_by_name("theta:0") # not shown in the book ##取出一个tensor theta这个ops的第一个输出tensor
with tf.Session() as sess:
saver.restore(sess, "/tmp/my_model_final.ckpt") # this restores the graph's state
best_theta_restored = theta.eval() # not shown in the book
np.allclose(best_theta, best_theta_restored) ###true
需要有取出tensor以便下面使用帮助你恢复一个模型。
Visualizing the Graph and Training Curves Using TensorBoard
第一步对你的程序进行微调,把图的定义和训练统计(例如MSE(training error))放入一个Log文件夹,tensorboard会从这个文件夹导入它。你每次需要使用不同的log文件夹,否则tensorboard会把不同的次运行的结果结合起来,造成结果混乱。为解决这个问题,可以加入时间戳。(UTC时间是
0时区的区时,即0度经线的地方时,比北京时间(东八区的区时,即东经120度的地方时)晚8小时),即加8小时=北京时间。
0时区的区时,即0度经线的地方时,比北京时间(东八区的区时,即东经120度的地方时)晚8小时),即加8小时=北京时间。
reset_graph()
from datetime import datetime
now = datetime.utcnow().strftime("%Y%m%d%H%M%S")
print (now)
root_logdir = "tf_logs"
logdir = "{}/run-{}/".format(root_logdir, now)
print (logdir)
n_epochs = 1000
learning_rate = 0.01
X = tf.placeholder(tf.float32, shape=(None, n + 1), name="X")
y = tf.placeholder(tf.float32, shape=(None, 1), 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="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(mse)
init = tf.global_variables_initializer()
mse_summary = tf.summary.scalar('MSE', mse)
file_writer = tf.summary.FileWriter(logdir, tf.get_default_graph())
在以上代码中,第一行在图中创建一个节点,将用来评估mse的值,这时候只是创建一个节点,如下。
第二行创建一个FileWriter,用来把summaries写入 log 目录下的logfiles中。第一个参数是log目录的地址,第二个参数是你想要可视化的图。最后FileWriter把图的定义写入events文件。
随后你需要在训练时刻,每10个batch就评估mse_summary节点。summary_str是一个summary,你可以把这个summary写入event文件,使用file_writer。
with tf.Session() as sess: # not shown in the book
sess.run(init) # not shown
for epoch in range(n_epochs): # not shown
for batch_index in range(n_batches):
X_batch, y_batch = fetch_batch(epoch, batch_index, batch_size)
if batch_index % 100 == 0:
summary_str = mse_summary.eval(feed_dict={X: X_batch, y: y_batch})
step = epoch * n_batches + batch_index
file_writer.add_summary(summary_str, step)
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
best_theta = theta.eval()
此图是根据mini_batch画出,可以看出与上面的tensorboard相比,多了SCALARS这一个。graphs与上面保持不变。
最后使用以下指令关闭
file_writer.close()
上面的代码会创建log目录并且把events文件写入这个目录,包括图的定义以及MSE的值。使用如下代码来展现tf_logs/run*下的内容。run*意思:前面三个字符为run。
加入跑了两次以上代码,则能看到
每一个节点都有很多边(连接到其他节点),为了减少不必要的混乱,把这些节点放到旁边的辅助区(右击),
打开tensorboard在tf_logs所在目录下,使用,注意不能使用ctrl+c退出,直接如下打开
source activate py36
tensorboard --logdir tf_logs/
Name Scopes
当使用神经网络时,节点之间的关系会变得复杂。可以使用名字空间(name scopes)来把相关的节点聚集起来。
使用losss名字来规定名字空间。
with tf.name_scope("losss") as scope:
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="msee")
所有在with块下面的op操作,都会被加一个前缀losss/
print(error.op.name) ##losss/sub
print(mse.op.name) ##losss/msee
在tensorboard中会把error和mse放在loss的名字空间当中。如下图,error,和mse被包在losss(loss的别名)中。
reset_graph()
a1 = tf.Variable(0, name="a") # name == "a"
a2 = tf.Variable(0, name="a") # name == "a_1"
with tf.name_scope("param"): # name == "param"
a3 = tf.Variable(0, name="a") # name == "param/a"
with tf.name_scope("param"): # name == "param_1"
a4 = tf.Variable(0, name="a") # name == "param_1/a"
for node in (a1, a2, a3, a4):
print(node.op.name)
Modularity
写代码没有模块性容易出错,例如下面这样。
reset_graph()
n_features = 3
X = tf.placeholder(tf.float32, shape=(None, n_features), name="XX")
w1 = tf.Variable(tf.random_normal((n_features, 1)), name="weights11")
w2 = tf.Variable(tf.random_normal((n_features, 1)), name="weights22")
b1 = tf.Variable(0.0, name="bias11")
b2 = tf.Variable(0.0, name="bias22")
z1 = tf.add(tf.matmul(X, w1), b1, name="z11")
z2 = tf.add(tf.matmul(X, w2), b2, name="z22")
relu1 = tf.maximum(z1, 0., name="relu11")
relu2 = tf.maximum(z1, 0., name="relu22") # Oops, cut&paste error! Did you spot it?
output = tf.add(relu1, relu2, name="output")
可以使用函数来使得代码更加简洁。
reset_graph()
def relu(X):
w_shape = (int(X.get_shape()[1]), 1)
w = tf.Variable(tf.random_normal(w_shape), name="weightss")
b = tf.Variable(0.0, name="biass")
z = tf.add(tf.matmul(X, w), b, name="zz")
return tf.maximum(z, 0., name="reluu")
n_features = 3
X = tf.placeholder(tf.float32, shape=(None, n_features), name="XX")
relus = [relu(X) for i in range(5)]
output = tf.add_n(relus, name="outputt")
file_writer = tf.summary.FileWriter("logs/relu11", tf.get_default_graph())
当你创建一个节点时,tensorboard会检查它是否已经存在,存在的话会给这个节点加一个下划线,后面跟一个索引,来使得这个节点不重复。使用上述代码创建的tensorboard如下
最好使用名字空间,这样tensorboard会显示的更加简洁。
reset_graph()
def relu(X):
with tf.name_scope("relu"):
w_shape = (int(X.get_shape()[1]), 1) # not shown in the book
w = tf.Variable(tf.random_normal(w_shape), name="weightss") # not shown
b = tf.Variable(0.0, name="biass") # not shown
z = tf.add(tf.matmul(X, w), b, name="zz") # not shown
return tf.maximum(z, 0., name="maxx")
n_features = 3
X = tf.placeholder(tf.float32, shape=(None, n_features), name="XX")
relus = [relu(X) for i in range(5)]
output = tf.add_n(relus, name="outputt")
file_writer = tf.summary.FileWriter("logs/relu22", tf.get_default_graph())
file_writer.close()
可以看出在函数开头加上名字空间relu,会把函数中的内容放入relu内部
Sharing Variables
假如你想在你的图之间的各个组件之间共享变量,最简单的方法就是先创建它,然后把这个共享变量传入需要它的函数。
reset_graph()
def relu(X, threshold):
with tf.name_scope("relu"):
w_shape = (int(X.get_shape()[1]), 1) # not shown in the book
w = tf.Variable(tf.random_normal(w_shape), name="weights") # not shown
b = tf.Variable(0.0, name="bias") # not shown
z = tf.add(tf.matmul(X, w), b, name="z") # not shown
return tf.maximum(z, threshold, name="max")
threshold = tf.Variable(0.0, name="threshold")
X = tf.placeholder(tf.float32, shape=(None, n_features), name="X")
relus = [relu(X, threshold) for i in range(5)]
output = tf.add_n(relus, name="output")
在tensorflow中还有一种更加简单的方式来创建共享变量,即使用get_variable() 函数来创建先前没有的变量,或者使用这个函数来重新使用共享变量。创建/重用操作受当前的variable_scope() 控制。例如如下代码
reset_graph()
with tf.variable_scope("relu"):
threshold = tf.get_variable("threshold", shape=(),
initializer=tf.constant_initializer(0.0))
此代码创建了一个变量,名为relu/threshold,因为此是一个标量,所以shape为(),假如这个变量被之前的get_variable()创建,那么会报错。假如你想重用此变量,那么需要使得变量范围中reuse=True.这时候不需要初始化了。
with tf.variable_scope("relu", reuse=True):
threshold = tf.get_variable("threshold")
上面代码会取回"relu/threshold" 变量。假如变量不存在或者不是由get_variable创建的,那么会报错。
reuse=True这个属性可以放在with块中,如下。
with tf.variable_scope("relu") as scope:
scope.reuse_variables()
threshold = tf.get_variable("threshold")
一旦reuse被设为True,那么在with块中就无法设置为False。假如你在此块中设置了其他的variable scopes ,那么他们的reuse也为True。最后,只有使用get_variable创建的变量才能使用reuse。
使用以下代码进行relu的多threshold设置
reset_graph()
def relu(X):
with tf.variable_scope("relu", reuse=True):
threshold = tf.get_variable("threshold")
w_shape = int(X.get_shape()[1]), 1 # not shown
w = tf.Variable(tf.random_normal(w_shape), name="weights") # not shown
b = tf.Variable(0.0, name="bias") # not shown
z = tf.add(tf.matmul(X, w), b, name="z") # not shown
return tf.maximum(z, threshold, name="max")
X = tf.placeholder(tf.float32, shape=(None, n_features), name="X")
with tf.variable_scope("relu"):
threshold = tf.get_variable("threshold", shape=(),
initializer=tf.constant_initializer(0.0))
relus = [relu(X) for relu_index in range(5)]
output = tf.add_n(relus, name="output")
首先定义relu函数,然后创建relu/threshold variable ,通过引用relu()函数创建5个ReLu,relu()函数会重用relu/threshold variable 。图的定义如下threshold同时传入给relu_1,2,3,4,5.
这个方法是把threshold的定义放在函数外面。还有一种放里面,一旦relu()函数被调用,那么在其内部创建threshold 变量,然后在后续调用中,重用此变量。需要注意,在第一次调用的时候需要把reuse设置为False(首先是创建),后面在设置为True。
reset_graph()
def relu(X):
threshold = tf.get_variable("threshold", shape=(),
initializer=tf.constant_initializer(0.0))
w_shape = (int(X.get_shape()[1]), 1) # not shown in the book
w = tf.Variable(tf.random_normal(w_shape), name="weights") # not shown
b = tf.Variable(0.0, name="bias") # not shown
z = tf.add(tf.matmul(X, w), b, name="z") # not shown
return tf.maximum(z, threshold, name="max")
X = tf.placeholder(tf.float32, shape=(None, n_features), name="X")
relus = []
for relu_index in range(5):
with tf.variable_scope("relu", reuse=(relu_index >= 1)) as scope:
relus.append(relu(X))
output = tf.add_n(relus, name="output")
图的定义如下。relu有一个箭头直接出来output,还有4个箭头指向relu_1,2,3,4
Extra material
以下代码
reset_graph()
with tf.variable_scope("my_scope"):
x0 = tf.get_variable("x", shape=(), initializer=tf.constant_initializer(0.))
x1 = tf.Variable(0., name="x")
x2 = tf.Variable(0., name="x")
with tf.variable_scope("my_scope", reuse=True):
x3 = tf.get_variable("x")
x4 = tf.Variable(0., name="x")
with tf.variable_scope("", default_name="", reuse=True):
x5 = tf.get_variable("my_scope/x")
print("x0:", x0.op.name)
print("x1:", x1.op.name)
print("x2:", x2.op.name)
print("x3:", x3.op.name)
print("x4:", x4.op.name)
print("x5:", x5.op.name)
print(x0 is x3 and x3 is x5)
对于非共享变量来说,name scope只是一个前缀,tensorflow会让前缀变得独一无二,所以才有了x4的my_scope_1/x,以及x1,x2.
Exercises
-
a_val = a.eval(session=sess) 和a_val =sess.run(a) 效果相同
-
和a_val, b_val = a.eval(session=sess), b.eval(session=sess)###1
效果不同,1运行两次图,#只运行一次。a_val, b_val = sess.run([a, b])##2
- 在local TensorFlow 中,sessions管理变量,假如创建一个包含有变量w的图,打开两个threads,并且在每个thread中打开session,同时使用同一张图,那么每一个session都会拥有一个变量w的拷贝。分布式tensorflow中,变量的值存在由cluster管理的container中,假如session连接到相同的cluster中,那么session可以共享变量w。
- 变量通过调用initializer开始它的生命周期,当session结束时,结束它的生命周期。
- 变量是一个op,用来存住一个值,当run的时候,会返回这个值。但是在run之前,需要initialize它。placeholder只拥有他所表示的tensor的shape和type,并没有值。必须通过feed_dict给placeholder传入值。原始问题为How can you set a variable to any value you want (during the execution phase)?当execution phase 时,需要设置variable的值,需要这么做。通过tf.assign()函数创建一个赋值节点,传入variable和placeholder,作为参数。如下
x = tf.Variable(tf.random_uniform(shape=(), minval=0.0, maxval=1.0)) x_new_val = tf.placeholder(shape=(), dtype=tf.float32) x_assign = tf.assign(x, x_new_val) with tf.Session(): x.initializer.run() # random number is sampled *now* print(x.eval()) # 0.646157 (some random number) x_assign.eval(feed_dict={x_new_val: 5.0}) print(x.eval()) # 5.0
上一篇: 机器学习实战------决策树
下一篇: chapter4 面向对象