Tensorflow 密集张量到稀疏二值化哈希技巧张量
Tensorflow dense tensor to sparse binarized hash trick tensor
我想以这样的方式转换此数据集,即每个张量都具有给定的大小 n
并且当且仅当此新张量的索引 i
处的特征设置为 1原始特征中有一个 i
(modulo n).
我希望下面的例子能让事情更清楚
假设我有一个像这样的数据集:
t = tf.constant([
[0, 3, 4],
[12, 2 ,4]])
ds = tf.data.Dataset.from_tensors(t)
我想得到 (if n
= 9)
的稀疏等价物
t = tf.constant([
[1, 0, 0, 1, 1, 0, 0, 0, 0], # index set to 1 are 0, 3 and 4
[0, 0, 1, 1, 1, 0, 0, 0, 0]]) # index set to 1 are 2, 4, and 12%9 = 3
我已经知道如何获得非稀疏表示 (),因为我最终会得到 n > 100 万,所以我不想通过密集张量来获得稀疏张量
谢谢
这是一个可能的实现:
import tensorflow as tf
def binarization_sparse(t, n):
# Input size
t_shape = tf.shape(t)
t_rows = t_shape[0]
t_cols = t_shape[1]
# Make sparse row indices for each value
row_idx = tf.tile(tf.range(t_rows)[: ,tf.newaxis], [1, t_cols])
# Sparse column indices
col_idx = t % n
# "Flat" indices - needed to discard repetitions
total_idx = row_idx * n + col_idx
# Remove repeated elements
out_idx, _ = tf.unique(tf.reshape(total_idx, [-1]))
# Back to row and column indices
sparse_idx = tf.stack([out_idx // n, out_idx % n], axis=-1)
# Sparse values
sparse_values = tf.ones([tf.shape(sparse_idx)[0]], dtype=t.dtype)
# Make sparse tensor
out = tf.sparse.SparseTensor(tf.cast(sparse_idx, tf.int64),
sparse_values,
[t_rows, n])
# Reorder indices
out = tf.sparse.reorder(out)
return out
# Test
with tf.Graph().as_default(), tf.Session() as sess:
t = tf.constant([
[ 0, 3, 4],
[12, 2, 4]
])
# Sparse result
t_m1h_sp = binarization_sparse(t, 9)
# Convert to dense to check output
t_m1h = tf.sparse.to_dense(t_m1h_sp)
print(sess.run(t_m1h))
输出:
[[1 0 0 1 1 0 0 0 0]
[0 0 1 1 1 0 0 0 0]]
我添加了删除重复元素的逻辑,因为原则上它可能会发生,但如果你能保证没有重复(包括取模),你可以跳过这一步。另外,我在最后重新排序了稀疏张量。这在这里不是绝对必要的,但是(我认为)稀疏操作有时期望索引被排序(并且 sparse_idx
可能不会被排序)。
此外,此解决方案特定于 2D 输入。对于一维输入会更简单,如果需要,也可以为高维输入编写。我认为完全通用的解决方案是可能的,但它会更复杂(特别是如果你想考虑维数未知的张量)。
我想以这样的方式转换此数据集,即每个张量都具有给定的大小 n
并且当且仅当此新张量的索引 i
处的特征设置为 1原始特征中有一个 i
(modulo n).
我希望下面的例子能让事情更清楚
假设我有一个像这样的数据集:
t = tf.constant([
[0, 3, 4],
[12, 2 ,4]])
ds = tf.data.Dataset.from_tensors(t)
我想得到 (if n
= 9)
t = tf.constant([
[1, 0, 0, 1, 1, 0, 0, 0, 0], # index set to 1 are 0, 3 and 4
[0, 0, 1, 1, 1, 0, 0, 0, 0]]) # index set to 1 are 2, 4, and 12%9 = 3
我已经知道如何获得非稀疏表示 (
谢谢
这是一个可能的实现:
import tensorflow as tf
def binarization_sparse(t, n):
# Input size
t_shape = tf.shape(t)
t_rows = t_shape[0]
t_cols = t_shape[1]
# Make sparse row indices for each value
row_idx = tf.tile(tf.range(t_rows)[: ,tf.newaxis], [1, t_cols])
# Sparse column indices
col_idx = t % n
# "Flat" indices - needed to discard repetitions
total_idx = row_idx * n + col_idx
# Remove repeated elements
out_idx, _ = tf.unique(tf.reshape(total_idx, [-1]))
# Back to row and column indices
sparse_idx = tf.stack([out_idx // n, out_idx % n], axis=-1)
# Sparse values
sparse_values = tf.ones([tf.shape(sparse_idx)[0]], dtype=t.dtype)
# Make sparse tensor
out = tf.sparse.SparseTensor(tf.cast(sparse_idx, tf.int64),
sparse_values,
[t_rows, n])
# Reorder indices
out = tf.sparse.reorder(out)
return out
# Test
with tf.Graph().as_default(), tf.Session() as sess:
t = tf.constant([
[ 0, 3, 4],
[12, 2, 4]
])
# Sparse result
t_m1h_sp = binarization_sparse(t, 9)
# Convert to dense to check output
t_m1h = tf.sparse.to_dense(t_m1h_sp)
print(sess.run(t_m1h))
输出:
[[1 0 0 1 1 0 0 0 0]
[0 0 1 1 1 0 0 0 0]]
我添加了删除重复元素的逻辑,因为原则上它可能会发生,但如果你能保证没有重复(包括取模),你可以跳过这一步。另外,我在最后重新排序了稀疏张量。这在这里不是绝对必要的,但是(我认为)稀疏操作有时期望索引被排序(并且 sparse_idx
可能不会被排序)。
此外,此解决方案特定于 2D 输入。对于一维输入会更简单,如果需要,也可以为高维输入编写。我认为完全通用的解决方案是可能的,但它会更复杂(特别是如果你想考虑维数未知的张量)。