【问题标题】:Should I transpose features or weights in Neural network?我应该在神经网络中转置特征或权重吗?
【发布时间】:2020-11-10 08:29:47
【问题描述】:

我正在学习神经网络。

下面是完整的代码: https://github.com/udacity/deep-learning-v2-pytorch/blob/master/intro-to-pytorch/Part%201%20-%20Tensors%20in%20PyTorch%20(Exercises).ipynb

当我转置特征时,我得到以下输出:

import torch
def activation(x):
    return 1/(1+torch.exp(-x))

### Generate some data
torch.manual_seed(7) # Set the random seed so things are predictable

# Features are 5 random normal variables
features = torch.randn((1, 5))
# True weights for our data, random normal variables again
weights = torch.randn_like(features)
# and a true bias term
bias = torch.randn((1, 1))

product = features.t() * weights + bias
output = activation(product.sum())

张量(0.9897)

但是,如果我转置权重,我会得到不同的输出:

weights_prime = weights.view(5,1)
prod = torch.mm(features, weights_prime) + bias
y_hat = activation(prod.sum())

张量(0.1595)

为什么会这样?


更新

我看了一下解决方案: https://github.com/udacity/deep-learning-v2-pytorch/blob/master/intro-to-pytorch/Part%201%20-%20Tensors%20in%20PyTorch%20(Solution).ipynb

我看到了这个:

y = activation((features * weights).sum() + bias)

为什么一个矩阵特征(1,5)可以乘另一个矩阵权重(1,5)而不先转置权重?

更新 2

看了几篇文章后,我意识到

matrixA * matrixB 不同于 torch.mm(matrixA,matrixB) 和 torch.matmul(matrixA,matrixB)。

有人可以确认我之间的三个理解吗?

  1. 所以 * 表示逐元素乘法,而 torch.mm() 和 torch.matmul() 是逐矩阵乘法。

  2. torch.mm() 和 torch.matmul() 的区别:mm() 专门用于二维矩阵,而 matmul() 可用于更复杂的情况。

  3. 在我上面链接中提到的这个 Udacity 编码练习的中性网络中,它需要逐元素乘法。

更新 3

只是为了给有同样困惑的人带来视频截图:

这里是视频链接:https://www.youtube.com/watch?time_continue=98&v=6Z7WntXays8&feature=emb_logo

【问题讨论】:

  • 对于您的更新 2:是的,* 用于元素乘法。这会进行广播,这就是为什么行向量* 列向量会产生外积的原因。 torch.matmultorch.mm支持场景,也做广播。对于 Udacity 示例,逐元素乘法有效,因为它后面跟着一个和,这会产生一个点积。

标签: python machine-learning neural-network pytorch


【解决方案1】:

这条线是两个向量之间的外积。

product = features.t() * weights + bias

生成的形状是5x5

如果您将其更改为点积,则 output 将匹配 y_hat

product = torch.mm(weights, features.t()) + bias

【讨论】:

  • 感谢@danny 的回答。所以NN需要点积而不是外积,对吗?而且,如果我在 2、羽毛和权重之间进行点积,那么在这种情况下,特征和权重的顺序将无关紧要,对吗?
  • 特征和权重的顺序对于点积无关紧要,但在使用torch.mm 计算点积时它们会很重要,因为该函数执行矩阵乘法。要对点积使用矩阵乘法,第一个参数应该是行向量,第二个参数应该是列向量。
  • 关于 NN 是否需要点积,这是在应用偏差和激活函数之前考虑如何计算每个单元的激活的一般方法。点积通常组合在一起,这样整个层的点积计算可以通过权重矩阵和前一层的活动向量的单个矩阵相乘来计算。
  • 感谢 Danny,您建议我使用 torch.mm(),而其他人建议使用 torch.matmul()。有什么区别?我应该使用哪一个?
  • torch.mmtorch.matmul 都执行矩阵乘法,但前者不执行 broadcast(在适用的情况下自动扩展张量)而后者执行。
【解决方案2】:

看着https://pytorch.org/docs/master/generated/torch.nn.Linear.html

torch 中典型的线性(全连接)层使用形状为(N,∗,in_features) 的输入特征和形状为(out_features,in_features) 的权重来生成形状为(N,*,out_features) 的输出。这里 N 是批量大小,* 是任意数量的其他维度(可能没有)。

实现是:

output = input.matmul(weight.t())

因此,根据惯例,答案是您的公式都不正确;标准公式就是上面那个。

您可以使用非标准形状,因为您是从头开始实现的;只要它是一致的,它就可以工作,但我不推荐它来学习。目前尚不清楚代码中的 1 和 5 是什么,但大概您需要 5 个输入特征和一个输出特征,批量大小也为 1。在这种情况下,标准形状应该输入 = torch.randn((1, 5)),批量大小=1 和 in_features=5,权重 = torch.randn((5, 1)),in_features=5 和 out_features=1。

没有理由让权重与特征具有相同的形状;因此weights = torch.randn_like(features) 没有意义。

最后,对于您的实际问题:

“我应该在神经网络中转置特征或权重吗?” - 在火炬约定中,您应该转置权重,但首先使用带有特征的 matmul。其他框架可能有不同的约定;只要权重的 in_features 维度乘以输入的 num_features 维度,就可以了。

“为什么会这样?” - 这是两个完全不同的计算;没有理由认为它们会产生相同的结果。

“所以 * 表示逐元素乘法,而 torch.mm() 和 torch.matmul() 是逐矩阵乘法。” - 是的; mm 只是矩阵矩阵,matmul 是向量矩阵或矩阵矩阵,包括相同的批处理版本 - 检查文档以了解 matmul 可以做的所有事情(这有点多)。

“torch.mm() 和 torch.matmul() 的区别:mm() 专门用于二维矩阵,而 matmul() 可用于更复杂的情况。” - 是的;最大的不同是 matmul 可以广播。当您有明确意图时使用它;使用 mm 来防止无意的广播。

“在我上面链接中提到的这个 Udacity 编码练习的中性网络中,它需要逐元素乘法。” - 我对此表示怀疑;这可能是 Udacity 代码中的错误。这段代码weights = torch.randn_like(features) 在任何情况下看起来都像是一个错误;权重的维度与特征维度的含义不同。

【讨论】:

  • 非常感谢您的详细解释。对典型线性层的解释确实让我对它有了更好的理解。但是当你说:形状的重量(out_features, in_features) 时,我会感到困惑。例如,如果我有一个用于识别鸟类的 NN,输出为 True 或 False,out_features 为 1,还假设 in_features=10000。所以根据你的解释,权重的形状是 (1, 10000) 这意味着权重只有 1 行。但是我在训练鸟类模型时看到权重有多行。你怎么解释这个?
  • 嗨@Alex,我也更新了我的问题,包括完整代码示例的链接。这个练习来自 Udacity。就像你说的:weights = torch.randn_like(features) 没有意义。我发现很难理解。
  • @Franva " 输出为 True 或 False,out_features 为 1,也假设 in_features=10000 。所以根据你的解释,权重的形状是 (1, 10000) 这意味着只有权重有 1 行。” - 是的,这是正确的:一个输出意味着权重(在最后一层)将具有形状(1,某物)
  • 谢谢你,你能看看我的更新2关于3件事情的确认吗?收到这 3 个确认后,我应该能够清除所有的困惑。
  • @Franva 当然,已回答。对于这种详细程度,赏金是合适的。
猜你喜欢
  • 1970-01-01
  • 2018-01-22
  • 2017-05-06
  • 1970-01-01
  • 2012-07-10
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
相关资源
最近更新 更多