为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 sympy lambdify 函数无法识别 numpy sum 函数和

为什么 sympy lambdify 函数无法识别 numpy sum 函数和

天涯尽头无女友 2022-06-28 15:41:24
我想用 sympy 和 numpy 来学习机器学习。因为 symoy 提供了非常方便的偏导数计算。但是在使用过程中发现sympy lambdify函数并不能识别numpy sum函数和multiply函数。举个例子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]).Tb_l = np.mat([0,0,0,0,0]).Ty_l = np.mat([6,6,6,6,6]).Tprint(y_f(w_l,x_l,b_l))b + w*x[[5] [5] [5] [5] [5]]Process finished with exit code 0y_ = np.multiply(w,x)+bprint(y_)y_f = lambdify((w,x,b),y_,"numpy")w_l = np.mat([1,1,1,1,1]).Tx_l= np.mat([1,1,1,1,1]).Tb_l = np.mat([0,0,0,0,0]).Ty_l = np.mat([6,6,6,6,6]).Tprint(y_f(w_l,x_l,b_l))b + w*xTraceback (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\numpy\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*xTraceback (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\numpy\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 回答

?
泛舟湖上清波郎朗

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


查看完整回答
反对 回复 2022-06-28
  • 1 回答
  • 0 关注
  • 183 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信