我有一個具有以下架構的 TF 資料集:
tf_features = {
'searched_destination_ufi': tf.io.FixedLenFeature([], tf.int64, default_value=0),
'booked_hotel_ufi': tf.io.FixedLenFeature([], dtype=tf.int64, default_value=0),
'user_id': tf.io.FixedLenFeature([], dtype=tf.int64, default_value=0),;
}
我也有一個像這樣的字典:
candidates = {'111': [123, 444, ...], '222': [555, 888, ...]...}
我想通過以下方式執行地圖操作:
ds.map(lambda x, y: {**x, 'candidates': candidates[x['searched_destination_ufi'].numpy()]})
但是我總是得到:AttributeError: 'Tensor' object has no attribute 'numpy'
當我洗掉.numpy()我得到TypeError: Tensor is unhashable. Instead, use tensor.ref() as the key.
你有什么解決辦法嗎?
uj5u.com熱心網友回復:
該函式dataset.map在圖形模式下作業,.numpy()無法呼叫張量。您可以嘗試使用tf.py_function將候選人包含dict到您的資料集中:
import tensorflow as tf
tf_features = {
'searched_destination_ufi': ['111', '222'],
'booked_hotel_ufi': [2, 4],
'user_id': [3, 2]
}
ds = tf.data.Dataset.from_tensor_slices(tf_features)
candidates = {'111': [123, 444], '222': [555, 888]}
def py_func(x):
x = x.numpy().decode('utf-8')
return candidates[x]
ds = ds.map(lambda x: {**x, 'candidates': tf.py_function(py_func, [x['searched_destination_ufi']], [tf.int32]*2)})
for x in ds:
print(x)
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'111'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=3>, 'candidates': <tf.Tensor: shape=(2,), dtype=int32, numpy=array([123, 444], dtype=int32)>}
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'222'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=4>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'candidates': <tf.Tensor: shape=(2,), dtype=int32, numpy=array([555, 888], dtype=int32)>}
請注意,這[tf.int32]*2對應于 中串列的長度candidates。
對于更復雜的方法,您可以使用tf.lookup.StaticHashTableand tf.gather,它們都可以在圖形模式下作業:
import tensorflow as tf
tf_features = {
'searched_destination_ufi': ['111', '222'],
'booked_hotel_ufi': [2, 4],
'user_id': [3, 2]
}
ds = tf.data.Dataset.from_tensor_slices(tf_features)
candidates = {'111': [123, 444], '222': [555, 888]}
keys = list(candidates.keys())
values = tf.constant(list(candidates.values()))
table = tf.lookup.StaticHashTable(
tf.lookup.KeyValueTensorInitializer(tf.constant(keys), tf.range(len(keys))),
default_value=-1)
ds = ds.map(lambda x: {**x, 'candidates': tf.gather(values, [table.lookup(x['searched_destination_ufi'])])})
for x in ds:
print(x)
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'111'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=3>, 'candidates': <tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[123, 444]], dtype=int32)>}
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'222'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=4>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'candidates': <tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[555, 888]], dtype=int32)>}
如果候選欄位的長度可變,則使用不規則張量和第二種方法,其余代碼保持不變:
candidates = {'111': [123, 444], '222': [555, 888, 323]}
keys = list(candidates.keys())
values = tf.ragged.constant(list(candidates.values()))
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'111'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=3>, 'candidates': <tf.RaggedTensor [[123, 444]]>}
{'searched_destination_ufi': <tf.Tensor: shape=(), dtype=string, numpy=b'222'>, 'booked_hotel_ufi': <tf.Tensor: shape=(), dtype=int32, numpy=4>, 'user_id': <tf.Tensor: shape=(), dtype=int32, numpy=2>, 'candidates': <tf.RaggedTensor [[555, 888, 323]]>}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464825.html
