简体   繁体   English

将标量输入 Tensorflow 2 model 的正确方法

[英]Proper way to input a scalar into a Tensorflow 2 model

In my Tensorflow 2 model, I want my batch size to be parametric, such that I can build tensors which have appropriate batch size dynamically.在我的 Tensorflow 2 model 中,我希望我的批量大小是参数化的,这样我就可以动态构建具有适当批量大小的张量。 I have the following code:我有以下代码:

batch_size_param = 128

tf_batch_size = tf.keras.Input(shape=(), name="tf_batch_size", dtype=tf.int32)
batch_indices = tf.range(0, tf_batch_size, 1)

md = tf.keras.Model(inputs={"tf_batch_size": tf_batch_size}, outputs=[batch_indices])
res = md(inputs={"tf_batch_size": batch_size_param})

The code throws an error in tf.range :代码在tf.range中引发错误:

ValueError: Shape must be rank 0 but is rank 1
 for 'limit' for '{{node Range}} = Range[Tidx=DT_INT32](Range/start, tf_batch_size, Range/delta)' with input shapes: [], [?], []

I think the problem is with the fact that tf.keras.Input automatically tries to expand the input array at the first dimension, since it expects the partial shape of the input without the batch size and will attach the batch size according to the shape of the input array, which in my case a scalar.我认为问题在于tf.keras.Input自动尝试在第一维扩展输入数组,因为它期望输入的部分形状没有批量大小,并将根据形状附加批量大小输入数组,在我的例子中是一个标量。 I can just feed the scalar value as a constant integer into tf.range but this time, I won't be able to change it after the model graph has been compiled.我可以将标量值作为常数 integer 输入到tf.range ,但是这一次,在 model 图表编译后我将无法更改它。

Interestingly, I failed to find a proper way to input only a scalar into a TF-2 model even though I checked the documentation, too.有趣的是,即使我也检查了文档,我也没有找到一种仅将标量输入到 TF-2 model 的正确方法。 So, what would be the best way to handle such a case?那么,处理这种情况的最佳方法是什么?

Don't use tf.keras.Input and just define the model by subclassing.不要使用tf.keras.Input并通过子类化定义 model 。

import tensorflow as tf


class ScalarModel(tf.keras.Model):
    def __init__(self):
        super().__init__()

    def call(self, x):
        return tf.range(0, x, 1)


print(ScalarModel()(10))
# tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)

I'm not sure if this is actually a good idea, but you could use tf.squeeze like我不确定这是否真的是一个好主意,但你可以使用 tf.squeeze

inp = keras.Input(shape=(), dtype=tf.int32)
batch_indices = tf.range(tf.squeeze(inp))
model = keras.Model(inputs=inp, outputs=batch_indices)

so that以便

model(6)

gives

<tf.Tensor: shape=(6,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5])>

Edit: Depending on what you want to achieve, it might also be worth looking into ragged tensors:编辑:根据您想要实现的目标,可能还值得研究参差不齐的张量:

inp = keras.Input(shape=(), dtype=tf.int32)
batch_indices = tf.ragged.range(inp)
model = keras.Model(inputs=inp, outputs=batch_indices)

would make将使

model(np.array([6,7]))

return返回

<tf.RaggedTensor [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6]]>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM