输入张量传递给具有错误形状的自定义层
我正在尝试创建一个自定义的keras层。该层将在部署前添加到经过训练的模型中,以便具有包含所有预处理步骤的模型。在训练中,由于多种原因,将在模型之外进行预处理。因此,该层将永远不会用于培训。
该层的输入是带有64个组件的浮子的一维张量。该向量包含基于映射的冗余值。映射是64个字符串的名称列表。具有相同名称的元素是多余的。该层应该根据在层的初始化处提供的映射来选择每组冗余值的中间。
def pick_median(X, name, mapping):
mask = (mapping == name)
median = tfp.stats.percentile(X[mask], 50.0, interpolation='midpoint')
return median
class PickMedianLayer(tf.keras.layers.Layer):
def __init__(self, mapping:List[str], **kwargs):
super(PickMedianLayer, self).__init__(**kwargs)
self.mapping= tf.constant(mapping, dtype='string')
self.map_value_set = tf.constant(list(set(mapping)), dtype='string')
self.trainable = False
def build(self, input_shape):
pass
def call(self, X):
picked_vec = tf.map_fn(fn=lambda name: pick_median(X, name, self.mapping), elems=self.map_value_set, fn_output_signature='float32')
return picked_vec
我使用tf.map_fn为映射中的每个唯一名称创建一个张量组件。 作为对图层的第一个简单测试,我创建了一个KERAS模型,仅包含自定义层,并试图预测一个简单的向量:
rel_model = Sequential()
rel_model.add(ToFuncLayer(mapping=mapping))
rel_model.compile()
#rel_model.build(input_shape=tf.TensorShape([64]))
vec = 1000. * tf.ones((64,), dtype='float32')
print(vec.shape)
vec1 = rel_model.predict(vec)
print(vec1)
print(vec1.shape)
我会在执行预测时获得错误“ valueerror:dureatorror:32,)和(64,)不兼容。线。我还收到消息:
Call arguments received by layer "pick_median_layer" (type PickMedianLayer):
• X=tf.Tensor(shape=(32,), dtype=float32)
创建输入向量VEC后,它具有形状张量图([64])。因此,似乎输入向量未正确馈入图层。通过调试,我能够验证该层内的其他张量具有预期的形状和类型。也可以按预期创建面具。
我在做什么错?有人可以帮我吗?谢谢你!
I am trying to create a custom keras layer. This layer will be added to a trained model before deployment in order to have a model that contains all pre-processing steps. In training the preprocessing will be done outside of the model for multiple reasons. So this layer will never be used in training.
The input for the layer is a 1D tensor of floats with 64 components. This vector contains redundant values based on a mapping. The mapping is a name list of 64 strings. Elements with the same name are redundant. The layer is supposed to pick the median of each set of redundant values based on a mapping provided at the initialisation of the layer.
def pick_median(X, name, mapping):
mask = (mapping == name)
median = tfp.stats.percentile(X[mask], 50.0, interpolation='midpoint')
return median
class PickMedianLayer(tf.keras.layers.Layer):
def __init__(self, mapping:List[str], **kwargs):
super(PickMedianLayer, self).__init__(**kwargs)
self.mapping= tf.constant(mapping, dtype='string')
self.map_value_set = tf.constant(list(set(mapping)), dtype='string')
self.trainable = False
def build(self, input_shape):
pass
def call(self, X):
picked_vec = tf.map_fn(fn=lambda name: pick_median(X, name, self.mapping), elems=self.map_value_set, fn_output_signature='float32')
return picked_vec
I use tf.map_fn to create a tensor component for each unique name in the mapping.
As a first simple test of the layer I created a keras model only containing the custom layer and tried to predict a simple vector:
rel_model = Sequential()
rel_model.add(ToFuncLayer(mapping=mapping))
rel_model.compile()
#rel_model.build(input_shape=tf.TensorShape([64]))
vec = 1000. * tf.ones((64,), dtype='float32')
print(vec.shape)
vec1 = rel_model.predict(vec)
print(vec1)
print(vec1.shape)
I get the error "ValueError: Shapes (32,) and (64,) are incompatible" when executing the predict line. I also get the message:
Call arguments received by layer "pick_median_layer" (type PickMedianLayer):
• X=tf.Tensor(shape=(32,), dtype=float32)
After creating the input vector vec, it has the shape TensorShape([64]). So it seems like the input vector is not fed into the layer correctly. By debugging I was able to verify that the other tensors inside the layer have the expected shapes and types. Also the mask is created as expected.
What am I doing wrong? Can anybody help me? Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我能够解决这个问题。这是三个问题的组合:
预测函数要求输入是批次。因此,我必须创建一个带有一行和64列的2D数组。
您需要使用tf.boolean_mask在张量上施加口罩。
层变量应存储为tf.variable,而不是tf.tensor。
工作解决方案看起来像这样:
I was able to fix the problem. It was a combination of three problems:
The predict function requires the input to be a batch. So I had to create a 2d array with one row and 64 columns.
You need to use tf.boolean_mask to apply a mask on tensors.
Layer variables should be stored as a tf.Variable, not tf.Tensor.
The working solution looks like this: