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

 

在实验中,你有可能会运行同样得一条指令多次,这样会导致你的默认图中拥有很多重复的节点。    有两种方法应对这种情况:

  1. 重启spyder
  2. 使用如下指令
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

  1. random_uniform() 函数在图中创建一个产生tensor的节点,给定Shape和值的范围,可以产生带有随机数的tensor。与numpy的rand()类似。
  2. 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()

 

  1.  

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

  1. a_val = a.eval(session=sess) 和a_val =sess.run(a) 效果相同
  2. a_val, b_val = a.eval(session=sess), b.eval(session=sess)###1
    a_val, b_val = sess.run([a, b])##2
    效果不同,1运行两次图,#只运行一次。
  3. 在local TensorFlow 中,sessions管理变量,假如创建一个包含有变量w的图,打开两个threads,并且在每个thread中打开session,同时使用同一张图,那么每一个session都会拥有一个变量w的拷贝。分布式tensorflow中,变量的值存在由cluster管理的container中,假如session连接到相同的cluster中,那么session可以共享变量w。
  4. 变量通过调用initializer开始它的生命周期,当session结束时,结束它的生命周期。
  5. 变量是一个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

     

​​​​​​​

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值