Тензор плотного тензора в разреженный бинаризованный тензор хеш-трюка - PullRequest
0 голосов
/ 23 ноября 2018

Я хочу преобразовать этот набор данных таким образом, чтобы каждый тензор имел заданный размер n, и чтобы особенность с индексом i этого нового тензора была установлена ​​в 1, если и только если существует iв оригинальной функции (по модулю n).

Я надеюсь, что следующий пример прояснит ситуацию

Предположим, у меня есть набор данных, подобный:

t = tf.constant([
  [0, 3, 4],
  [12, 2 ,4]])
ds = tf.data.Dataset.from_tensors(t)

Я хочуполучить разреженный эквивалент (если 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

Я уже знаю, как получить не разреженное представление ( Tensorflow: тензорная бинаризация ) и, как я в конечном итогепри n> 1 миллиона я не хочу проходить мимо плотного тензора, чтобы получить разреженный

спасибо

1 Ответ

0 голосов
/ 23 ноября 2018

Вот возможная реализация для этого:

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 входов.Для 1D входов будет проще, и при необходимости его можно записать и для многомерных входов.Я думаю, что вполне общее решение возможно, но оно будет более сложным (особенно если вы хотите рассмотреть тензоры с неизвестным числом измерений).

...