简体   繁体   中英

How to use tf.clip_by_value() on sliced tensor in tensorflow?

I am using RNN to predict Humidity and Temperature for next hour based on the Humidity and Temperature values for last 24 hours. To train the model my input and output tensors are in shape of [24, 2] as shown below:

[[23, 78],
 [24, 79],
 [25, 78],
 [23, 81],
  .......
 [27, 82],
 [21, 87],
 [28, 88],
 [23, 90]]

Here I want to clip the values of only Humidity column(second) between 0 and 100 as it cant go beyond that.

The code I am using for that purpose is

.....
outputs[:,1] = tf.clip_by_value(outputs[:,1], 0, 100)
.....

And getting the following error:

'Tensor' object does not support item assignment

What should be right way to use tf.clip_by_value() only to one column?

I think the most straightforward (but maybe not optimal) way is to split outputs along the second dimension using tf.split , then apply the clipping and concatenate back (if needed).

temperature, humidity = tf.split(output, 2, axis=1)
humidity = tf.clip_by_value(humidity, 0, 100)

# optional concat
clipped_output = tf.concat([temperature, humidity], axis=1)

If your outputs is a variable, you can use tf.assign :

tf.assign(outputs[:,1], tf.clip_by_value(outputs[:,1], 0, 100))

import tensorflow as tf
a = tf.Variable([[23, 78],
 [24, 79],
 [25, 78],
 [23, 81],
 [27, 82],
 [21, 87],
 [28, 88],
 [23, 90]])

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    clipped_value = tf.clip_by_value(a[:,1], 80, 85)
    sess.run(tf.assign(a[:,1], clipped_value))
    print(sess.run(a))

#[[23 80]
# [24 80]
# [25 80]
# [23 81]
# [27 82]
# [21 85]
# [28 85]
# [23 85]]

The following is not documented on the man page https://www.tensorflow.org/api_docs/python/tf/clip_by_value , but in my tests it seems to work: clip_by_value should support broadcasting. If so, the easiest (as in: not creating temporary tensors) way to do this clipping is the following:

outputs = tf.clip_by_value(outputs, [[-2147483647, 0]], [[2147483647, 100]])

Here I'm assuming you're using tf.int32 dtype, hence the min and max values for the field you don't want to clip. Admittedly it's not super nice, it looks better for floats where you can use -numpy.inf and numpy.inf instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM