реализовать N-горячее кодирование в tf.slim - PullRequest
0 голосов
/ 30 мая 2018

Как реализовать N-горячее кодирование по индексу 1 в tf.int64?Ввод тензор, содержащий несколько tf.int64.N-hot-кодирование предназначено для замены одно-hot-кодирования в tf.slim.

Кодирование one_hot реализовано следующим образом:

def dense_to_one_hot(labels_dense, num_classes):
  """Convert class labels from scalars to one-hot vectors."""
  num_labels = labels_dense.shape[0]
  index_offset = numpy.arange(num_labels) * num_classes
  labels_one_hot = numpy.zeros((num_labels, num_classes))
  labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
  return labels_one_hot

N-not-кодирование означает: 19 =00010011, результат после кодирования составляет [0,0,0,1,0,0,1,1].

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Это одно из решений:

import numpy as np
import tensorflow as tf

def n_hot_encoding(a, n):
    a = tf.convert_to_tensor(a)
    m = 1 << np.arange(n)[::-1]
    shape = np.r_[np.ones(len(a.shape), dtype=int), -1]
    m = m.reshape(shape)
    hits = tf.bitwise.bitwise_and(a[..., tf.newaxis], tf.cast(m, a.dtype))
    return tf.not_equal(hits, 0)


with tf.Graph().as_default(), tf.Session() as sess:
    n_hot = n_hot_encoding([19, 20, 21], 10)
    print(sess.run(tf.cast(n_hot, tf.int32)))

Вывод:

[[0 0 0 0 0 1 0 0 1 1]
 [0 0 0 0 0 1 0 1 0 0]
 [0 0 0 0 0 1 0 1 0 1]]

Предполагается, что N является регулярным скаляром (не значением TensorFlow) и что числоРазмеры массива для преобразования известны (размер каждого измерения может быть динамическим, но a.shape не должен быть просто None).Функция может быть адаптирована для вычислений только TensorFlow следующим образом:

import tensorflow as tf

def n_hot_encoding(a, n):
    a = tf.convert_to_tensor(a)
    n = tf.convert_to_tensor(n)
    m = tf.bitwise.left_shift(1, tf.range(n)[::-1])
    shape = tf.concat([tf.ones([tf.rank(a)], dtype=tf.int64), [-1]], axis=0)
    m = tf.reshape(m, shape)
    hits = tf.bitwise.bitwise_and(a[..., tf.newaxis], tf.cast(m, a.dtype))
    return tf.not_equal(hits, 0)

Это должно работать с любым входом, но может выполнять немного больше дополнительной работы при каждом запуске графика.

0 голосов
/ 30 мая 2018

Найдите ниже альтернативу @jdehesa отличный ответ.Эта версия вычисляет длину в битах N сама по себе (но работает только с однозначными тензорами - или тензорами, содержащими значения одинаковой длины в битах):

import tensorflow as tf

def logn(x, n):
  numerator = tf.log(x)
  denominator = tf.log(tf.cast(n, dtype=numerator.dtype))
  return numerator / denominator

def count_bits(x):
    return tf.cast((logn(tf.cast(x, dtype=tf.float32), 2)) + 1, dtype=x.dtype)

def n_hot_encode(x):
    """
    Unpack an integer into its variable-length bit representation
    :param x: Int tensor of shape ()
    :return:  Bool tensor of shape (N,) with N = bit length of x
    """
    N = count_bits(x)
    bins = tf.bitwise.left_shift(1, tf.range(N))[::-1]
    x_unpacked = tf.reshape(tf.bitwise.bitwise_and(x, bins), [-1])
    x_bits = tf.cast(x_unpacked, dtype=tf.bool)
    return x_bits

with tf.Session() as sess:
    result = sess.run(n_hot_encode(tf.constant(19)))
    print(result)
    # > [ True False False  True  True]
    result = sess.run(n_hot_encode(tf.constant(255)))
    print(result)
    # > [ True  True  True  True  True  True  True  True]

Предыдущий ответ:

Использование tf.one_hot():

labels_one_hot = tf.one_hot(labels_dense, num_classes)
...