我有一个存储的Tensorflow模型,我想确定性地评估最终预测。在恢复模型和运行预测时,网络流中存在一个点,其中张量值(意外地)以非确定性方式计算。
这是有问题的一点:
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的值则是一致的。
我构建图表并恢复模型的方式:
代码:
// 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 - 我还尝试设置一个恒定的全局Tensorflow和Numpy种子。那没有用。
**编辑**
系统地通过网络层我发现第一个非确定性操作是reduce_sum。具体来说,这行代码:
self.x_weighted = tf.reduce_sum(tf.multiply(tf.expand_dims(self.x_weights_norm, -1), x_outputs), axis=1, name="x_weighted")
我看到这是一个已知问题 - 请参阅here和here。 然而,这种行为在单个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)
现在,我想知道是否还有其他部分未正确设置,例如导致随机性,或者即使使用此配置,仍会发生reduce_sum非确定性。
答案 0 :(得分:0)
问题解决了。随机性是由于使用了python哈希函数,应用于网络的输入。通过修复PYTHONHASHSEED环境变量,输出在不同的执行中变得一致。