<h2>解决方案</h2>
<p>这里的解决方案需要明确以下几个概念。我将解释这些概念
在下面的章节中</p>
<ul>
<li>{<cd1>}期望输入什么</li>
<li>可以对<code>keras</code>模型进行何种修改以允许稀疏输入矩阵</li>
<li>将2D<code>numpy</code>数组转换为3D<code>numpy</code>数组</li>
<li>使用在稀疏和非稀疏(或密集)数组之间来回转换
<ul>
<li><code>scipy.sparse.coo_matrix</code>用于2D<code>numpy</code>数组</li>
<li><code>sparse.COO</code>用于3D<code>numpy</code>数组</li>
</ul>
</li>
</ul>
<h2>使用稀疏矩阵作为<code>tf.keras</code>模型的输入</h2>
<ul>
<li><p>一个选项是使用以下命令将稀疏输入矩阵转换为非稀疏(密集)格式:
<code>todense()</code>方法。这使得矩阵成为一个规则的<code>numpy</code>数组。参见kaggle的讨论,
<a href="https://www.kaggle.com/c/talkingdata-mobile-user-demographics/discussion/22567" rel="nofollow noreferrer">[3]</a>和<a href="https://www.kaggle.com/c/walmart-recruiting-trip-type-classification/discussion/18154" rel="nofollow noreferrer">[4]</a></p>
</li>
<li><p>另一种选择是通过以下方式为稀疏和密集输入编写自己的自定义层:
子类化<code>tf.keras.layers.Layer</code>类。见这篇文章<a href="https://medium.com/dailymotion/how-to-design-deep-learning-models-with-sparse-inputs-in-tensorflow-keras-fd5e754abec1" rel="nofollow noreferrer">[2]</a></p>
</li>
<li><p>看起来<code>tensorflow.keras</code>现在允许使用稀疏权重进行模型训练。所以
在某些地方,它有能力处理稀疏性。您可能需要浏览文档,
<a href="https://www.tensorflow.org/model_optimization/guide/pruning/train_sparse_models" rel="nofollow noreferrer">[1]</a>在这方面</p>
</li>
</ul>
<h2>向numpy阵列添加新轴</h2>
<p>您可以使用<code>np.newaxis</code>将另一个轴添加到numpy数组,如下所示</p>
<pre class="lang-py prettyprint-override"><code>import numpy as np
## Make a 2D array
a2D = np.zeros((10,10))
# Make a few elements non-zero in a2D
aa = a2D.flatten()
aa[[0,13,41,87,98]] = np.random.randint(1,10,size=5)
a2D = aa.reshape(a2D.shape)
# Make 3D array from 2D array by adding another axis
a3D = a2D[:,:,np.newaxis]
#print(a2D)
print('a2D.shape: {}\na3D.shape: {}'.format(a2D.shape, a3D.shape))
</code></pre>
<p><strong>输出</strong>:</p>
<pre><code>a2D.shape: (10, 10)
a3D.shape: (10, 10, 1)
</code></pre>
<p>话虽如此,请查看参考资料部分的链接</p>
<h2>稀疏阵列</h2>
<p>由于稀疏数组的非零值非常少,因此在转换时会使用常规numpy数组
在稀疏数组中,以几种稀疏格式存储:</p>
<ul>
<li><code>csr_matrix</code>:非零值和索引的行数组</li>
<li><code>csc-matrix</code>:非零值和索引的按列数组</li>
<li><code>coo-matrix</code>:一个有三列的表
<ul>
<li>划船</li>
<li>纵队</li>
<li>非零值</li>
</ul>
</li>
</ul>
<p><strong>Scipy稀疏矩阵需要2D输入矩阵</p>
<p>然而,上述三种稀疏矩阵的实现
将二维非稀疏矩阵视为输入</p>
<pre class="lang-py prettyprint-override"><code>from scipy.sparse import csr_matrix, coo_matrix
coo_a2D = coo_matrix(a2D)
coo_a2D.shape # output: (10, 10)
# scipy.sparse only accepts 2D input matrices
# the following line will throw an !!! ERROR !!!
coo_a3D = coo_matrix(coo_a2D.todense()[:,:,np.newaxis])
</code></pre>
<h3>来自3D非稀疏输入矩阵的稀疏矩阵</h3>
<p>是的,您可以使用<a href="https://github.com/pydata/sparse" rel="nofollow noreferrer">^{<cd19>}</a>库执行此操作。
它还支持<code>scipy.sparse</code>和<code>numpy</code>数组。将稀疏矩阵转换为
非稀疏(密集)格式(<em>这不是神经网络中的密集层</em>),使用
<code>todense()</code>方法</p>
<pre class="lang-py prettyprint-override"><code>## Installation
# pip install -U sparse
import sparse
## Create sparse coo_matrix from a
# 3D numpy array (dense format)
coo_a3D = sparse.COO(a3D)
## Test that
# coo_a3D == coo made from (coo_a2D + newaxis)
print(
(coo_a3D == sparse.COO(coo_a2D.todense()[:,:,np.newaxis])).all()
) # output: True
## Convert to dense (non-sparse) format
# use: coo_a3D.todense()
print((a3D == coo_a3D.todense()).all()) # output: True
</code></pre>
<p><a href="https://i.stack.imgur.com/VXYgK.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VXYgK.png" alt="scipy.sparse.coo_matrix vs. sparse.COO"/></a></p>
<p><a href="https://sparse.pydata.org/en/latest/" rel="nofollow noreferrer">Source</a></p>
<h3>PyTorch:<code>torch.sparse</code>🔥 ⭐</h3>
<p>PyTorch库还提供了使用Space张量的方法</p>
<ul>
<li><p>文档<code>torch.sparse</code>:<a href="https://pytorch.org/docs/stable/sparse.html#sparse-coo-docs" rel="nofollow noreferrer">https://pytorch.org/docs/stable/sparse.html#sparse-coo-docs</a></p>
<p><a href="https://pytorch.org/docs/stable/sparse.html#sparse-coo-docs" rel="nofollow noreferrer"><img src="https://i.imgur.com/e3GSn4O.png" alt="warning: torch.sparse"/></a></p>
</li>
</ul>
<h2>参考资料</h2>
<ol>
<li><p><a href="https://www.tensorflow.org/model_optimization/guide/pruning/train_sparse_models" rel="nofollow noreferrer">Train sparse TensorFlow models with Keras</a></p>
</li>
<li><p><a href="https://medium.com/dailymotion/how-to-design-deep-learning-models-with-sparse-inputs-in-tensorflow-keras-fd5e754abec1" rel="nofollow noreferrer">How to design deep learning models with sparse inputs in Tensorflow Keras</a></p>
</li>
<li><p><a href="https://www.kaggle.com/c/talkingdata-mobile-user-demographics/discussion/22567" rel="nofollow noreferrer">Neural network for sparse matrices</a></p>
</li>
<li><p><a href="https://www.kaggle.com/c/walmart-recruiting-trip-type-classification/discussion/18154" rel="nofollow noreferrer">Training Neural network with scipy sparse matrix?</a></p>
</li>
<li><p><a href="https://sparse.pydata.org/en/latest/" rel="nofollow noreferrer">Documentation of ^{<cd19>} library</a></p>
</li>
</ol>