1 回答
TA贡献1818条经验 获得超3个赞
混合可能很棘手numpy;再加上由 .而不是基本数组类型sympy引起的潜在混淆。np.matndarray
总共
y_ = np.sum(np.dot(w,x)+b)
评估 sympy 对象上的 python/numpy 表达式。结果是一个同情的表达w*x+b。sympy 对象是标量,因此它不编码任何类型的矩阵乘法或数组求和。multiply表达式的计算方式相同。
然后,lambdify表达式将相同的内容转换为y_相同的 Python 函数。这种评估取决于np.mat论点的维度和类别。
细节
暂时忽略sympy部分:
In [310]: w = np.mat([1,1,1,1,1])
...: x= np.mat([1,1,1,1,1]).T
...: b = np.mat([0,0,0,0,0]).T
...: y = np.mat([6,6,6,6,6]).T
In [311]: np.sum(np.dot(w,x)+b)
Out[311]: 25
In [312]: np.multiply(w,x)+b
Out[312]:
matrix([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
因为它们是,np.mat两者都是 2d:wx
In [316]: w.shape
Out[316]: (1, 5)
In [317]: x.shape
Out[317]: (5, 1)
np.dot(1,5) 和 (5,1) 是 (1,1) 结果:
In [313]: np.dot(w,x)
Out[313]: matrix([[5]])
而对于np.matrix,*被定义为dot:
In [314]: w*x
Out[314]: matrix([[5]])
元素方面:
In [315]: np.multiply(w,x) # elementwise produces (5,5)
Out[315]:
matrix([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.sum(np.dot(w,x)+b)做dot, 然后添加b, 并以 asum结束所有元素。
np.multiply(w,x)+b这是否相乘,增加b。没有sum。
更正
使用w.T我第一次错过的:
In [322]: np.multiply(w.T,x)
Out[322]:
matrix([[1],
[1],
[1],
[1],
[1]])
In [323]: w.T*x
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-323-11ad839cfa88> in <module>
----> 1 w.T*x
/usr/local/lib/python3.6/dist-packages/numpy/matrixlib/defmatrix.py in __mul__(self, other)
218 if isinstance(other, (N.ndarray, list, tuple)) :
219 # This promotes 1-D vectors to row vectors
--> 220 return N.dot(self, asmatrix(other))
221 if isscalar(other) or not hasattr(other, '__rmul__') :
222 return N.dot(self, other)
<__array_function__ internals> in dot(*args, **kwargs)
ValueError: shapes (5,1) and (5,1) not aligned: 1 (dim 1) != 5 (dim 0)
np.multiply(5,1) 和 (5,1) 产生 (5,1),元素乘法
w.T*x是 的矩阵乘法np.mat,因此有np.dot误差。
不鼓励使用np.mat(如果没有正式贬低)。此外消除了它的符号优势numpy。如果你坚持使用基数组类,matmul/@生活会更简单, . 我意识到仍然使用二维矩阵概念,作为矩阵乘法。 numpyndarraysympy*
同情
在一个isympy会话中,我发现我需要定义w,x,b为符号:
y_ = np.sum(np.dot(w,x)+b)
如果w,x,b只是符号,它们是标量,而不是矩阵或数组。你的np.sum(np.dot(1,2)+4),np.multiply(1,2)+4并且1*2+4都产生同样的东西。只有当变量是数组,或者np.mat,或者sympy.Matrix表达式不同时。
问题不在于lambdify. 在这两种情况下,它都是相同的y_(由 验证print(y_)。您会收到错误,因为参数是np.mat,并且*是矩阵乘法。
带x,y,z符号:
In [55]: f = lambdify((x,y,z),x*y+z, 'numpy')
使用isympy内省:
In [56]: f??
Signature: f(x, y, z)
Docstring:
Created with lambdify. Signature:
func(x, y, z)
Expression:
x*y + z
Source code:
def _lambdifygenerated(x, y, z):
return (x*y + z)
Imported modules:
Source:
def _lambdifygenerated(x, y, z):
return (x*y + z)
File: ~/mypy/<lambdifygenerated-4>
Type: function
阅读lambdify. 请注意,它基本上是一个词法替换
https://docs.sympy.org/latest/modules/utilities/lambdify.html
本文档警告:
作为一般规则,NumPy 函数不知道如何对 SymPy 表达式进行操作,而 SymPy 函数也不知道如何对 NumPy 数组进行操作。这就是 lambdify 存在的原因:在 SymPy 和 NumPy 之间架起一座桥梁。
同化
https://docs.sympy.org/latest/modules/core.html#module-sympy.core.sympify
说它使用eval. 定义x,y,z为符号:
In [66]: eval('np.dot(x,y)+z')
Out[66]: x⋅y + z
In [67]: eval('np.sum(np.dot(x,y)+z)')
Out[67]: x⋅y + z
In [68]: eval('np.multiply(x,y)+z')
Out[68]: x⋅y + z
换句话说,它只是将符号传递给 numpy 函数(和/或运算符),
In [69]: np.dot(x,y)
Out[69]: x⋅y
dot将其输入转换为数组:
In [70]: np.array(x)
Out[70]: array(x, dtype=object)
In [71]: np.dot(np.array(x), np.array(y))
Out[71]: x⋅y
这是有效的,因为符号定义了“*”和“+”。
sympy文档警告说,评估numpy对 sympy 对象一无所知。它将它们视为对象 dtype 数组,这可能会或可能不会起作用:
In [72]: sin(x) # sympy sin
Out[72]: sin(x)
In [73]: np.sin(x) # numpy sin
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
AttributeError: 'Symbol' object has no attribute 'sin'
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-73-92f2c2d0df9d> in <module>
----> 1 np.sin(x)
TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable sin method
np.sin执行然后np.sin(np.array(x))将操作委托给不存在的sin方法。x
添加回答
举报