Why sympy lambdify function cannot identify numpy sum function and multiply function
我想使用 sympy 和 numpy 来学习机器学习。因为 symoy 提供了非常方便的偏导数计算。
但是在使用过程中发现sympy的lambdify函数并不能识别numpy的sum函数和multiply函数。
以下面的例子为例
1 2 3 4 5 6 7 8 | y_ = np.sum(np.dot(w,x)+b) print(y_) y_f = lambdify((w,x,b),y_,"numpy") w_l = np.mat([1,1,1,1,1]) x_l= np.mat([1,1,1,1,1]).T b_l = np.mat([0,0,0,0,0]).T y_l = np.mat([6,6,6,6,6]).T print(y_f(w_l,x_l,b_l)) |
1 2 3 4 5 6 7 8 | b + w*x [[5] [5] [5] [5] [5]] Process finished with exit code 0 |
1 2 3 4 5 6 7 8 | y_ = np.multiply(w,x)+b print(y_) y_f = lambdify((w,x,b),y_,"numpy") w_l = np.mat([1,1,1,1,1]).T x_l= np.mat([1,1,1,1,1]).T b_l = np.mat([0,0,0,0,0]).T y_l = np.mat([6,6,6,6,6]).T print(y_f(w_l,x_l,b_l)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | b + w*x Traceback (most recent call last): File"G:/lijie/PycharmProjects/hw3/test.py", line 24, in <module> print(y_f(w_l,x_l,b_l)) File"<lambdifygenerated-1>", line 2, in _lambdifygenerated File"C:\\Users\\lijie\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\ umpy\\matrixlib\\defmatrix.py", line 220, in __mul__ return N.dot(self, asmatrix(other)) ValueError: shapes (5,1) and (5,1) not aligned: 1 (dim 1) != 5 (dim 0) b + w*x Traceback (most recent call last): File"G:/lijie/PycharmProjects/hw3/test.py", line 24, in <module> print(y_f(w_l,x_l,b_l)) File"<lambdifygenerated-1>", line 2, in _lambdifygenerated File"C:\\Users\\lijie\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\ umpy\\matrixlib\\defmatrix.py", line 220, in __mul__ return N.dot(self, asmatrix(other)) ValueError: shapes (5,1) and (5,1) not aligned: 1 (dim 1) != 5 (dim 0) |
如您所见,lambdify 仅接受 lamda 表达式而不检查操作符号。如何解决这个问题呢。谢谢你的帮助
混合
引起的潜在混淆
总共
1 | y_ = np.sum(np.dot(w,x)+b) |
在 sympy 对象上评估 python/numpy 表达式。结果是一个 sympy 表达式
细节
暂时忽略
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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]]) |
因为它们是
1 2 3 4 | In [316]: w.shape Out[316]: (1, 5) In [317]: x.shape Out[317]: (5, 1) |
1 2 | In [313]: np.dot(w,x) Out[313]: matrix([[5]]) |
,对于
1 2 | In [314]: w*x Out[314]: matrix([[5]]) |
元素方面:
1 2 3 4 5 6 7 | 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]]) |
更正
使用我第一次错过的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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) |
(5,1) 和 (5,1) 的
不鼓励使用
同情
在
1 | y_ = np.sum(np.dot(w,x)+b) |
如果
问题不在于
使用
1 | In [55]: f = lambdify((x,y,z),x*y+z, 'numpy') |
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
阅读
https://docs.sympy.org/latest/modules/utilities/lambdify.html
本文档警告:
As a general rule, NumPy
functions do not know how to operate on SymPy expressions, and SymPy
functions do not know how to operate on NumPy arrays. This is why lambdify
exists: to provide a bridge between SymPy and NumPy.
象征
https://docs.sympy.org/latest/modules/core.html#module-sympy.core.sympify
说它使用
1 2 3 4 5 6 7 8 | 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 函数(和/或运算符),
1 2 | In [69]: np.dot(x,y) Out[69]: x?y |
1 2 3 4 5 | 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 |
这是有效的,因为符号定义了 \\'*\\' 和 \\' \\'。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |