tf.reduce_sum на GPU терпит неудачу в сочетании с заполнителем в качестве формы ввода
UPDATE:
Исправлено в Tensorflow 1.14.0 (возможно, раньше, не проверял)
UPDATE:
По-прежнему происходит в Tensorflow 1.7.0
UPDATE:
Я написал записную книжку, которая воспроизводит эту ошибку на оборудовании Google gpu: https://drive.google.com/file/d/13V87kSTyyFVMM7NoJNk9QTsCYS7FRbyz/view?usp=sharing
UPDATE:
После ошибочного обвинения в первом пересмотре этого вопроса tf.gather
я теперь сузил его до tf.reduce_sum
в сочетании с заполнителем в форме:
tf.reduce_sum
создает нули (только на графическом процессоре) для больших тензоров, форма которых зависит от заполнителя.
Выполнение следующего кода при подаче большого целого числа в заполнитель batch_size
(> 700000 в моем случае):
import tensorflow as tf
import numpy as np
graph = tf.Graph()
with graph.as_default():
batch_size = tf.placeholder(tf.int32,shape=[])
ones_with_placeholder = tf.ones([batch_size,256,4])
sum_out = tf.reduce_sum(ones_with_placeholder,axis=2)
min_sum_out = tf.reduce_min(sum_out)
sess = tf.Session(graph=graph)
sum_result,min_sum_result = sess.run([sum_out,min_sum_out],feed_dict={batch_size: 1000000})
print("Min value in sum_out processed on host with numpy:", np.min(sum_result))
print("Min value in sum_out tensor processed in graph with tf:", min_sum_result)
Отображается следующий неверный результат:
Min value in sum_out processed on host with numpy: 0.0
Min value in sum_out tensor processed in graph with tf: 0.0
Я ожидал, что применение reduce_sum
к оси 2 должно повсеместно привести к 4.0!
Запуск этого точного кода на процессоре приводит к правильным результатам. Кроме того, выполнение этого с фиксированной формой для tf.ones приводит к правильным результатам как на CPU, так и на GPU:
ones_with_fixed_shape = tf.ones([1000000,256,4])
sum_out = tf.reduce_sum(ones_with_fixed_shape,axis=2)
В чем проблема с заполнителем на GPU?
Ответы
Ответ 1
Основная проблема заключается в том, что существует компромисс скорости и точности. Несмотря на то, что ваш пример кажется тривиальным: весь тензор, инициализированный 1, содержит 1,024B записей. Обратите внимание, что int32 может представлять целые числа в диапазоне [-2, 147,483,648 до 2,147,483,647] без потери точности:
Поэтому мы ожидаем увидеть некоторую ошибку, если будем накапливать все записи и выполнять вычисления. Это также объясняет, почему меньшие матрицы не проявляют проблемы (меньший размер партии).