2017-04-05 2 views
0

제목으로, 나는 tensorflow의 행렬에서 행당 가장 높은 n 개의 원소를 추출하고 그 결과를 희소한 Tensor에 저장하려고합니다.tf.nn.top_n의 출력을 희소 행렬로 변환

tf.nn.top_n을 사용하여 인덱스와 값을 추출 할 수 있었지만 인덱스가 tf.SparseTensor에서 요구하는 규칙을 따르지 않았습니다.

특히, tf.nn.top_n은 결과 값 행렬 (행 xn)과 동일한 모양을 갖는 열 인덱스 행렬을 반환하는 반면 tf.SparseTensor는 행 당 1 행을 갖는 (# 0이 아닌 x2) 행렬을 원합니다. 0이 아닌 요소와 행 및 열 인덱스를 보유하는 열을 반환합니다.

값은 값의 매트릭스가 아닌 0이 아닌 요소의 목록이 필요한 유사한 문제 일 수 있습니다.

어떻게 이러한 인덱싱 표기법간에 신속하게 변환 할 수 있습니까?

답변

2

이것은 모듈러 산술 연산을 통해 수행 할 수 있습니다. 다음은 행렬에서 작동하는 예제입니다. 더 많은 축으로 반복 할 수도 있습니다.

import tensorflow as tf 

def slices_to_dims(slice_indices): 
    """ 
    Args: 
    slice_indices: An [N, k] Tensor mapping to column indices. 
    Returns: 
    An index Tensor with shape [N * k, 2], corresponding to indices suitable for 
    passing to SparseTensor. 
    """ 
    slice_indices = tf.cast(slice_indices, tf.int64) 
    num_rows = tf.shape(slice_indices, out_type=tf.int64)[0] 
    row_range = tf.range(num_rows) 
    item_numbers = slice_indices * num_rows + tf.expand_dims(row_range, axis=1) 
    item_numbers_flat = tf.reshape(item_numbers, [-1]) 
    return tf.stack([item_numbers_flat % num_rows, 
        item_numbers_flat // num_rows], axis=1) 

사용 예제 :

dense_shape = [5, 7] 
dense_matrix = tf.random_normal(shape=dense_shape) 
top_values, top_indices = tf.nn.top_k(dense_matrix, k=2) 
sparse_indices = slices_to_dims(top_indices) 
sparse_tensor = tf.sparse_reorder(tf.SparseTensor(
    indices=sparse_indices, 
    values=tf.reshape(top_values, [-1]), 
    dense_shape=dense_shape)) 
densified_top = tf.sparse_tensor_to_dense(sparse_tensor) 
with tf.Session() as session: 
    sparse_top, dense_original, dense_selected = session.run(
     [sparse_tensor, dense_matrix, densified_top]) 
    print(dense_original) 
    print(dense_selected) 
    print(sparse_top) 

인쇄 : 마법처럼

[[ 1.44056129 -1.01790774 -0.2795608 2.34854746 -2.27528405 -0.62035948 
    3.36598897] 
[ 0.7114948 -0.42564821 -0.93446779 -0.25373486 -0.51730365 0.72331643 
    -0.75625718] 
[-0.6501748 -0.92748415 -0.95409006 -0.07157528 0.80637723 -0.32177576 
    -1.4516511 ] 
[-1.081038 -0.67226124 -1.19455576 0.44537872 -0.69019234 -0.61539739 
    0.15328468] 
[ 0.43032476 -0.11295394 0.83491379 -0.67906654 0.20325914 -0.0155068 
    0.52107805]] 
[[ 0.   0.   0.   2.34854746 0.   0. 
    3.36598897] 
[ 0.7114948 0.   0.   0.   0.   0.72331643 
    0.  ] 
[ 0.   0.   0.   -0.07157528 0.80637723 0.   0.  ] 
[ 0.   0.   0.   0.44537872 0.   0. 
    0.15328468] 
[ 0.   0.   0.83491379 0.   0.   0. 
    0.52107805]] 
SparseTensorValue(indices=array([[0, 3], 
     [0, 6], 
     [1, 0], 
     [1, 5], 
     [2, 3], 
     [2, 4], 
     [3, 3], 
     [3, 6], 
     [4, 2], 
     [4, 6]]), values=array([ 2.34854746, 3.36598897, 0.7114948 , 0.72331643, -0.07157528, 
     0.80637723, 0.44537872, 0.15328468, 0.83491379, 0.52107805], dtype=float32), dense_shape=array([5, 7])) 
+0

작품! 이런 방법으로 너무 많은 오버 헤드가 발생할 것이라는 걱정이 들더군요. 감사! – zergylord