Как создать однократный тензор для k крупнейших элементов в 4d тензоре?

#python #tensorflow #deep-learning

#python #тензорный поток #глубокое обучение

Вопрос:

Учитывая тензор формы, скажем (2,3,3,1), где размер пакета равен 2, а каждая матрица имеет форму (3,3,1). Как вы можете найти k крупнейших элементов из каждой матрицы и создать однократную матрицу, чтобы записи в этих k местоположениях были равны 1 и 0 в другом месте. Пример: (Обратите внимание, что каждая запись будет числом с плавающей запятой, для простоты используются целые числа)

 input_tensor=[[[1, 5, 7],
      [2, 8, 1],
      [3, 9, 1],
     ],
     [[0, 9, 5],
      [6, 0, 4],
      [3, 0, 8]
     ]
    ]
  

Однократный тензор для k = 3:

 output_tensor=[[[0, 0, 1],
      [0, 1, 0],
      [0, 1, 0],
     ],
     [[0, 1, 0],
      [1, 0, 0],
      [0, 0, 1]
     ]
    ]
  

tf.nn.top_k вернет k наибольших элементов только из последнего измерения. Как получить k наибольших элементов из 3d тензора, например: (3,3,1).
Также tf.one_hot поместит единицу в каждую строку для указанной глубины и заданных индексов, чего здесь нет.

Комментарии:

1. размер input_tensor , который вы показали в примере, имеет размер (2X3X3) можете ли вы исправить свой пример или описание вашей проблемы, что когда-либо было правильным.

Ответ №1:

Если вы хотите найти самые k большие элементы из каждой матрицы, вы можете использовать следующий метод.

 import tensorflow as tf

input_tensor = tf.constant([[[1, 5, 7],[2, 8, 1],[3, 9, 1]],
                            [[0, 9, 5],[6, 0, 4],[3, 0, 8]]],dtype=tf.int32)

k_tf = tf.placeholder(shape=(),dtype=tf.int32)

temp = tf.reshape(input_tensor,shape=(input_tensor.shape[0],-1))
# [[1 5 7 2 8 1 3 9 1]
#  [0 9 5 6 0 4 3 0 8]]
result = tf.reduce_sum(tf.one_hot(indices=tf.nn.top_k(temp,k=k_tf)[1], depth=temp.shape[1]), axis=1)
# [[0. 0. 1. 0. 1. 0. 0. 1. 0.]
#  [0. 1. 0. 1. 0. 0. 0. 0. 1.]]
result = tf.reshape(result,input_tensor.shape)

with tf.Session() as sess:
    print('k=2:')
    print(sess.run(result, feed_dict={k_tf: 2}))
    print('k=3:')
    print(sess.run(result,feed_dict={k_tf:3}))

k=2:
[[[0. 0. 0.]
  [0. 1. 0.]
  [0. 1. 0.]]

 [[0. 1. 0.]
  [0. 0. 0.]
  [0. 0. 1.]]]
k=3:
[[[0. 0. 1.]
  [0. 1. 0.]
  [0. 1. 0.]]

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

Ответ №2:

Учитывая ваш пример, который фактически имеет форму 2,3,3

 output = tf.one_hot(tf.math.argmax(inp, 2), 3)
  

Итак, сначала мы берем индекс наибольшей записи на желаемой оси, в данном случае 2. Затем примените одно горячее кодирование с желаемой глубиной, 3

Ответ №3:

 import numpy as np
import tensorflow as tf

inputs=np.array([[[1, 5, 7],
      [2, 8, 1],
      [3, 9, 1],
     ],
     [[0, 9, 5],
      [6, 0, 4],
      [3, 0, 8]
     ]
    ])

j = tf.placeholder(tf.int32)
input_tensor = tf.placeholder(tf.float64, shape=(2,3,3))    
_, inds = tf.nn.top_k(input_tensor, 3)    
r = tf.reshape(inds[:,:,3-j], [-1])
encoded_tensor = tf.reshape(tf.one_hot(r, 3),tf.shape(input_tensor))

with tf.Session() as sess:
    for k in [1,2,3]:
        print ("K:",k)
        print (sess.run(encoded_tensor , feed_dict={j: k, input_tensor: inputs}))  
  

Вывод:

 K: 1
[[[1. 0. 0.]
  [0. 0. 1.]
  [0. 0. 1.]]

 [[1. 0. 0.]
  [0. 1. 0.]
  [0. 1. 0.]]]
K: 2
[[[0. 1. 0.]
  [1. 0. 0.]
  [1. 0. 0.]]

 [[0. 0. 1.]
  [0. 0. 1.]
  [1. 0. 0.]]]
K: 3
[[[0. 0. 1.]
  [0. 1. 0.]
  [0. 1. 0.]]

 [[0. 1. 0.]
  [1. 0. 0.]
  [0. 0. 1.]]]
  
  • Используйте top_k , чтобы получить все индексы в порядке
  • Выберите необходимые индексы на основе значения k
  • Сгладьте и создайте однократное кодирование уровня 3 (поскольку столбцов в матрице равно 3)
  • Измените форму input_tensor .

Комментарии:

1. Я думаю, что OP предназначался для поиска верхних k элементов из элементов 2-мерной матрицы (3x3)