PyTorch 矩阵乘法的方法总结 & 问题解答

在机器学习和深度学习中时,矩阵运算是最常见、有效提高计算效率的方法。因为特征和权重都以向量储存,矩阵运算就显得尤为重要,诸如梯度下降、反向传播、矩阵因子分解等重要的机器学习方法,都需要基于矩阵运算。

在深度学习中,神经网络将权重储存在矩阵当中,基于线性代数的运算在 GPU上,可以对矩阵进行简单迅捷的计算处理。

 

小规模的矩阵运算,可以用 for 循环来快速运算。但是一旦遇到巨大的数据量,循环语句就会拖慢运算速度,这时候我们常常使用矩阵乘法,它可以极大提高运算的效率。

 

常见矩阵、向量、标量相乘方法

  • torch(mm) 二维矩阵乘法

torch.mm(mat1,ma2,out=None), 其中 mat1(n*m), mat2(m*d), 输出 out 的维度是(n*d)。

注:计算两个二维矩阵的矩阵乘法,而且不支持广播。

 

  • torch.bmm() 三维带 Batch 矩阵乘法

torch.bmm(bmat1,bmat2,out=None),其中 bmat1(b*n*m), bmat2(B*m*d), 输出 out 的维度是 (B*n*d)。

注:该函数的两个输入必须是三维矩阵且第一维相同(表示Batch维度),不支持广播。

 

  • torch.matmul() 混合矩阵乘法 

torch.matmul(input,other,out=None),该方法较为复杂建议参考文档,两个张量的矩阵乘积,计算结果取决于张量的维度,支持广播。

 

  • torch.mul() 矩阵逐元素乘法 

torch.mul(mat1,other,out=None),其中 other 乘数可以是标量也可以是任意维度的矩阵,只要满足最终相乘即可,支持广播。

 

  • torch.mv() 矩阵向量乘法

torch.mv(mat, vec, out=None) ,对矩阵 mat 和向量 vec 进行相乘。如果mat 是一个 n×m 张量,vec 是一个 m 元的一维张量,将会输出一个 n 元的一维张量,不支持广播。

 

  • torch.dot() 张量点乘法

torch.dot(tensor1, tensor2) ,计算两个张量的点乘,两个张量都为 1-D 向量,不支持广播。

 

论坛热门问题

 Q:不用 for 循环,如何进行批数据向量相乘 ?

input shape:N x M x VectorSize

weight shape:M x VectorSize x VectorSize

目标 output shape:N x M x VectorSize

N 表示批尺寸,M 表示向量数量,VectorSize 则代表向量的大小。

如下图所示:

 解决思路:

N, M, V=2, 3, 5a = torch.randn(N, M, V)b = torch.randn(M, V, V)a_expand = a.unsqueeze(-2)b_expand = b.expand(N, -1, -1, -1)c = torch.matmul(a_expand, b_expand).squeeze(-2)

原帖地址:

https://discuss.pytorch.org/t/batch-matrix-vector-multiplication-without-for-loop/112841

 

 Q:计算矩阵向量乘以批向量输入,出现 RuntimeError 报错 

给定:

# (batch x inp)v = torch.randn(5, 15)# (inp x output)M = torch.randn(15, 20)

计算:

# (batch x output)out = torch.Tensor(5, 20)for i, batch_v in enumerate(v):    out[i] = (batch_v * M).t()

但是 (i) 乘法对于两个维度相同的输入,都会出现:

RuntimeError: inconsistent tensor size at /home/enrique/code/vendor/pytorch/torch/lib/TH/generic/THTensorMath.c:623

为什么会出现这个报错?有没有能避免行向量循环的方法?

 

解决思路:

* 表示 elementwise 乘法,如果你用的是 Python3,可以使用 @ 算子可以用作矩阵-向量乘法和矩阵-矩阵乘法。

也可以使用 batch_v.mm(M),因为批向量矩阵(batched vector matrix)即矩阵-矩阵乘法。

此外还可以借助 bmm、 baddbmm 等方法消除 Python 中的循环操作。

 

原贴地址:

https://discuss.pytorch.org/t/matrix-vector-multiply-handling-batched-data/203

 

 Q:不使用循环语句的前提下,如何计算矩阵向量相乘?

求 2x2 的矩阵乘以 3 个大小为 2 的向量,如果不使用循环,该如何实现?

备注:

1、使用循环语句时代码如下:

A=torch.tensor([[1.,2.],[3.,4.]])b=torch.tensor([[3.,4.], [5.,6], [7.,8.]])res = []for i in range(b.shape[0]):    res.append(torch.matmul(A, b[i]))

2、经尝试 torch.matmul (A.repeat ((2,1,1)) ,b) 行不通。

 解决思路:

可以通过 a.matmul (b.t ()) 实现。

原帖地址:

https://discuss.pytorch.org/t/vectorize-matrix-vector-multiplication/88051

本公众号将持续更新 PyTorch 最新资讯和开发技巧,欢迎关注!

