TensorFlow——变量初始化

  • 注:本文的设置仅针对 TensorFlow 1.x

变量的内存分配与初始值设定

  • 变量创建 :在 TensorFlow 1.x 中,当你定义一个变量(Variable)时,实际上是在图中创建了一个占位符(创建了一个表示该变量的节点),它仅仅定义了变量的形状数据类型并未为其分配实际的内存空间设定初始值

    1
    2
    3
    import 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
    12
    import 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
    12
    import 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])仅初始化了变量ab

初始化单个变量

  • 你还可以使用variable.initializer来初始化单个变量。示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import 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)
    • 在这个示例中,分别对变量ab进行了初始化

新加入的变量都要初始化

  • 在已经创建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
    import 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
    22
    import 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
    34
    import 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),再次执行操作并打印结果