【发布时间】:2021-10-21 15:23:15
【问题描述】:
我在 keras 中创建了一个自定义层,它获取 (N, 3) 个顶点张量作为输入。因为我的层应该学习这些顶点的嵌入,所以我想用顶点的随机投影来初始化权重。我试图这样做:
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()))
但 Keras 声明 NotImplementedError: Cannot convert a symbolic Tensor (custom_layer/strided_slice:0) to a numpy array.。这是由projected_verts 引起的,具体取决于输入(符号张量)。 (我使用 call 方法,因为我无法访问 build() 中的顶点)
有什么办法可以规避这个问题吗?我需要维护顶点之间的关系以便更好地初始化。
编辑,堆栈跟踪中的相关部分:
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
【问题讨论】:
-
具体是哪一行抛出错误?通常我在尝试在符号张量上使用 numpy 数据类型/方法时会遇到这种错误,这通常意味着我需要将其转换为它的
tf等效值。 -
你能发布你的整个自定义层吗?
-
感谢您的回复,我已经添加了自定义层和包含错误位置的堆栈跟踪。
-
谢谢,您的输入形状是什么?或者如何使用
CustomLayer? -
我的输入形状是 (6890, 3),我想学习形状 (6890, 16) 的权重。因此,我尝试使用 input * projection_m 初始化权重,其中 projection_m 是 (3, 16) 矩阵。我只是这样称呼它:
input = Input(shape=input_shape[1:]); embeddings = CustomLayer(feat_dim)(input)
标签: python tensorflow keras deep-learning