<think>嗯,用户想用Python实现机器人雅可比矩阵导数的求解。首先,我需要回忆一下雅可比矩阵导数的相关知识。根据引用[3]中的代码,看起来是用Hessian矩阵和链式法则来计算导数。不过用户提供的代码里有Hessian0和J_dot这两个函数,可能涉及到雅可比矩阵的导数计算。 首先,雅可比矩阵导数通常指的是雅可比矩阵对时间的导数,也就是在机械臂运动时,各关节速度对末端执行器速度的影响变化。这时候可能需要用到Hessian矩阵,或者通过链式法则来分解。Angeles法在引用[2]中提到,可能需要参考那本书的5.1到5.5章节,但用户可能暂时没有这本书,所以需要给出具体的方法步骤。 然后,用户希望用Python实现。根据引用[3]的代码示例,Hessian0函数计算了一个三维张量H,其中每个H[:,i,j]可能对应雅可比矩阵元素关于关节变量的二阶导数。然后通过链式法则,将H与关节速度dq相乘,得到雅可比矩阵的导数J_dot。 接下来,我需要验证这个方法的正确性。代码中的H计算涉及到雅可比矩阵各列的乘,这可能与机械臂的速度传递有关。比如,每个关节的速度和加速度如何影响末端执行器的速度和加速度。这里可能需要用机器人学中的速度传递公式,比如通过每个连杆的运动学递推。 另外,用户可能需要先计算雅可比矩阵本身,然后才能求导。所以步骤可能分为:1. 计算机器人的雅可比矩阵J;2. 计算Hessian张量H;3. 使用关节速度dq和H相乘得到J_dot。 需要注意,H的计算是否正确。例如,在Hessian0函数中,H的前三行和后三行的乘是否正确对应位置和角速度部分的导数。乘可能对应于旋转速度对线速度和角速度的影响,这需要根据机器人学的理论来确认。 另外,用户可能需要使用符号计算库如SymPy来自动求导,但实际应用中可能更倾向于数值方法,尤其是在实时控制中。不过引用[1]提到PyTorch的自动求导,这可能用于自动计算雅可比矩阵的导数,但需要构造计算图,可能适用于不同的情况。 但用户的问题是关于机器人学的,所以可能更偏向于数值方法,如引用[3]中的代码。因此,步骤可能包括: 1. 确定机器人模型和DH参数,建立运动学模型。 2. 根据当前关节角度q计算雅可比矩阵J0。 3. 计算Hessian张量H,这需要遍历所有关节,计算各列之间的乘。 4. 结合当前的关节速度dq,计算J_dot = H * dq的和。 在实现过程中,需要注意乘的顺序和索引是否正确。例如,H的前三行是位置部分的导数,后三行是角速度部分的导数。而每个H的元素对应J的第i列对第j个关节变量的导数,再乘以关节速度dq[j]。 可能的疑问是,这样的H是否准确,或者是否需要其他方法,如通过数值微分来近似雅可比矩阵的导数。不过数值微分可能误差较大,而解析方法更可靠但复杂。 总结实现步骤: - 实现雅可比矩阵的计算。 - 实现Hessian张量的计算,根据J的各列进行乘。 - 将Hessian张量与关节速度相乘得到J_dot。 最后,验证代码的正确性,可能需要对比已知模型的理论结果或使用仿真软件验证。</think>### 分步解答:Python实现机器人雅可比矩阵导数 #### 一、雅可比矩阵导数的数学定义 雅可比矩阵导数 $J̇$ 表示雅可比矩阵随时间的变化率。对于机械臂,其导数与关节速度 $dq/dt$ 相关,可通过链式法则分解: $$ J̇ = \sum_{i=1}^{n} \frac{\partial J}{\partial q_i} \cdot \dot{q_i} $$ 其中 $\frac{\partial J}{\partial q_i}$ 是雅可比矩阵对第 $i$ 个关节角度的偏导数,$\dot{q_i}$ 是关节速度[^2]。 --- #### 二、实现步骤与代码 ##### 1. **计算雅可比矩阵 $J$** 假设已实现机器人运动学模型(如基于DH参数的正运动学),雅可比矩阵可通过解析法或几何法计算。以6轴机械臂为例: ```python def compute_jacobian(q): # 实现具体的雅可比矩阵计算(此处为示意) J = np.zeros((6, 6)) # 填充位置和姿态导数部分 return J ``` ##### 2. **计算Hessian张量 $H$** Hessian张量 $H \in \mathbb{R}^{6 \times n \times n}$ 存储雅可比矩阵的二阶导数信息。根据Angeles法,可通过乘运算高效计算: ```python def compute_hessian(q, J): n = len(q) H = np.zeros((6, n, n)) for j in range(n): for i in range(j, n): # 位置导数部分:J_rot_j × J_pos_i H[:3, i, j] = np.cross(J[3:, j], J[:3, i]) # 姿态导数部分:J_rot_j × J_rot_i H[3:, i, j] = np.cross(J[3:, j], J[3:, i]) if i != j: H[:3, j, i] = H[:3, i, j] # 对称性填充 return H ``` ##### 3. **计算雅可比矩阵导数 $J̇$** 结合关节速度 $dq$,通过张量乘法计算 $J̇$: ```python def compute_jacobian_derivative(H, dq): n = len(dq) J_dot = np.zeros((6, n)) for i in range(n): J_dot += H[:, :, i] * dq[i] # 按关节速度加权求和 return J_dot ``` --- #### 三、完整调用流程 ```python # 输入:关节角度 q 和关节速度 dq q = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) dq = np.array([0.01, 0.02, 0.03, 0.04, 0.05, 0.06]) # 步骤1:计算雅可比矩阵 J = compute_jacobian(q) # 步骤2:计算Hessian张量 H = compute_hessian(q, J) # 步骤3:计算雅可比矩阵导数 J_dot = compute_jacobian_derivative(H, dq) ``` --- #### 四、验证与优化建议 1. **验证方法**: - 对比数值微分:$J̇ \approx \frac{J(q + \Delta t \cdot dq) - J(q)}{\Delta t}$ - 仿真工具验证(如MATLAB Robotics Toolbox) 2. **优化方向**: - 利用并行计算加速Hessian张量生成 - 使用符号计算库(如SymPy)生成解析表达式[^1] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值