Недетерминированное поведение TensorFlow while_loop()
Я реализовал алгоритм с использованием while_loop
с большими матрицами, и я недавно заметил странное поведение: я получаю разные результаты с разными прогонами, иногда даже с значениями nan
. Я потратил некоторое время на сокращение проблемы, и теперь у меня есть следующий минимальный пример. Я беру большую матрицу K размером 15000x15000
заполненную единицами, а затем вычисляю K⁵u для вектора u, заполненного единицами. После одной итерации я ожидаю, что в результате вектор будет заполнен 15000
. Но это не то, что происходит.
import numpy as np
import tensorflow as tf
n = 15000
np_kernel_mat = np.ones((n, n), dtype=np.float32)
kernel_mat = tf.constant(np_kernel_mat)
# for debugging
def compare_kernel(kernel_matrix):
print("AverageDifference:" + str(np.average(np.abs(np_kernel_mat - kernel_matrix))))
print("AmountDifferent:" + str(np.count_nonzero(np.abs(np_kernel_mat - kernel_matrix))))
return True
# body of the loop
def iterate(i, u):
# for debugging
with tf.control_dependencies(tf.py_func(compare_kernel, [kernel_mat], [tf.bool])):
u = tf.identity(u)
# multiply
u = tf.matmul(kernel_mat, u)
# check result and kernel
u = tf.Print(u, [tf.count_nonzero(tf.abs(kernel_mat-np_kernel_mat))], "AmountDifferentKernel: ")
u = tf.Print(u, [tf.count_nonzero(tf.abs(u-float(n)))], "AmountDifferentRes: ")
i = i + 1
return i, u
def cond(i, u):
return tf.less(i, 5)
u0 = tf.fill((n, 1), 1.0, name='u0')
iu_0 = (tf.constant(0), u0)
iu_final = tf.while_loop(cond, iterate, iu_0, back_prop=False, parallel_iterations=1)
u_res = iu_final[1]
with tf.Session() as sess:
kernel_mat_eval, u_res_eval = sess.run([kernel_mat, u_res])
print(np.array_equal(kernel_mat_eval, np_kernel_mat))
Теперь я запускаю этот вывод:
I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:898] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:1356] Found device 0 with properties:
name: GeForce GTX TITAN X major: 5 minor: 2 memoryClockRate(GHz): 1.076
pciBusID: 0000:00:0f.0
totalMemory: 11.93GiB freeMemory: 11.81GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:1435] Adding visible gpu devices: 0
I tensorflow/core/common_runtime/gpu/gpu_device.cc:923] Device interconnect StreamExecutor with strength 1 edge matrix:
I tensorflow/core/common_runtime/gpu/gpu_device.cc:929] 0
I tensorflow/core/common_runtime/gpu/gpu_device.cc:942] 0: N
I tensorflow/core/common_runtime/gpu/gpu_device.cc:1053] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 11435 MB memory) -> physical GPU (device: 0, name: GeForce GTX TITAN X, pci bus id: 0000:00:0f.0, compute capability: 5.2)
minimal_example.py:25: RuntimeWarning: invalid value encountered in subtr[8/281]
print("AverageDifference:" + str(np.average(np.abs(np_kernel_mat - kernel_matr
ix))))
/usr/local/lib/python3.6/dist-packages/numpy/core/_methods.py:70: RuntimeWarning
: overflow encountered in reduce
ret = umr_sum(arr, axis, dtype, out, keepdims)
AverageDifference:nan
minimal_example.py:26: RuntimeWarning: invalid value encountered in subtract
print("AmountDifferent:" + str(np.count_nonzero(np.abs(np_kernel_mat - kernel_
matrix))))
AmountDifferent:4096
AmountDifferentKernel: [0]
AmountDifferentRes, DifferenceRes: [4][inf]
AverageDifference:nan
AmountDifferent:4096
AmountDifferentKernel: [0]
AmountDifferentRes, DifferenceRes: [15000][nan]
AverageDifference:nan
AmountDifferent:4096
AmountDifferentKernel: [0]
AmountDifferentRes, DifferenceRes: [15000][nan]
AverageDifference:nan
...
Понятно, что на второй итерации результат больше не 15000
, но это не объясняет, почему разница - нан. На процессоре все работает нормально (разница в том, что-то вроде 2e08
).
Теперь мои вопросы: почему вывод Print op отличается от вывода py_func
печати? Почему оценка матрицы снова равна исходной матрице? Почему я получаю разные результаты по разным прогонам? Может ли кто-нибудь воспроизвести это?
Я запускаю это на Ubuntu 16.04
, TensorFlow 1.8
, numpy 1.14
, python3.6
. GPU - GeForceGTX 1080.
NVRM version: NVIDIA UNIX x86_64 Kernel Module 390.48 Thu Mar 22 00:42:57 PDT 2018
GCC
version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
Ответы
Ответ 1
Скорее всего, ваша проблема проистекает из проблем с random.seed()
, убедитесь, что вы установили начальное число как для random.seed()
, так и для numpy.random.seed()
. Вам нужно будет заполнить оба, так как случайное случайное начальное число не зависит от random
случайного состояния.