Zach Moshe
Zach Moshe

Reputation: 2980

tf.keras.layers.Concatenate() works with a list but fails on a tuple of tensors

This will work:

tf.keras.layers.Concatenate()([features['a'], features['b']])

While this:

tf.keras.layers.Concatenate()((features['a'], features['b']))

Results in:

TypeError: int() argument must be a string or a number, not 'TensorShapeV1'

Is that expected? If so - why does it matter what sequence do I pass?

Thanks, Zach

EDIT (adding a code example):

import pandas as pd
import numpy as np

data = {
    'a': [1.0, 2.0, 3.0],
    'b': [0.1, 0.3, 0.2],
}

with tf.Session() as sess: 
  ds = tf.data.Dataset.from_tensor_slices(data)
  ds = ds.batch(1)

  it = ds.make_one_shot_iterator()
  features = it.get_next()

  concat = tf.keras.layers.Concatenate()((features['a'], features['b']))


  try:
    while True:
      print(sess.run(concat))
  except tf.errors.OutOfRangeError:
    pass


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-135-0e1a45017941> in <module>()
      6   features = it.get_next()
      7 
----> 8   concat = tf.keras.layers.Concatenate()((features['a'], features['b']))
      9 
     10 

google3/third_party/tensorflow/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
    751           # the user has manually overwritten the build method do we need to
    752           # build it.
--> 753           self.build(input_shapes)
    754         # We must set self.built since user defined build functions are not
    755         # constrained to set self.built.

google3/third_party/tensorflow/python/keras/utils/tf_utils.py in wrapper(instance, input_shape)
    148             tuple(tensor_shape.TensorShape(x).as_list()) for x in input_shape]
    149       else:
--> 150         input_shape = tuple(tensor_shape.TensorShape(input_shape).as_list())
    151     output_shape = fn(instance, input_shape)
    152     if output_shape is not None:

google3/third_party/tensorflow/python/framework/tensor_shape.py in __init__(self, dims)
    688       else:
    689         # Got a list of dimensions
--> 690         self._dims = [as_dimension(d) for d in dims_iter]
    691 
    692   @property

google3/third_party/tensorflow/python/framework/tensor_shape.py in as_dimension(value)
    630     return value
    631   else:
--> 632     return Dimension(value)
    633 
    634 

google3/third_party/tensorflow/python/framework/tensor_shape.py in __init__(self, value)
    183       raise TypeError("Cannot convert %s to Dimension" % value)
    184     else:
--> 185       self._value = int(value)
    186       if (not isinstance(value, compat.bytes_or_text_types) and
    187           self._value != value):

TypeError: int() argument must be a string or a number, not 'TensorShapeV1'

Upvotes: 5

Views: 1997

Answers (1)

Mete Han Kahraman
Mete Han Kahraman

Reputation: 760

https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L329

comment on the concanate class states it requires a list. this class calls K.backend's concatenate function https://github.com/keras-team/keras/blob/master/keras/backend/tensorflow_backend.py#L2041

which also states it requires a list.

in tensorflow https://github.com/tensorflow/tensorflow/blob/r1.12/tensorflow/python/ops/array_ops.py#L1034

also states it requires a list of tensors. Why? I don't know. in this function the tensors (variable called "values") actually gets checked if its a list or tuple. but somewhere along the way you still get an error.

Upvotes: 4

Related Questions