我目前正在研究计算机科学教科书中的一些概念。线性代数被大量使用,它们在教科书中显示的示例均使用Numpy。

特别是一个表达式让我完全困惑,因为它似乎是完全没用的表达式。从教科书复制的逐字记录说:

normalisers = sum(exp(outputs),axis=1)*ones((1,shape(outputs)[0]))

因此,为简化起见,我将删除exp(与此处的问题无关),这将使我们:

sum(outputs,axis=1)*ones((1,shape(outputs)[0]))

其中outputs是二维Numpy array(矩阵)。

据我所知,这只是将outputs矩阵中的所有行相加,然后将所得的矢量逐个元素乘以所有矢量。所以...在这里乘以所有点有什么意义?根本不会更改任何值。

这是教科书中的错误吗,还是我只是不明白乘以所有倍数可能对此处的值有什么影响?在这一点上,我对Numpy只是有点熟悉,所以我不确定是否只是误解了该表达式的某些含义。

最佳答案

正如mutzmatron在评论中所写,当outputs是一个数组时,这种乘法是将sum的结果形状从(n,)更改为(1,n)的一种非常人为的方式。快速而惯用的方式是

sum(exp(outputs), axis=1).reshape(1, -1)


与您的教科书中介绍的方法相比,这既可读又可扩展,因为reshape占用的是常数而不是线性的时间和内存。

但是,如果outputs不是数组而是可怕类型np.matrix的对象,则结果将完全不同:

>>> outputs = np.matrix(outputs)
>>> (sum(exp(outputs), axis=1) * ones((1,shape(outputs)[0]))).shape
(10, 10)


(但是仍然,这是一种表达不同操作的人为方法。)

10-07 13:29