Python 稠密张量张量流的稀疏张量(矩阵)

Python 稠密张量张量流的稀疏张量(矩阵),python,graph,tensorflow,sparse-matrix,autoencoder,Python,Graph,Tensorflow,Sparse Matrix,Autoencoder,我正在创建一个卷积稀疏自动编码器,我需要将一个充满值的4D矩阵(其形状为[样本,N,N,D])转换为稀疏矩阵 对于每个示例,我都有D个NxN功能映射。我想将每个NxN功能映射转换为稀疏矩阵,最大值映射为1,所有其他值映射为0 我不想在运行时执行此操作,而是在图形声明期间执行此操作(因为我需要使用生成的稀疏矩阵作为其他图形操作的输入),但我不知道如何获取索引以构建稀疏矩阵。您可以使用tf.where和tf.gather\n执行此操作: import numpy as np import tenso

我正在创建一个卷积稀疏自动编码器,我需要将一个充满值的4D矩阵(其形状为
[样本,N,N,D]
)转换为稀疏矩阵

对于每个示例,我都有D个NxN功能映射。我想将每个NxN功能映射转换为稀疏矩阵,最大值映射为1,所有其他值映射为0


我不想在运行时执行此操作,而是在图形声明期间执行此操作(因为我需要使用生成的稀疏矩阵作为其他图形操作的输入),但我不知道如何获取索引以构建稀疏矩阵。

您可以使用
tf.where
tf.gather\n
执行此操作:

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

将密集numpy阵列转换为tf.SparseTensor的简单代码:

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

注意TF 2.3中的(take)

中有一个内置函数用于此:

import tensorflow_probability as tfp

tfp.math.dense_to_sparse(x, ignore_value=None, name=None)
Tensorflow自1.15以来一直在增长。例如:

In [1]: import tensorflow as tf

In [2]: x = tf.eye(3) * 5

In [3]: x
Out[3]: 
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[5., 0., 0.],
       [0., 5., 0.],
       [0., 0., 5.]], dtype=float32)>
通过应用以下内容验证身份:

[7]中的
:tf.sparse.to_densed(y)=x
出[7]:

您想用Tensorflow还是python进行此转换?如果在python中,此函数可以帮助您从稠密矩阵()转换为稀疏矩阵(),您可以使用tf.SparseTensor(使用coo格式)存储每个特征映射,并使用列表存储所有稀疏张量。特别是,nonzero()()可以为您提供非零元素的索引。不确定这是否被视为运行时方法。这可能是图形声明之前的一些数据预处理。4D密集矩阵是在运行时生成的还是仅仅是一些给定的输入数据?我不想在运行时这样做(我知道如何使用numpy),但在图形声明期间(使用Tensorflow也是如此),如何使用张量来实现这一点?就像我想把张量转换成稀疏张量一样。@RocketPingu不知道你的意思,这是把密集张量转换成稀疏张量
a_t
这里是一个正则张量流张量(在这种情况下,从
tf.常量
op中获得,但可以是任何其他op的输出)。为了清晰起见,我添加了一些注释。就在我尝试编写代码时,它给了我一个错误。这里有更多信息:@RocketPingu正如我在代码中的一条注释中所说的,如果在创建图形时不知道张量的完整形状(即其形状是动态的,而不是静态的),则应该使用
tf.shape(tensor)
而不是
tensor.get\u shape()
tensor.shape
。我再次运行代码。结果证明转换是成功的。现在的问题在于ctc_的损失。谢谢如果你对当前的impl感兴趣:这应该是公认的答案。
In [4]: y = tf.sparse.from_dense(x)

In [5]: y.values
Out[5]: <tf.Tensor: shape=(3,), dtype=float32, numpy=array([5., 5., 5.], dtype=float32)>

In [6]: y.indices
Out[6]: 
<tf.Tensor: shape=(3, 2), dtype=int64, numpy=
array([[0, 0],
       [1, 1],
       [2, 2]])>
In [7]: tf.sparse.to_dense(y) == x
Out[7]: 
<tf.Tensor: shape=(3, 3), dtype=bool, numpy=
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])>