Я пытался выполнить tf.vectorized_map на тензоре формы [размер партии, размер списка] и применить оператор tf.math.top_k поверх каждая строка в пакете и не удалась.
Например, данные могут быть:
[ [1,2,4,5,6], [9,5,4,2,1] ]
, и я хотел бы применить topk к [1,2,4,5,6]
и [9,5,4,2,1]
.
Однако мне удалось сделать то же самое с tf.map_fn
, но vectorized_map
должен работать быстрее. Я использую tensorflow 1.15 .
import tensorflow as tf
import numpy as np
# create fake data
x = tf.convert_to_tensor([
[1,2,4,5,6],
[9,5,4,2,1],
], dtype=tf.float32)
x = tf.reshape(x, (2, -1))
B = x.shape[0] # batchsize
L = x.shape[1] # list size
print(f"B {B}, L {L}")
sess = tf.Session()
print(f"x tensor: {sess.run(x)}\n")
def fv(_x):
#_tensor = tf.reshape(_x, (L,)) # doesnt work (1)
_tensor = tf.reshape(tf.convert_to_tensor([9,5,4,2,1], dtype=tf.float32), (L,)) # work (2)
#_tensor = tf.convert_to_tensor([9,5,4,2,1], dtype=tf.float32) # work (3)
print(f"_tensor: {_tensor}")
values, indices = tf.math.top_k(_tensor, k=3)
# i just need the indices
return indices
indices = tf.vectorized_map(
fv,
x,
)
print("\nindices ")
print(sess.run(indices))
Как мы видим, (2) и (3) выполняются, поэтому оператор topk должен быть пригоден для использования. Также, даже если (1) не работает, я могу использовать _x и, например, просто вернуть его как:
def fv(_x):
return _x * 10
Итак, _x можно использовать.
Итак, когда я запускаю код с (1) у меня есть ошибка:
ValueError: No converter defined for TopKV2
name: "loop_body/TopKV2"
op: "TopKV2"
input: "loop_body/Reshape"
input: "loop_body/TopKV2/k"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "sorted"
value {
b: true
}
}
inputs: [WrappedTensor(t=<tf.Tensor 'loop_body/Reshape/pfor/Reshape:0' shape=(2, 5) dtype=float32>, is_stacked=True, is_sparse_stacked=False), WrappedTensor(t=<tf.Tensor 'loop_body/TopKV2/k:0' shape=() dtype=int32>, is_stacked=False, is_sparse_stacked=False)].
Either add a converter or set --op_conversion_fallback_to_while_loop=True, which may run slower
Process finished with exit code 1
Здесь я просто пытаюсь получить индексы, после того, как мне нужно будет обработать вектор, чтобы на выходе было как [[0,0,1,1,1], [1,1,1,0,0] ]
для K=3
(1, если значения находятся в топе, иначе 0). А также чтобы задать другой тензор формы [размер пакета, 1], содержащий параметр K для каждой строки. (Мне уже удалось сделать это с помощью map_fn, поэтому я не думаю, что это будет проблемой позже).
Возможно, можно реализовать мой собственный оператор topk в векторизованной карте, но я бы предпочел не