张量流梯度更新的确定性?
Determinism in tensorflow gradient updates?
所以我有一个用 Tensorflow 编写的非常简单的 NN 脚本,我很难追踪一些 "randomness" 是从哪里来的。
我已经记录了
- 权重,
- 渐变,
- 对数
我训练的网络,对于第一次迭代,很明显一切都以相同的方式开始。我有一个关于如何读入数据的 SEED 值,还有一个用于初始化网络权重的 SEED 值。那些我永远不会改变。
我的问题是,在我做的每个重新 运行 的第二次迭代中,我开始看到 梯度 发散,(少量,比如说,1e-6 左右)。然而,随着时间的推移,这当然会导致不可重复的行为。
这可能是什么原因?我不知道任何可能的随机性来源可能来自哪里...
谢谢
如果您 运行 您的网络在 CPU (export CUDA_VISIBLE_DEVICES=
) 上,在 Eigen 线程池中使用单线程 (tf.Session(config=tf.ConfigProto(intra_op_parallelism_threads=1)
),一个 Python 线程(没有多线程队列 - 运行 你从像 tf.batch
这样的 ops 获得的线程),以及一个明确定义的操作顺序。此外,使用 inter_op_parallelism_threads=1
在某些情况下可能会有所帮助。
一个问题是浮点数 addition/multiplication 是非关联的,因此获得确定性结果的一种万无一失的方法是使用整数运算或量化值。
除此之外,您可以隔离哪个操作是不确定的,并尽量避免使用该操作。例如,有一个 tf.add_n
运算符,它没有说明对值求和的顺序,但不同的顺序会产生不同的结果。
获得确定性结果是一场艰苦的战斗,因为确定性与性能相冲突,而性能通常是更受关注的目标。尝试在 re运行s 上使用完全相同的数字的另一种方法是关注数值稳定性——如果您的算法稳定,那么您将获得可重现的结果(即相同数量的错误分类),即使是精确的参数值可能略有不同
tensorflow reduce_sum op 被特别称为 non-deterministic。此外,reduce_sum 用于计算偏置梯度。
This post 讨论了一种避免使用 reduce_sum 的变通方法(即,对任何向量与全 1 的向量进行点积与 reduce_sum 相同)
我遇到了同样的问题..
对我来说可行的解决方案是:
1- 使用 tf.set_random_seed(1)
以使所有 tf 函数在每个新 运行
时都具有相同的种子
2- 使用 CPU 而不是 GPU 训练模型,以避免 GPU 由于精度而导致的不确定性操作。
所以我有一个用 Tensorflow 编写的非常简单的 NN 脚本,我很难追踪一些 "randomness" 是从哪里来的。
我已经记录了
- 权重,
- 渐变,
- 对数
我训练的网络,对于第一次迭代,很明显一切都以相同的方式开始。我有一个关于如何读入数据的 SEED 值,还有一个用于初始化网络权重的 SEED 值。那些我永远不会改变。
我的问题是,在我做的每个重新 运行 的第二次迭代中,我开始看到 梯度 发散,(少量,比如说,1e-6 左右)。然而,随着时间的推移,这当然会导致不可重复的行为。
这可能是什么原因?我不知道任何可能的随机性来源可能来自哪里...
谢谢
如果您 运行 您的网络在 CPU (export CUDA_VISIBLE_DEVICES=
) 上,在 Eigen 线程池中使用单线程 (tf.Session(config=tf.ConfigProto(intra_op_parallelism_threads=1)
),一个 Python 线程(没有多线程队列 - 运行 你从像 tf.batch
这样的 ops 获得的线程),以及一个明确定义的操作顺序。此外,使用 inter_op_parallelism_threads=1
在某些情况下可能会有所帮助。
一个问题是浮点数 addition/multiplication 是非关联的,因此获得确定性结果的一种万无一失的方法是使用整数运算或量化值。
除此之外,您可以隔离哪个操作是不确定的,并尽量避免使用该操作。例如,有一个 tf.add_n
运算符,它没有说明对值求和的顺序,但不同的顺序会产生不同的结果。
获得确定性结果是一场艰苦的战斗,因为确定性与性能相冲突,而性能通常是更受关注的目标。尝试在 re运行s 上使用完全相同的数字的另一种方法是关注数值稳定性——如果您的算法稳定,那么您将获得可重现的结果(即相同数量的错误分类),即使是精确的参数值可能略有不同
tensorflow reduce_sum op 被特别称为 non-deterministic。此外,reduce_sum 用于计算偏置梯度。
This post 讨论了一种避免使用 reduce_sum 的变通方法(即,对任何向量与全 1 的向量进行点积与 reduce_sum 相同)
我遇到了同样的问题.. 对我来说可行的解决方案是:
1- 使用 tf.set_random_seed(1)
以使所有 tf 函数在每个新 运行
2- 使用 CPU 而不是 GPU 训练模型,以避免 GPU 由于精度而导致的不确定性操作。