我有以下情况:
--enable_batching
的命令行选项。这会导致模型服务器自动批处理请求以最大化吞吐量。我想要启用它。(batch_size, 640, 480, 3)
。(number_of_faces, 4)
和(number_of_faces,)
。第一个输出将被称为 faces 。最后一个输出,我们可以称之为分区,是相应面的原始批次中的索引。例如,如果我传递了一批4个图像并获得7个面孔,那么我可能会将此张量设为[0, 0, 1, 2, 2, 2, 3]
。前两个面对应第一个图像,第三个面对应第二个图像,第三个图像有3个面等等。我的问题是:
--enable_batching
标志起作用,我的模型的输出需要使第0个维度与输入相同。也就是说,我需要一个具有以下形状的张量:(batch_size, ...)
。我想这是模型服务器可以知道哪个grpc连接将批量发送给每个输出。(number_of_faces, 4)
转换为此形状(batch_size, None, 4)
。也就是说,一批批次,其中每批可以有可变数量的面(例如,批次中的一个图像可能没有面,另一个可能有3个)。我尝试了什么:
tf.dynamic_partition
。从表面上看,这个功能看起来很完美。但是,在意识到num_partitions
参数不能是一个张量,只有一个整数后,我遇到了困难:
tensorflow_serving_output = tf.dynamic_partition(faces, partitions, batch_size)
如果tf.dynamic_partition
函数接受num_partition
的张量值,那么我的问题似乎就会得到解决。但是,我回到原点,因为事实并非如此。
谢谢大家的帮助!如果有什么不清楚,请告诉我
P.S。以下是预期过程的直观表示:
答案 0 :(得分:1)
我最终使用TensorArray
和tf.while_loop
找到了解决方案:
def batch_reconstructor(tensor, partitions, batch_size):
"""
Take a tensor of shape (batch_size, 4) and a 1-D partitions tensor as well as the scalar batch_size
And reconstruct a TensorArray that preserves the original batching
From the partitions, we can get the maximum amount of tensors within a batch. This will inform the padding we need to use.
Params:
- tensor: The tensor to convert to a batch
- partitions: A list of batch indices. The tensor at position i corresponds to batch # partitions[i]
"""
tfarr = tf.TensorArray(tf.int32, size=batch_size, infer_shape=False)
_, _, count = tf.unique_with_counts(partitions)
maximum_tensor_size = tf.cast(tf.reduce_max(count), tf.int32)
padding_tensor_index = tf.cast(tf.gather(tf.shape(tensor), 0), tf.int32)
padding_tensor = tf.expand_dims(tf.cast(tf.fill([4], -1), tf.float32), axis=0) # fill with [-1, -1, -1, -1]
tensor = tf.concat([tensor, padding_tensor], axis=0)
def cond(i, acc):
return tf.less(i, batch_size)
def body(i, acc):
partition_indices = tf.reshape(tf.cast(tf.where(tf.equal(partitions, i)), tf.int32), [-1])
partition_size = tf.gather(tf.shape(partition_indices), 0)
# concat the partition_indices with padding_size * padding_tensor_index
padding_size = tf.subtract(maximum_tensor_size, partition_size)
padding_indices = tf.reshape(tf.fill([padding_size], padding_tensor_index), [-1])
partition_indices = tf.concat([partition_indices, padding_indices], axis=0)
return (tf.add(i, 1), acc.write(i, tf.gather(tensor, partition_indices)))
_, reconstructed = tf.while_loop(
cond,
body,
(tf.constant(0), tfarr),
name='batch_reconstructor'
)
reconstructed = reconstructed.stack()
return reconstructed