tensorflow 在CPU和GPU上,tf.cast在转换负值时的行为不同,

t5fffqht  于 6个月前  发布在  其他
关注(0)|答案(5)|浏览(43)

问题类型

Bug

你是否在TF nightly版本中复现了这个bug?

是的

问题来源

source

Tensorflow版本

2.13.0.dev20230204

自定义代码

是的

OS平台和发行版

Ubuntu 20.04.4 LTS

移动设备

  • 无响应*

Python版本

  • 无响应*

Bazel版本

  • 无响应*

GCC/编译器版本

  • 无响应*

CUDA/cuDNN版本

  • 无响应*

GPU型号和内存大小

  • 无响应*

当前行为?

tf.cast behaves differently in CPU and GPU when casting negative values

独立代码以重现问题

import tensorflow as tf
import numpy as np

with tf.device('cpu'):
    data = np.array([[-1.0]]).astype(np.float64)
    x = tf.dtypes.cast(data, tf.uint8)
    print(x)
    
with tf.device('gpu'):
    data = np.array([[-1.0]]).astype(np.float64)
    x = tf.dtypes.cast(data, tf.uint8)
    print(x)

相关日志输出

tf.Tensor([[255]], shape=(1, 1), dtype=uint8)
tf.Tensor([[0]], shape=(1, 1), dtype=uint8)
pieyvz9o

pieyvz9o1#

根据C++标准,将负浮点数转换为整数的结果是未定义的:
A prvalue of a floating-point type can be converted to a prvalue of an
integer type. The conversion truncates; that is, the fractional part is
discarded.
如果截断后的值无法在目标类型中表示,则行为是未定义的。
https://github.com/cplusplus/draft/blob/5ef31f3fc1531d9e6e923cb57bf6e5ecec59ed4e/source/expressions.tex#L949-L958
这里用更易读的语言提到了(非官方):

也许TensorFlow可以通过以下两种方式之一来解决这个问题:

  • 首先对浮点数值取绝对值,或者
  • 首先将其转换为有符号整数类型
mf98qq94

mf98qq942#

我能够在Colab上使用TF v2.11和tf-nightly重现这个问题。请参考2.11tf-nightly的摘要。
谢谢!

f3temu5u

f3temu5u3#

你好,@trickiwoo
对于延迟表示歉意,并感谢@nrwahl2的详细解释和建议的解决方法。我非常感激你的努力和时间。我能够使用tensorflow 2.12.0rc0复现相同的问题,并已将gist-file添加为您的参考。
C99中,如果浮点数是less than or equal to -1.0,则行为是未定义的。如果它在(-1.0, 0.0),范围内,结果值将为0。

来自C99,§6.3.1.4,第1段

When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined
我们将不得不深入研究此问题,并很快会更新您。谢谢!

wgeznvg7

wgeznvg74#

这个问题已经被自动标记为过时,因为它没有最近的活动。如果没有进一步的活动发生,它将被关闭。谢谢。

n8ghc7c1

n8ghc7c15#

你好,@sachinprasadhs
请问您能调查一下这个问题吗?谢谢!

相关问题