- 注:本文的设置仅针对 TensorFlow 1.x
变量的内存分配与初始值设定
变量创建 :在 TensorFlow 1.x 中,当你定义一个变量(
Variable)时,实际上是在图中创建了一个占位符(创建了一个表示该变量的节点),它仅仅定义了变量的形状和数据类型 ,并未为其分配实际的内存空间和设定初始值1
2
3import tensorflow as tf
my_variable = tf.Variable(initial_value=3.0, dtype=tf.float32)- 这里的
my_variable只是一个图中的节点,它描述了变量的基本信息,但在内存中还没有真正存储值
- 这里的
变量初始化 :在会话中执行初始化操作时(注意,初始化操作需要和变量在同一个图中),TensorFlow 会为这个变量分配内存空间,用于存储其值(注意:如果有多个会话绑定同一个图,变量需要重新初始化)
- 在 TensorFlow 1.x 里,变量的状态是与会话(Session)相关联的。每个会话都有自己独立的变量副本和状态
- 多个 Session 绑定同一个 Graph 的特殊场景 :当在一个会话中初始化变量时,只会影响该会话中的变量状态,其他会话中的同一变量仍然处于未初始化状态,如果有多个会话绑定同一个图,为了能在每个会话中正常使用变量,需要分别对每个会话中的变量进行初始化操作
防止未定义行为 :如果不进行初始化就尝试使用变量,会导致未定义行为,因为变量在内存中的值是不确定的。这可能会引发错误或得到意外的计算结果。通过强制要求初始化变量,可以确保在使用变量之前,它们已经被正确地赋予了初始值,从而保证计算的正确性和稳定性
全局变量初始化
在大多数情形下,你需要对所有的变量进行初始化。可以借助
tf.global_variables_initializer()来实现这一目的。示例如下:1
2
3
4
5
6
7
8
9
10
11
12import tensorflow as tf
a = tf.Variable(3, name='a')
b = tf.Variable(2, name='b')
c = tf.add(a, b)
with tf.Session() as sess:
# 初始化所有全局变量
init = tf.global_variables_initializer()
sess.run(init)
result = sess.run(c)
print("结果: ", result)- 在这个示例中,
tf.global_variables_initializer()会初始化所有定义的全局变量。在运行计算图之前,必须先运行这个初始化操作
- 在这个示例中,
初始化部分变量
如果你只想初始化部分变量 ,可以使用
tf.variables_initializer()。示例如下:1
2
3
4
5
6
7
8
9
10
11
12import tensorflow as tf
a = tf.Variable(3, name='a')
b = tf.Variable(2, name='b')
c = tf.add(a, b)
with tf.Session() as sess:
# 初始化部分变量
init_ab = tf.variables_initializer([a, b])
sess.run(init_ab)
result = sess.run(c)
print("结果: ", result)- 在这个示例中,
tf.variables_initializer([a, b])仅初始化了变量a和b
- 在这个示例中,
初始化单个变量
你还可以使用
variable.initializer来初始化单个变量。示例如下:1
2
3
4
5
6
7
8
9
10
11
12import tensorflow as tf
a = tf.Variable(3, name='a')
b = tf.Variable(2, name='b')
c = tf.add(a, b)
with tf.Session() as sess:
# 初始化单个变量
sess.run(a.initializer)
sess.run(b.initializer)
result = sess.run(c)
print("结果: ", result)- 在这个示例中,分别对变量
a和b进行了初始化
- 在这个示例中,分别对变量
新加入的变量都要初始化
- 在已经创建session后,依然是可以加入新的变量的,但是需要进行初始化才可以使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import tensorflow as tf
var1 = tf.Variable(3, dtype=tf.float32)
var2 = tf.Variable(5, dtype=tf.float32)
add_op1 = tf.add(var1, var2)
sess = tf.Session()
init_op = tf.global_variables_initializer() # 初始化所有变量
sess.run(init_op)
result1 = sess.run(add_op1)
print("两个变量的和:", result1)
# 在Session后继续创建变量
var3 = tf.Variable(7, dtype=tf.float32)
add_op2 = tf.add(add_op1, var3)
init_new_var = tf.variables_initializer([var3]) # 初始化新创建的变量
sess.run(init_new_var)
result2 = sess.run(add_op2)
print("三个变量的和:", result2)
sess.close() # 显式关闭会话
# 两个变量的和: 8.0
# 三个变量的和: 15.0
附录:多次初始化变量会发生什么?
在 TensorFlow 1.x 中,对同一个变量进行两次初始化后,从内存占用的角度来说,变量所占用的内存位置通常是一致的,但变量存储的值会被重置为初始值
当你在 TensorFlow 1.x 里:
- 定义一个变量时,实际上是在图中创建了一个表示该变量的节点
- 在会话中执行初始化操作时,TensorFlow 会为这个变量分配内存空间,用于存储其值
- 同一个Session中,再次对该变量执行初始化操作,并不会重新分配内存空间,而是直接在已分配的内存位置上修改存储的值
- 同一个图中,内存分配操作只会在第一次初始化时发生
示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import tensorflow as tf
var = tf.Variable(10, dtype=tf.float32)
init = tf.global_variables_initializer()
with tf.Session() as sess:
# 第一次初始化变量
sess.run(init)
print("第一次初始化后变量的值:", sess.run(var))
# 修改变量的值
assign_op = var.assign(20)
sess.run(assign_op)
print("修改变量后的值:", sess.run(var))
# 再次初始化变量
sess.run(init)
print("第二次初始化后变量的值:", sess.run(var))
# 第一次初始化后变量的值: 10.0
# 修改变量后的值: 20.0
# 第二次初始化后变量的值: 10.0- 定义变量和初始化操作 :定义了变量
var,并创建了初始化所有全局变量的操作init - 第一次初始化 :运行
init操作,此时 TensorFlow 为变量var分配内存空间,并将初始值 10 存储在该内存位置 - 修改变量的值 :使用
assign操作将变量var的值修改为 20,这会直接在已分配的内存位置上更新存储的值 - 第二次初始化 :再次运行
init操作,TensorFlow 不会重新分配内存空间,而是直接将内存中存储的值重置为初始值 10
- 定义变量和初始化操作 :定义了变量
附录:多个Session执行同一个图
核心注意点 :在 TensorFlow 1.x 中,当一个图被多个 Session 执行时,需要分别对每个 Session 中的变量进行初始化
在 TensorFlow 1.x 里,变量的状态是与会话(
Session)相关联的。每个会话都有自己独立的变量副本和状态。当你在一个会话中初始化变量时,只会影响该会话中的变量状态,其他会话中的同一变量仍然处于未初始化状态。因此,为了能在每个会话中正常使用变量,需要分别对每个会话中的变量进行初始化操作多个Session执行同一个图的示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34import tensorflow as tf
# 创建一个图
graph = tf.Graph()
with graph.as_default():
var = tf.Variable(10, dtype=tf.float32)
add_op = tf.add(var, 5)
init_op = tf.global_variables_initializer() # 注意:这个操作必须添加到图中,后续所有Session的初始化都可以调用这个操作
# 创建第一个会话
sess1 = tf.Session(graph=graph)
# 初始化第一个会话中的变量
sess1.run(init_op)
result1 = sess1.run(add_op)
print("第一个会话执行结果:", result1)
# 创建第二个会话
sess2 = tf.Session(graph=graph)
try:
result2 = sess2.run(add_op) # 尝试在未初始化变量的情况下执行操作
except tf.errors.FailedPreconditionError:
print("第二个会话未初始化变量,操作失败")
# 初始化第二个会话中的变量
sess2.run(init_op)
result2 = sess2.run(add_op) # 在第二个会话中执行操作
print("第二个会话初始化变量后执行结果:", result2)
# 关闭会话以释放资源
sess1.close()
sess2.close()
# 第一个会话执行结果: 15.0
# 第二个会话未初始化变量,操作失败
# 第二个会话初始化变量后执行结果: 15.0- 图的定义 :创建了一个图,并在图中定义了一个变量
var和一个操作add_op,同时定义初始化操作init_op - 第一个会话 :创建第一个会话
sess1,对其中的变量进行初始化(执行图中的操作init_op),然后执行操作并打印结果 - 第二个会话 :创建第二个会话
sess2,尝试在未初始化变量的情况下执行操作,会抛出FailedPreconditionError异常;捕获异常后,对第二个会话中的变量进行初始化(执行图中的操作init_op),再次执行操作并打印结果
- 图的定义 :创建了一个图,并在图中定义了一个变量