我的tf.Graph中的修改改变了我的NN权重初始化

时间:2018-05-04 09:16:36

标签: python python-3.x tensorflow

在开始之前,我使用 python3.4.6 tensorflow1.4.0

我的目标是在不同输入管道下训练张量流时比较完全相同的NN架构。为此,我想首先确保相同的NN图获得与先前定义的输入管道相同的初始化权重。

我已经看到张量流中存在两个PRNG,图一和操作一。我目前正在tf.set_random_seed(777)设置图表的种子。

为了方便起见,我在下面列出了几个输入管道及其权重输出(它们的子集)不同的代码:

代码1

import tensorflow as tf

g = tf.Graph()
with g.as_default():

    # Set graph seed
    tf.set_random_seed(777)

    # Input placeholders
    input_x = tf.placeholder(tf.float32, shape=(None, 512, 512, 3))
    labels = tf.placeholder(tf.int64, shape=(None, 1))

    # Dummy placeholder
    # dummy = tf.placeholder(tf.int32)

    # Example Model
    conv1_1 = tf.layers.conv2d(input_x, 8, 3, activation=tf.nn.relu, name='conv1_1')
    conv1_2 = tf.layers.conv2d(conv1_1, 8, 3, activation=tf.nn.relu, name='conv1_2')
    pool1 = tf.layers.max_pooling2d(conv1_2, 2, 2, name="pool1")

    session_conf = tf.ConfigProto(log_device_placement=False)
    with tf.Session(config=session_conf) as sess:
        sess.run([tf.local_variables_initializer(), tf.global_variables_initializer()])

        conv1_1_kernels = [v for v in tf.trainable_variables() if v.name == "conv1_1/kernel:0"][0]
        print(sess.run(conv1_1_kernels)[:, :, 0, 0])

输出代码1:

  

[[0.03720146 0.0177983 -0.18485998]

     

[0.22072873 -0.14565685 0.21660429]

     

[ - 0.15442888 0.12140495 -0.05090818]]

代码2

import tensorflow as tf

g = tf.Graph()
with g.as_default():

    # Set graph seed
    tf.set_random_seed(777)

    # Input placeholders
    input_x = tf.placeholder(tf.float32, shape=(None, 512, 512, 3))
    labels = tf.placeholder(tf.int64, shape=(None, 1))

    # Dummy placeholder
    dummy = tf.placeholder(tf.int32)

    # Example Model
    conv1_1 = tf.layers.conv2d(input_x, 8, 3, activation=tf.nn.relu, name='conv1_1')
    conv1_2 = tf.layers.conv2d(conv1_1, 8, 3, activation=tf.nn.relu, name='conv1_2')
    pool1 = tf.layers.max_pooling2d(conv1_2, 2, 2, name="pool1")

    session_conf = tf.ConfigProto(log_device_placement=False)
    with tf.Session(config=session_conf) as sess:
        sess.run([tf.local_variables_initializer(), tf.global_variables_initializer()])

        conv1_1_kernels = [v for v in tf.trainable_variables() if v.name == "conv1_1/kernel:0"][0]
        print(sess.run(conv1_1_kernels)[:, :, 0, 0])

输出代码2:

  

[[ - 0.20316723 0.01109874 -0.16709594]

     

[0.22850838 -0.10679846 -0.22449632]

     

[ - 0.13468848 0.12664327 0.2225503]]

这些代码通过占位符定义我的输入管道,并定义一个简单的NN图。然后我们开始tf.Session作为sess来评估第一层conv1_1中第一个内核的第一个通道上的当前权重。

代码1 代码2 之间的主要区别在于我们是否对dummy占位符进行了评论。 我已经多次独立重新运行两个代码并且权重一致

那么,是否有人知道如何在我的NN层上获得相同权重,如果我定义dummy占位符?为什么tensorflow PRNG依赖于之前的占位符(不需要PRNG)?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

正如documentation中所述:

  

如果设置了图级别种子,但操作种子不是:系统确定性地将操作种子与图级别种子一起选取,以便它获得唯一的随机序列。

看起来这个“确定性选择”取决于图表内容。

因此,为了获得可重现的结果,您还需要传递操作级别的种子:

import tensorflow as tf


g = tf.Graph()
with g.as_default():

    # Set graph seed
    tf.set_random_seed(777)

    # Input placeholders
    input_x = tf.placeholder(tf.float32, shape=(None, 512, 512, 3))
    labels = tf.placeholder(tf.int64, shape=(None, 1))

    # Dummy placeholder
    dummy = tf.placeholder(tf.int32)

    # Example Model
    conv1_1 = tf.layers.conv2d(
        input_x, 8, 3, 
        activation=tf.nn.relu, 
        name='conv1_1', 
        kernel_initializer=tf.glorot_uniform_initializer(seed=1)
    )
    conv1_2 = tf.layers.conv2d(
        conv1_1, 8, 3, 
        activation=tf.nn.relu, 
        name='conv1_2', 
        kernel_initializer=tf.glorot_uniform_initializer(seed=2)
    )
    pool1 = tf.layers.max_pooling2d(conv1_2, 2, 2, name="pool1")

    session_conf = tf.ConfigProto(log_device_placement=False)
    with tf.Session(config=session_conf) as sess:
        sess.run([tf.local_variables_initializer(), tf.global_variables_initializer()])

        conv1_1_kernels = [v for v in tf.trainable_variables() if v.name == "conv1_1/kernel:0"][0]
        print(sess.run(conv1_1_kernels)[:, :, 0, 0])

我刚刚添加了kernel_initializer个参数。它们应该被添加到两个脚本中。