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.