代码之家  ›  专栏  ›  技术社区  ›  raaj

辛张量积错误结果

  •  0
  • raaj  · 技术社区  · 5 年前

    A = Array(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,1,1,1,1,1,1,1,1,1,1]
        ])).reshape(3,3,4)
    
    b = Array(Matrix([
        [1,1,1,1],
        [1,1,1,1],
        [1,1,1,1]
        ])).reshape(3,4,1)
    
    MatMul(A,b)
    

    我相信这是和matmul一起做的?但当我试图用SymPy Matmul做这件事时,我得到了一个错误:

    AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_base_exp'

    0 回复  |  直到 5 年前
        1
  •  2
  •   hpaulj    5 年前

    让我们澄清一下 matmul numpy :

    In [8]: A = np.arange(24).reshape(2,3,4); B = np.arange(8).reshape(2,4,1)       
    In [9]: A@B                                                                     
    Out[9]: 
    array([[[ 14],
            [ 38],
            [ 62]],
    
           [[302],
            [390],
            [478]]])
    In [10]: _.shape                                                                
    Out[10]: (2, 3, 1)
    

    这是在做一件好事 dot ,或最后两个轴上的二维矩阵积。在第一个轴上有效的批处理:

    In [11]: A[0].dot(B[0])                                                         
    Out[11]: 
    array([[14],
           [38],
           [62]])
    

    einsum ,而 i k 轴是1的乘积之和。

    In [12]: np.einsum('ijk,ikl->ijl',A,B)                                          
    Out[12]: 
    array([[[ 14],
            [ 38],
            [ 62]],
    
           [[302],
            [390],
            [478]]])
    

    我认为这里的问题是 sympy/tensor 模块也可以这样做。

    In [13]: from sympy import Array, tensorproduct, tensorcontraction              
    In [14]: As = Array(A[0])                                                       
    In [15]: As                                                                     
    Out[15]: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
    In [16]: Bs = Array(B[0])                                                       
    In [17]: Bs                                                                     
    Out[17]: [[0], [1], [2], [3]]
    In [18]: tensorproduct(As,Bs)                                                   
    Out[18]: [[[[0], [0], [0], [0]], [[0], [1], [2], [3]], [[0], [2], [4], [6]], [[0], [3], [6], [9]]], [[[0], [4], [8], [12]], [[0], [5], [10], [15]], [[0], [6], [12], [18]], [[0], [7], [14], [21]]], [[[0], [8], [16], [24]], [[0], [9], [18], [27]], [[0], [10], [20], [30]], [[0], [11], [22], [33]]]]
    In [19]: tensorcontraction(_, (1,2))                                            
    Out[19]: [[14], [38], [62]]
    

    所以 Out[19] Out[11] . 我们可以重复这一点 A[1]

    sympy/Matrix 类别:

    In [20]: from sympy import Matrix                                               
    In [21]: Matrix(A[0])*Matrix(B[0])                                              
    Out[21]: 
    Matrix([
    [14],
    [38],
    [62]])
    

    制作3d交响乐 Array :

    In [22]: AS = Array(A)                                                          
    In [23]: AS                                                                     
    Out[23]: [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
    In [24]: AS.shape                                                               
    Out[24]: (2, 3, 4)
    In [25]: BS = Array(B)                                                          
    In [26]: BS.shape                                                               
    Out[26]: (2, 4, 1)
    

    tensorproduct 生成一个6d阵列:

    In [28]: CS = tensorproduct(AS, BS)                                             
    In [29]: CS.shape                                                               
    Out[29]: (2, 3, 4, 2, 4, 1)
    

    拆下中间部分 2 :

    In [30]: CS[:,:,:,0,:,:].shape                                                  
    Out[30]: (2, 3, 4, 4, 1)
    

    In [31]: tensorcontraction(CS[:,:,:,0,:,:],(2,3)).shape                         
    Out[31]: (2, 3, 1)
    In [32]: tensorcontraction(CS[:,:,:,0,:,:],(2,3))                               
    Out[32]: [[[14], [38], [62]], [[86], [110], [134]]]
    

    上半场比赛 Out[9]

    马特穆尔 添加到 这在很大程度上是因为很难实现所需的“批量”操作 np.dot np.tensordot ). np.einsum

    埃因苏姆 用一个 K 收缩,包含 输出[9] Out[32]

    In [80]: np.einsum('ijk,lkn',A,B)                                               
    Out[80]: 
    array([[[[ 14],
             [ 38]],
    
            [[ 38],
             [126]],
    
            [[ 62],
             [214]]],
    
    
           [[[ 86],
             [302]],
    
            [[110],
             [390]],
    
            [[134],
             [478]]]])
    

    问题是,如何选择正确的子集。 tensorcontraction CS[:,:,:,0,:,:] 这不是消除重复的正确方法。

    In [81]: tensorcontraction(CS, (2,4))                               
    Out[81]: [[[[14], [38]], [[38], [126]], [[62], [214]]], [[[86], [302]], [[110], [390]], [[134], [478]]]]
    
    Out[81]: [[[[14], [38]], 
               [[38], [126]], 
               [[62], [214]]], 
    
              [[[86], [302]], 
               [[110], [390]], 
               [[134], [478]]]
             ]
    

    埃因苏姆

    In [96]: np.einsum('ijk,lkn',A,B)[[0,1],:,[0,1],:]                              
    Out[96]: 
    array([[[ 14],
            [ 38],
            [ 62]],
    
           [[302],
            [390],
            [478]]])
    

    我们可以用另一个做同样的事情 埃因苏姆 np.einsum('ijim->ijm', np.einsum('ijk,lkn',A,B)) In[12]

    我也可以用这个 Out[81] 对象这个 sympy.Array 显然没有实现与之相同的高级索引 :

    In [108]: np.array(Out[81].tolist())[[0,1],:,[0,1],:]                           
    Out[108]: 
    array([[[14],
            [38],
            [62]],
    
           [[302],
            [390],
            [478]]], dtype=object)
    

    我应该记得,在其他情况下,当我试图实施 马特穆尔 使用 NP点 ,我必须这样画对角线。实际上 在非合并维度上获取外部产品,我们必须丢弃大部分值。

    另一种看待这一点的方式是我们想要 np.dot(A[0], B[0]) np.dot(A[1], B[1]) tesorproduct (外部产品)也给了我们 np.dot(A[0], B[1]) np.dot(A[1], B[0]) .