Home > Net >  How to pass iterator range for `for loop` as keras input layer in TensorFlow?
How to pass iterator range for `for loop` as keras input layer in TensorFlow?

Time:12-23

I want to create a model which will take multiple inputs, with one input being number of time a loop has to be run in a custom layer, example implementation is below:

import tensorflow as tf

class TrialLayer(tf.keras.layers.Layer):
    def __init__(self):
        super().__init__()
        self.d = tf.Variable(2.0)

    def call(self, a, b,c):
        e = 0.0
        # iterator = tf.shape(tf.range(c)) # fails
        for i in range(c):
            e = e   a b self.d
        return e
# =============================================================================

input_a = tf.keras.layers.Input(shape=(1), dtype=tf.float32)
input_b = tf.keras.layers.Input(shape=(1), dtype=tf.float32)
input_c = tf.keras.layers.Input(shape=(1), dtype=tf.int32)

tl = TrialLayer()(input_a, input_b, input_c)

model = tf.keras.models.Model(inputs=[input_a,input_b,input_c], outputs=tl)

print(model([2.0,3.0,4]))

This gives the error

 ValueError: Shape must be rank 0 but is rank 2
         for 'limit' for '{{node trial_layer_1/range}} = Range[Tidx=DT_INT32](trial_layer_1/range/start, trial_layer_1/Maximum, trial_layer_1/range/delta)' with input shapes: [], [?,1], [].

How to pass iterator value as input?

CodePudding user response:

Maybe try using tf.Variable combined with tf.while_loop like this:

import tensorflow as tf

class TrialLayer(tf.keras.layers.Layer):
    def __init__(self):
        super().__init__()
        self.d = tf.Variable(2.0)

    def call(self, a, b, c):
        e = tf.Variable(0.0, shape=tf.TensorShape(None))
        i = tf.constant(0)
        while_condition = lambda i: tf.math.less_equal(i, c)
        def body(i):
            e.assign_add(a b self.d)
            return [tf.add(i, 1)]
        _ = tf.while_loop(while_condition, body, [i])
  
        return e

input_a = tf.keras.layers.Input(shape=(1), dtype=tf.float32)
input_b = tf.keras.layers.Input(shape=(1), dtype=tf.float32)
input_c = tf.keras.layers.Input(shape=(1), dtype=tf.int32)

tl = TrialLayer()(input_a, input_b, input_c)

model = tf.keras.models.Model(inputs=[input_a,input_b,input_c], outputs=tl)

tf.print(model([2.0,3.0, 4]))
# 35

You can also change the condition to tf.math.less(i, c) and get 28 as your output.

  • Related