为什么神经网络模型不允许输入相乘?

数据挖掘 神经网络 深度学习
2021-09-30 00:40:28

在神经网络中,每个神经元值乘以连接的权重。然后,每个神经元的输入是所有这些值的总和,我们在其上应用激活函数(sigmoid、relu、tanh 等)。

为什么输入不能是所有这些值的向量,以便我可以决定是否需要将它们相乘,或者将向量空间中的另一个函数应用于实数,然后将激活函数应用于该实数?我见过的任何实现都不允许这样做,如果我想这样做,似乎我必须自己实现我的整个神经网络架构,而不能使用 Theano、Keras 或其他库。有什么原因让我无法理解为什么这不起作用?如果没有,是否有任何库我可以使用已经这样做而无需从头开始创建它?

4个回答

使用低级库,例如 Theano 或 TensorFlow,您很可能可以构建减少张量的新方案(可能通过一些可学习的权重向量等)。在 TensorFlow 中,您还可以获得自动梯度计算,因此您应该仍然能够定义成本函数并使用现有的优化器,而无需自己分析新设计或重新编写反向传播公式。

通用逼近定理本质上表明,为了拥有一个可以学习特定函数的网络,您只需要一个使用标准矩阵乘法加上非线性激活函数的隐藏层。因此,新架构的发明和使用需要一些理由。原因通常是这些添加提高了可以学习的速度或范围,它们从训练数据中更好地概括,或者它们对问题域中的某些东西进行了很好的建模。

毫无疑问,随着时间的推移,对标准 NN 模型的各种变化进行了探索。那些已经流行起来的都在某些任务上证明了自己,并且经常有相关的论文证明它们的有用性。

例如,卷积神经网络已经证明自己擅长基于图像的任务。二维 CNN 层的设计与图像中的像素在本地如何相互关联具有逻辑匹配——定义边缘、纹理等,因此模型中的架构很好地匹配某些问题域。

如果您可以从向量乘法模型中找到与特定问题域的良好匹配,那么这表明它可能值得实施以测试该理论。如果您只是想探索其他 NN 结构以查看它们是否有效,您仍然可以这样做,但是如果没有特定目标,您将寻找要解决的问题(除非您偶然发现一些通常有用但之前被忽略的东西)。

要解决标题中的问题:

为什么神经网络模型不允许输入相乘?

一些低级的(例如TensorFlow)。然而,这并不是一个已经证明自己有用的架构,因此高级库(例如 Keras)的作者没有理由实现或支持它。这种情况有可能是疏忽,这个想法通常是有用的。在这种情况下,一旦有人可以展示这一点,您会发现它会很快得到积极开发的库的支持,因为它看起来很容易实现。

标准神经网络的“通用逼近”不是通用的。小写字母表示目标函数必须有界,并且当每个单元的输出有界到例如 (-1,1) 时,您可能需要一个非常宽的隐藏层才能获得很大的值范围。然后是高效学习的问题,因为表达能力并不意味着有效学习的能力。探索其他类型的神经元可能很有用。

乘法神经元的一个具体应用可能是有一个初始层,它从输入中生成任意数量的复合特征,泛化到一组固定的多项式项之外,其中非负整数指数低于给定值。下一层可以由标准的加性神经元组成,给出特征的线性组合。

已经探索了乘法神经元。还有在加法和乘法之间插值(至少近似地)的神经元:

最后一个,来自 Deepmind 的 NALU,显然取得了巨大的成功,并且存在于多个 NN 框架的社区实现中。它可以插入线性层,尽管计算成本更高,并且需要训练更多参数。

乘积的对数是因子的对数之和。因此,为正输入制作乘法神经元层的一种方法是将对数应用于输入,然后通过线性层运行它们,然后对输出求幂。权重将对应于指数。

更新:看到这个答案

这是矩阵乘法的标准定义。我的意思是对这些值求和。你不必让它像那样工作,事实上,如果你愿意,你可以将它们相乘。只需执行一系列标量乘法即可:

# Input vector
X = tf.placeholder("float32", (-1, 30)) # so a 1x30 input vector

# "Layer 1"
w_l1 = []
for n in range(50):
  w_l1.append(tf.Variable(tf.random_normal((1,))))

l1 = []
for n in range(50):
  l1.append(X * w_l1[n])

l1_out = l1[0]
for n in range(1, 50):
  l1_out *= l1[n]

这接近你的意思吗?

更一般地说,我认为你想要实现的大部分都可以通过 tensorflow 中的 reduce_prod 方法来完成,而 theano 也有类似的功能。我认为它没有在实践中完成,因为它不会在张量上形成一个环。

本文指出(逐字):

...乘法和除法可以通过深度 3 ANN 计算