9

I'd like division to return 0. for 0./0. instead of NaN or an error in a tensorflow application.

I know how I can do this in numpy [1], [2], but I'm new to tensorflow.

How can this be achieved?

A Sz
  • 984
  • 7
  • 19
  • 9
    `tf.where(tf.less(s, 1e-7), s, 1./s)` – Yaroslav Bulatov Aug 02 '17 at 16:24
  • @YaroslavBulatov Thanks for the pointer! Wouldn't it rather be `tf.where(tf.equal(s, 0.), s, 1./s)`? Or is there a numerical/robustness reason you suggested <10^(-7)? – A Sz Aug 02 '17 at 17:57
  • 1
    Yes, robustness, you should generally not do exact equality tests on floating point numbers, those tests can fail non-deterministically on modern hardware (http://blog.nag.com/2011/02/wandering-precision.html) – Yaroslav Bulatov Aug 02 '17 at 18:01
  • 1
    @YaroslavBulatov I'd like the equivalent of `tf.realdiv(a, b)`, not a mere inversion. with `div0 = lambda s: tf.where(tf.less(s, 1e-7), s, 1./s)`, I could use `a * div0(b)`, but that is neither readable, nor do I think that's robust / optimal performance wise. – A Sz Aug 02 '17 at 18:03
  • 1
    For whoever comes across this - the suggestion by Yaroslav Bulatov can result in NaNs, *regardless* of the fact the NaNs are on the non-taken branch of the tf.where call. See this issue on github: https://github.com/tensorflow/tensorflow/issues/20091 – Moos Hueting Jan 10 '19 at 17:26
  • 1
    Even though this question is old, tf.math.divide_no_nan (https://www.tensorflow.org/api_docs/python/tf/math/divide_no_nan) should do exactly what you want – Frithjof Mar 31 '20 at 08:24
  • @Frithjof, please do add this as an answer. I will happily accept this as the solution. It seems to have been introduced in the 1.x line with release 1.15 on Oct 16, 2019, as a backport from 2.0 (it is not present in the 1.14 release). So while it could not have been the answer when asking, it most certainly is for people coming across the question today! – A Sz May 13 '20 at 07:47
  • @ASz Thanks! The answer by Clock ZHONG that was added in the meantime should cover this. :) – Frithjof May 13 '20 at 11:21
  • @Frithjof yeah, I only noticed that entry after writing the comment. – A Sz May 14 '20 at 10:06

1 Answers1

6

This question is asked 2 years ago, not sure whether this API is supported at that time, but Tensorflow 2.X really support it now:

#Computes a safe divide which returns 0 if the y is zero.
tf.math.divide_no_nan(
    x, y, name=None
)

Args:

x: A Tensor. Must be one of the following types: float32, float64.

y: A Tensor whose dtype is compatible with x.

name: A name for the operation (optional).

Returns:

The element-wise value of the x divided by y.

You need pay attention to the argument type, they should be only tf.float32 or tf.float64, if tf.int*, tf2.x will report error. The following is my testing codes runned correctly in colab:

import tensorflow as tf
myShape=(30,30)
a = tf.constant(2, shape=myShape, dtype=tf.float32)
z = tf.constant(0, shape=myShape, dtype=tf.float32 )
cz2 = tf.math.divide_no_nan(a, z)
print(cz2)
Clock ZHONG
  • 875
  • 9
  • 23
  • 1
    At first, my testing code go wrong, because I didn't assign the dtype as tf.float*, its default is integer type, this will cause error, not sure why tensorflow team could endure this restriction. – Clock ZHONG May 06 '20 at 08:50
  • 1
    It seems the method has been introduced with 2.0 only and then backported to the 1.15 release (released on Oct 16 2019), as it is not present in the 1.14 API. So it was definitely not in the API at the time of originally asking the question. – A Sz May 13 '20 at 08:07
  • @ASz , yes, the Tensorflow is still in active development status, those APIs are kept changing, new APIs and modifications are still added sometimes in recent releases. Comparing with tensorflows index mechanism, I like more using numpy APIs, numpy APIs are more flexible and more stable but fewer restrictions than tensorflow's API in current status. – Clock ZHONG May 14 '20 at 08:12