2016-10-03 45 views
7

Bir konvolüsyonel seyrek otomatik kodlayıcı oluşturuyorum ve 4D matrisini (şekli [samples, N, N, D] olan) seyrek bir matrise dönüştürmem gerekiyor.Yoğun bir Tensorflow'dan Seyrek Matrix

Her örnek için, D NxN özellik haritalarına sahibim. Her NxN özellik haritasının, 1 ile eşleştirilebilen maksimum değeri ve diğerlerini 0'a dönüştürdüğü, çok az değeri olan bir matrise dönüştürmek istiyorum.

Çalışma zamanında bunu yapmak istemiyorum ama Grafik Bildirimi sırasında Ortaya çıkan seyrek matrisi diğer grafik işlemlerine bir girdi olarak kullanmak için), ancak seyrek matrisi oluşturmak için endeksleri nasıl alacağımı anlamıyorum.

+0

Eğer Tensorflow içi veya bu dönüşümü yapmak ister misin piton? Python'da ise, bu işlev yoğundan kaba matrise dönüşüm yapmanıza yardımcı olabilir (http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.coo_matrix.html#scipy.sparse.coo_matrix). Her özellik haritasını saklamak için tf.SparseTensor'u (coo formatını kullanır) kullanın ve tüm seyrek tensörleri saklamak için bir liste kullanın. –

+0

Özellikle, nonzero() (http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.coo_matrix.nonzero.html#scipy.sparse.coo_matrix.nonzero) size sıfır olmayanlar için bilgi verebilir elementler. Bunun çalışma zamanı yaklaşımı olarak kabul edilip edilmediğinden emin değil. Bu, grafik beyanından önce bazı veri ön işleme olabilir. Çalışma zamanında oluşturulan 4D yoğun matris mi yoksa sadece bazı verilen giriş verileri mi? –

+0

Bunu çalışma zamanında (numpy ile nasıl yapılacağını biliyorum) yapmak istemiyorum, ancak grafik bildirimi sırasında (Tensorflow ile) – Cramer

cevap

9
Sen tf.where kullanabilirsiniz

ve tf.gather_nd bunu:

import numpy as np 
import tensorflow as tf 

# Make a tensor from a constant 
a = np.reshape(np.arange(24), (3, 4, 2)) 
a_t = tf.constant(a) 
# Find indices where the tensor is not zero 
idx = tf.where(tf.not_equal(a_t, 0)) 
# Make the sparse tensor 
# Use tf.shape(a_t, out_type=tf.int64) instead of a_t.get_shape() 
# if tensor shape is dynamic 
sparse = tf.SparseTensor(idx, tf.gather_nd(a_t, idx), a_t.get_shape()) 
# Make a dense tensor back from the sparse one, only to check result is correct 
dense = tf.sparse_tensor_to_dense(sparse) 
# Check result 
with tf.Session() as sess: 
    b = sess.run(dense) 
np.all(a == b) 
>>> True 
+0

Bunu tensörlerle nasıl yapabilirim? Gibi bir tensörü seyrek birine dönüştürmek istiyorum. –

+1

@RocketPingu Ne demek istediğinizden emin değilsiniz, bu yoğun tensörü seyrek birine dönüştürmektir. Burada a_t düzenli bir TensorFlow tensörüdür (bu durumda "tf.constant' op den elde edilir, ancak diğer herhangi bir op). Açıklık için bazı yorumlar ekledim. – jdehesa

+0

Sadece kodum için denediğimde, bana bir hata verdi. Burada daha fazlası: https://stackoverflow.com/questions/48201725/converting-tensor-to-a-sparsetensor –

1

Basit kod tf.SparseTensor için yoğun numpy dizisi dönüştürmek için:

def denseNDArrayToSparseTensor(arr): 
    idx = np.where(arr != 0.0) 
    return tf.SparseTensor(np.vstack(idx).T, arr[idx], arr.shape)