简体   繁体   中英

Keras Custom Layer - NotImplementedError: Cannot convert a symbolic Tensor to a numpy array

I have created a custom layer in keras that gets an (N, 3) tensor of vertices as input. Since my layer should learn an embedding of these vertices I want to initialize the weights with a random projection of the vertices. I attempted to do this as follows:

class CustomLayer(Layer):
    def __init__(self, feat_dims,  **kwargs):
        super(CustomLayer, self).__init__(**kwargs)
        self.feat_dims = feat_dims
        self.embeddings = None
        self.first = True

    def build(self, input_shape):
        _, nvertex, k = input_shape

    def call(self, inputs, **kwargs):
        vertices = inputs
        _, nvertex, k = inputs.shape
        if self.first:
            q = tf.random.normal((k, self.feat_dims), dtype=tf.dtypes.float32)
            q = tf.transpose(tf.linalg.pinv(q))
            scale = tf.math.sqrt(tf.cast(k, tf.dtypes.float32))
            projection_m = scale * q
            projected_verts = tf.tensordot(vertices, projection_m, axes=1)
            initializer = lambda x, dtype=np.float: tf.constant(projected_verts, dtype=dtype)
            self.embeddings = self.add_weight(name="vertex_embedding", shape=(nvertex, self.feat_dims),
                                              initializer=initializer, trainable=True)
            self.first = False

    def get_config(self):
        config = {'feat_dims': self.feat_dims}

        base_config = super(CustomLayer, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

But Keras states NotImplementedError: Cannot convert a symbolic Tensor (custom_layer/strided_slice:0) to a numpy array. . Which is caused by projected_verts depending on the input (symbolic tensor). (I used the call method since I don't have access to the vertices in build() )

Is there any way I can circumvent this issue? I need to maintain the relations between vertices for a better initialization.

Edit, relevant section in Stack trace:

NotImplementedError: in user code:

/home/.../layers.py:5744 call  *
    initializer = lambda x, dtype=np.float: tf.constant(projected_verts, dtype=dtype)
/home/.../python3.8/site-packages/tensorflow/python/framework/constant_op.py:264 constant  **
    return _constant_impl(value, dtype, shape, name, verify_shape=False,
/home/.../python3.8/site-packages/tensorflow/python/framework/constant_op.py:276 _constant_impl
    return _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
/home/.../python3.8/site-packages/tensorflow/python/framework/constant_op.py:301 _constant_eager_impl
    t = convert_to_eager_tensor(value, ctx, dtype)
/home/.../python3.8/site-packages/tensorflow/python/framework/constant_op.py:98 convert_to_eager_tensor
    return ops.EagerTensor(value, ctx.device_name, dtype)
/home/.../python3.8/site-packages/tensorflow/python/framework/ops.py:867 __array__
    raise NotImplementedError(

NotImplementedError: Cannot convert a symbolic Tensor (custom_layer/strided_slice:0) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported

Try explicitly converting projected_verts into a tensor

initializer = lambda x, dtype=tf.dtypes.float32 : tf.convert_to_tensor(projected_verts)

instead of using tf.constant . Note that I also replaced np.float with tf.dtypes.float32 .

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