对于不清楚我要问的问题而投票决定关闭的人,以下是我帖子中的问题:
y
的结果吗? x
是否需要广播? y
是列/行向量? x=np.array([[7],[2],[3]])
怎么办?w=np.array([[1,2,3],[4,5,6],[7,8,9]])
x=np.array([7,2,3])
y=np.dot(w,x)
谁能告诉我y
的结果是什么?
我特意将屏幕快照拼接起来,以便您假装自己正在测试中并且无法运行python来获取结果。
https://docs.scipy.org/doc/numpy-1.15.4/reference/generated/numpy.dot.html#numpy.dot说
如果a是一个N-D数组而b是一个一维数组,则它是 a和b的最后一个轴。
数学中有什么叫做和积的东西吗?
x
是否需要广播?
为什么y
是列/行向量?
如果x=np.array([[7],[2],[3]])
怎么办?
答案 0 :(得分:1)
np.dot
就是矩阵乘法(即w为3x3,x为1x3,因此无法进行WX的矩阵乘法,但XW可以)。 第一种情况:
>>> w=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> x=np.array([7,2,3])
>>> w.shape
(3, 3)
>>> x.shape # 1d vector
(3, )
因此,在这种情况下,它返回W的每行带有
>>> [np.dot(ww,x) for ww in w]
[20, 56, 92]
>>> np.dot(w,x)
array([20, 56, 92]) # as they are both same
更改订单
>>> y = np.dot(x,w) # matrix mult as usual
>>> y
array([36, 48, 60])
第二种情况:
>>> x=np.array([[7],[2],[3]])
>>> x.shape
(3, 1)
>>> y = np.dot(w,x) # matrix mult
>>> y
array([[20],
[56],
[92]])
但是,这次乘积(3x1,3x3)和内积(1x1,1x3)的时间维度都不匹配,因此会产生误差。
>>> y = np.dot(x,w)
Traceback (most recent call last):
File "<ipython-input-110-dcddcf3bedd8>", line 1, in <module>
y = np.dot(x,w)
ValueError: shapes (3,1) and (3,3) not aligned: 1 (dim 1) != 3 (dim 0)
答案 1 :(得分:1)
我认为您的问题不是很明确,而是过于腐。
例如,当文档使用sum product
用于1d by 1d情况,而inner product
用于2d by 2d情况时,为什么在这种nD 1d情况下对matrix product
感到困惑?案件?像内部产品一样,给自己一些自由,将其读取为sum of the products
。
为使示例更清晰,请将w
设置为矩形,以更好地区分行操作和列操作:
In [168]: w=np.array([[1,2,3],[4,5,6]])
...: x=np.array([7,2,3])
...:
...:
In [169]: w.shape
Out[169]: (2, 3)
In [170]: x.shape
Out[170]: (3,)
dot
及其等效的einstein
表示法:
In [171]: np.dot(w,x)
Out[171]: array([20, 56])
In [172]: np.einsum('ij,j->i',w,x)
Out[172]: array([20, 56])
sum of the products
是在重复的j
维度上完成的,而没有对i
进行求和。
我们可以通过广播的逐元素乘法来做同样的事情:
In [173]: (w*x[None,:]).sum(axis=1)
Out[173]: array([20, 56])
尽管此等效操作确实使用广播,但最好不要以这些术语来考虑dot
。
matmul
给出了相同操作的另一种描述,在x
中添加了一个尺寸以形成2d by 2d矩阵乘积,然后进行挤压以删除多余的尺寸。我不认为dot
是在幕后这样做的,但结果是相同的。
这也可以称为矩阵向量乘法,只要您不必坚持将1d x
称为行向量或列向量即可。
现在为2d x
,形状为(3,1):
In [175]: x2 = x[:,None]
In [176]: x2
Out[176]:
array([[7],
[2],
[3]])
In [177]: x2.shape
Out[177]: (3, 1)
In [178]: np.dot(w,x2)
Out[178]:
array([[20],
[56]])
In [179]: np.einsum('ij,jk->ik',w,x2)
Out[179]:
array([[20],
[56]])
总和超过j
,w
的最后一个轴,以及x
的第二个到最后一个。要对元素进行相同的操作,我们必须使用广播来生成3d outer
乘积,然后进行求和以将维数减小到2。
In [180]: (w[:,:,None]*x2[None,:,:]).sum(axis=1)
Out[180]:
array([[20],
[56]])
在此示例中,(2,3) dot (3,1) => (2,1)
。这是完全正常的矩阵产品行为。在第一个(2,3) dot (3,) => (2,)
中。对我来说,这是逻辑上的概括。 (3,) dot (3,) => scalar
(与()相反)是一种特殊情况。
我怀疑第一种情况主要是对看到(3,)形状并认为(1,3)行向量的人来说是一个问题。由于3和1之间的不匹配,(2,3) dot (1,3)
不起作用。