在神经网络中实现稀疏连接(Theano)

Posted

技术标签:

【中文标题】在神经网络中实现稀疏连接(Theano)【英文标题】:Implementing sparse connections in neural network (Theano) 【发布时间】:2016-07-26 01:55:52 【问题描述】:

神经网络的一些用例要求并非所有神经元都连接在两个连续的层之间。对于我的神经网络架构,我需要有一个层,其中每个神经元只与前一层中的一些预先指定的神经元有连接(在有些随意的地方,而不是像卷积层这样的模式)。为了在特定图表上对数据进行建模,这是必需的。我需要在 Theano 中实现这个“稀疏”层,但我不习惯 Theano 的编程方式。

似乎在 Theano 中编程稀疏连接的最有效方法是使用theano.tensor.nnet.blocksparse.SparseBlockGemv。另一种方法是进行矩阵乘法,其中许多权重设置为 0(= 无连接),但与 SparseBlockGemv 相比效率非常低,因为每个神经元仅连接到前一层中的 2-6 个神经元约 100000 个神经元。此外,100000x100000 的权重矩阵不适合我的 RAM/GPU。因此,有人可以提供一个示例,说明如何使用SparseBlockGemv 方法或其他计算效率高的方法实现稀疏连接?

一个完美的例子是在隐藏层之后(并且在 softmax 之前)用一个额外的层扩展 MLP Theano Tutorial,其中每个神经元只与前一层中的一部分神经元有连接。但是,也非常欢迎其他示例!

编辑:请注意,该层必须在 Theano 中实现,因为它只是较大架构的一小部分。

【问题讨论】:

我开始意识到 SparseBlockGemv 并不适用于一般的稀疏块矩阵(例如 BSR),而是适用于只有有限输入/输出组合的大型 W 矩阵上的点运算。跨度> 【参考方案1】:

全连接层的输出由输入的点积和该层的权重给出。在 theano 或 numpy 中你可以使用dot 方法。

y = x.dot(w)

如果您只与前一层中的某些神经元有连接,并且这些连接是预定义的,您可以执行以下操作:

y = [x[edges[i]].dot(w[i])) for i in neurons]

其中edges[i] 包含连接到神经元i 的神经元的索引,w[i] 包含此连接的权重。

请注意,theano 不知道层或其他高级细节。

【讨论】:

【参考方案2】:

很抱歉恢复旧线程,但这是我发现的最简单的指南,它有助于扩展 https://iamtrask.github.io/2015/07/12/basic-python-network/ 的指南以用于部分连接的输入。但是,我花了一段时间才理解 basaundi 的答案,我认为我可以改进它。

有几件事我需要更改才能使其正常工作。就我而言,我试图从 N 个输入映射到我的第一个隐藏层中的 M 个神经元。我的输入位于 NxF 数组中,其中 F 是我的输入的特征数,输入和第一层之间的突触值(权重)位于 FxM 数组中。因此,Inputs Weights 的输出是一个 NxM 数组。我的边缘矩阵是一个 MxF 数组,它为第 1 层(行)中的每个神经元指定输入数据的哪些特征是相关的(列)。

至少在这个设置中,它要求我以不同于上面指定的方式对数组进行切片。此外,列表推导返回一个矩阵列表,必须将其相加才能得到正确的 NxM(否则你会得到一个 MxNxM 数组)。

所以我使用了以下(util.sigmoid 是我自己的辅助函数):

y = [numpy.dot(x[:, edges[i]], w[edges[i]]) 
     for i in range(M)]
y = util.sigmoid(numpy.sum(y, 0))

这似乎对我有用。

【讨论】:

“我花了一段时间才弄明白这个答案 [...]” 请在你的“答案”中包含答案,因为博客文章可能会在这篇文章之前消失很久。我们不需要整篇博文,只需要完整回答问题即可。 还有,欢迎来到Stack Overflow! 你误解了我的评论。 “回答”是指我正在回复的消息。如果我的实现与原始海报的实现之间存在歧义,则仅为上下文提供该链接。

以上是关于在神经网络中实现稀疏连接(Theano)的主要内容,如果未能解决你的问题,请参考以下文章

在 Theano 中使用屏幕会话 - 竞争条件

Theano 梯度扫描操作失败

机器学习之旅分享4 | 稀疏连接的张量神经网络

如何在 JGit 中实现稀疏结帐?

稀疏自编码器及事实上现——怎样搞基

在CentOS7中实现Cobbler自动装机