因此,我有一个用Tensorflow编写的非常简单的NN脚本,并且我很难找到一些“随机性”来自何处。
我已经记录了
重量
渐变
Logits
我训练时的网络,对于第一次迭代,很明显,一切都始于相同的过程。我有一个SEED值,用于读取数据,还有一个SEED值,用于初始化网络的权重。我永远不会改变的那些。
我的问题是,说我每次重试的第二次迭代,我开始看到梯度发散(少量,例如1e-6左右)。但是随着时间的流逝,这当然会导致不可重复的行为。
这可能是什么原因?我不知道任何可能的随机性来源可能来自...
谢谢
最佳答案
如果在Eigen线程池(export CUDA_VISIBLE_DEVICES=
)中使用单线程,一个Python线程(没有多线程队列运行器)在CPU(tf.Session(config=tf.ConfigProto(intra_op_parallelism_threads=1)
)上运行网络,则很有可能获得确定性的结果。 (如tf.batch
这样的操作),以及一个定义明确的操作顺序。在某些情况下,使用inter_op_parallelism_threads=1
也可能会有所帮助。
一个问题是浮点加法/乘法是非关联的,因此要获得确定性结果的一种简单方法是使用整数算术或量化值。
除非这样做,否则您可以隔离哪个操作不确定,并尝试避免使用该操作。例如,有一个tf.add_n
op,它没有说明其求和值的顺序,但是不同的顺序会产生不同的结果。
获得确定性的结果有点艰巨,因为确定性与性能冲突,而性能通常是引起更多关注的目标。尝试在重运行中使用完全相同的数字的另一种方法是着眼于数值稳定性-如果算法稳定,那么即使精确的参数值可能略有不同,您仍将获得可重现的结果(即,错误分类的数目相同)