• [代码学习]matmul的理解与使用


    matmul 的理解与使用

    引言:本实例以paddle框架中的matmul为例进行说明。torchnumpy中的matmul同理。

    简介

    PaddlePaddle中的matmul是一个矩阵乘法函数,可以用来实现两个矩阵的乘法操作。在PaddlePaddle的动态图模式下,可以用paddle.matmul()函数来调用该函数,其语法如下:

    # 源码链接:https://github.com/PaddlePaddle/Paddle/blob/release/2.5/python/paddle/tensor/linalg.py#L139
    paddle.matmul(x, y, transpose_x=False, transpose_y=False, name=None)
    
    • 1
    • 2

    参数

    • x (Tensor) - 输入变量,类型为 Tensor,数据类型为 bfloat16, float16, float32, float64。

    • y (Tensor) - 输入变量,类型为 Tensor,数据类型为 bfloat16, float16, float32, float64。

    • transpose_x (bool,可选) - 相乘前是否转置 x,默认值为 False。

    • transpose_y (bool,可选) - 相乘前是否转置 y,默认值为 False。

    • name (str,可选) - 具体用法请参见 Name,一般无需设置,默认值为 None。

    返回

    • Tensor,矩阵相乘后的结果,数据类型和输入数据类型一致。

    说明

    目前,输入 Tensor 的维数可以是任意数量,matmul 可以用于 实现 dot , matmul 和 batchmatmul。实际行为取决于输入 x 、输入 y 、 transpose_x , transpose_y。具体如下:

    如果 transpose 为真,则对应 Tensor 的后两维会转置。如果 Tensor 的一维,则转置无效。假定 x 是一个 shape=[D] 的一维 Tensor,则 x 视为 [1, D]。然而,y 是一个 shape=[D]的一维 Tensor,则视为[D, 1]。

    乘法行为取决于 x 和 y 的尺寸。具体如下:

    • 如果两个 Tensor 均为一维,则获得点积结果。

    • 如果两个 Tensor 都是二维的,则获得矩阵与矩阵的乘积。

    • 如果 x 是 1 维的,而 y 是 2 维的,则将 1 放在 x 维度之前,以进行矩阵乘法。矩阵相乘后,将删除前置尺寸。

    • 如果 x 是 2 维的,而 y 是 1 维的,获得矩阵与向量的乘积。

    • 如果两个输入至少为一维,且至少一个输入为 N 维(其中 N> 2),则将获得批矩阵乘法。如果第一个自变量是一维的,则将 1 放在其维度的前面,以便进行批量矩阵的乘法运算,然后将其删除。如果第二个参数为一维,则将 1 附加到其维度后面,以实现成批矩阵倍数的目的,然后将其删除。根据广播规则广播非矩阵维度(不包括最后两个维度)。例如,如果输入 x 是(j,1,n,m)Tensor,另一个 y 是(k,m,p)Tensor,则 out 将是(j,k,n,p)Tensor。

    实例

    下面对不同维度举例,演示如何使用PaddlePaddle中的matmul函数计算两个矩阵的乘积:

    [3,2] matmul [2,2] -> [3,2]

    import paddle
    
    # 定义两个输入矩阵
    x = paddle.to_tensor([[1, 2], [3, 4], [5, 6]], dtype='float32')
    y = paddle.to_tensor([[2, 1], [4, 3]], dtype='float32')
    
    # 计算矩阵乘积
    z = paddle.matmul(x, y)
    
    # 打印结果
    print(f"x: \n{x.numpy()}, shape: {x.shape}")
    print(f"y: \n{y.numpy()}, shape: {y.shape}")
    print(f"z: \n{z.numpy()}, shape: {z.shape}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出结果为:

    x: 
    [[1. 2.]
     [3. 4.]
     [5. 6.]], shape: [3, 2]
    y: 
    [[2. 1.]
     [4. 3.]], shape: [2, 2]
    z: 
    [[10.  7.]
     [22. 15.]
     [34. 23.]], shape: [3, 2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这个例子中,我们首先定义了两个输入矩阵x和y,然后调用paddle.matmul()函数计算它们的乘积,并将结果保存到变量z中。最后,我们打印出x,y,z的值和形状,方便观察结果。

    [2] matmul [2, 3] -> [3]

    import paddle
    
    # 定义两个输入矩阵
    # x = paddle.to_tensor([[1, 2], [3, 4], [5, 6]], dtype='float32')
    # x = paddle.to_tensor([[1, 2], [3, 4]], dtype='float32')
    x = paddle.to_tensor([[1, 2, 3], [4, 5, 6]], dtype='float32')
    
    # y = paddle.to_tensor([[2, 1], [4, 3]], dtype='float32')
    y = paddle.to_tensor([2, 1], dtype='float32')
    
    # 计算矩阵乘积
    # z = paddle.matmul(x, y)
    z = paddle.matmul(y, x)
    
    # 打印结果
    print(f"x: \n{x.numpy()}, shape: {x.shape}")
    print(f"y: \n{y.numpy()}, shape: {y.shape}")
    print(f"z: \n{z.numpy()}, shape: {z.shape}")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果为:

    x: 
    [[1. 2. 3.]
     [4. 5. 6.]], shape: [2, 3]
    y: 
    [2. 1.], shape: [2]
    z: 
    [ 6.  9. 12.], shape: [3]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [2,2] matmul [2] -> [2]

    如果第一个参数或者第二个参数是1 维的,它会提升该参数为矩阵(根据另一个参数维数,给该参数增加一个为1的维数)。矩阵相乘之后会将为1的维数去掉。

    import paddle
    
    # 定义两个输入矩阵
    # x = paddle.to_tensor([[1, 2], [3, 4], [5, 6]], dtype='float32')
    x = paddle.to_tensor([[1, 2], [3, 4]], dtype='float32')
    
    # y = paddle.to_tensor([[2, 1], [4, 3]], dtype='float32')
    y = paddle.to_tensor([2, 1], dtype='float32')
    
    # 计算矩阵乘积
    z = paddle.matmul(x, y)
    
    # 打印结果
    print(f"x: \n{x.numpy()}, shape: {x.shape}")
    print(f"y: \n{y.numpy()}, shape: {y.shape}")
    print(f"z: \n{z.numpy()}, shape: {z.shape}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    输出结果为:

    x: 
    [[1. 2.]
     [3. 4.]], shape: [2, 2]
    y: 
    [2. 1.], shape: [2]
    z: 
    [ 4. 10.], shape: [2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [2] matmul [2] -> [1]

    import paddle
    
    # 定义两个输入矩阵
    # x = paddle.to_tensor([[1, 2], [3, 4], [5, 6]], dtype='float32')
    # x = paddle.to_tensor([[1, 2], [3, 4]], dtype='float32')
    x = paddle.to_tensor([1, 2], dtype='float32')
    
    # y = paddle.to_tensor([[2, 1], [4, 3]], dtype='float32')
    y = paddle.to_tensor([2, 1], dtype='float32')
    
    # 计算矩阵乘积
    z = paddle.matmul(x, y)
    
    # 打印结果
    print(f"x: \n{x.numpy()}, shape: {x.shape}")
    print(f"y: \n{y.numpy()}, shape: {y.shape}")
    print(f"z: \n{z.numpy()}, shape: {z.shape}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    输出结果为:

    x: 
    [1. 2.], shape: [2]
    y: 
    [2. 1.], shape: [2]
    z: 
    [4.], shape: [1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    reference

    @misc{BibEntry2023Oct,
    title = {{matmul-API文档-PaddlePaddle深度学习平台}},
    year = {2023},
    month = oct,
    urldate = {2023-10-10},
    language = {chinese},
    note = {[Online; accessed 10. Oct. 2023]},
    url = {https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/matmul_cn.html}
    }

  • 相关阅读:
    [附源码]java毕业设计大学生心理咨询网站
    基于 Kubernetes 的 Serverless PaaS 稳定性建设万字总结
    Chapter8_FundamentalsOfComputerGraphic
    elasticsearch升级和索引重建
    Nvidia Jetson Nano学习笔记--使用C语言实现GPIO 输入输出
    TypeError: ‘float‘ object is not subscriptable 已解决
    LM324的输出VOL与IOL你注意过吗?
    刷题日记【第十一篇】-笔试必刷题【小易的升级之路+找出字符串中第一个只出现一次的字符+微信红包+计算字符串的编辑距离】
    八大排序详解
    Rust使用Rust For Windows调用CreateProcessA
  • 原文地址:https://blog.csdn.net/orDream/article/details/133744368