泛舟湖上清波郎朗
混合可能很棘手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]: 25In [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:wxIn [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 + zSource 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 + zIn [67]: eval('np.sum(np.dot(x,y)+z)') Out[67]: x⋅y + zIn [68]: eval('np.multiply(x,y)+z') Out[68]: x⋅y + z换句话说,它只是将符号传递给 numpy 函数(和/或运算符),In [69]: np.dot(x,y) Out[69]: x⋅ydot将其输入转换为数组: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 methodnp.sin执行然后np.sin(np.array(x))将操作委托给不存在的sin方法。x