还原保存的张量流模型时随机行为



我有一个存储的张量模型,我想确定性地评估最终预测。恢复模型和运行预测时,网络流中有一个点,张量值是以非确定性方式计算的。

这是有问题的点:

self.h0 = tf.concat([self.q_weighted, self.x_weighted], 1, name='h0')
self.h1 = tf.layers.dense(inputs=self.h0, units=512, activation=tf.nn.relu, name='h1',kernel_initializer=self.kernel_initializer, bias_initializer=self.bias_initializer)

其中:

self.kernel_initializer = tf.glorot_uniform_initializer()
self.bias_initializer = tf.truncated_normal_initializer(mean=0.011, stddev=0.005)

将多个执行与相同输入进行比较,H0的结果值是一致的,而H1的值则变化。

我构建图形并还原模型的方式:

  1. 建筑模型图(例如,上面提到的两个变量(。我创建init op(tf.global_variables_initializer(((,但在这里(只有在训练时(
  2. 才能运行它
  3. 初始化会话
  4. 加载训练的模型
  5. 运行操作以获取预测

代码:

// building network graph
// ...
// restoring trained model
self.saver = tf.train.Saver(max_to_keep=2)
self.sess = tf.Session()
self.saver.restore(self.sess, model_path)
// running network ops (without running tf.global_variables_initializer)
self.sess.run([...])

我在两个单独的执行中手动检查了H0和H1的恢复重量(内核和偏置(,并且从检查点还原后它们是相同的。

有什么想法会导致这呢?或如何处理此操作,以使执行是确定性的?

P.S-我还试图设置一个恒定的全局张量和Numpy种子。这无济于事。

**编辑**


在网络层上系统地进行操作,我发现第一个非确定性OP是redus_sum。具体而言,这条代码线:

self.x_weighted = tf.reduce_sum(tf.multiply(tf.expand_dims(self.x_weights_norm, -1), x_outputs), axis=1, name="x_weighted")

我看到这是一个已知的问题 - 请参阅此处和此处。然而,这种行为在单个CPU上复制,而将线程数限制为1,例如:

config = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1, allow_soft_placement=True, device_count={'CPU': 1})
self.sess = tf.Session(config=config)

现在,我想知道是否有另一部分设置不正确,例如导致随机性,或者即使使用这种配置也会发生redy_sum非确定性。

解决了问题。随机性是由于使用Python Hash函数的使用,应用于网络的输入。通过修复Pythonhashseed环境变量,输出已在不同的执行中变得一致。

最新更新