深度学习中的乘法运算类型
2025-9-7
1. 点积 (Dot Product)
符号表示:a · b 或 ⟨a, b⟩
定义:两个向量对应元素相乘后求和,结果为标量。
数学表示:
a · b = Σᵢ aᵢbᵢ = a₁b₁ + a₂b₂ + ... + aₙbₙ
具体案例:
a = [1, 2, 3]
b = [4, 5, 6]
a · b = 1×4 + 2×5 + 3×6 = 4 + 10 + 18 = 32
特点要求:
- 两个向量必须具有相同的维度
- 结果是标量值
- 满足交换律:
a · b = b · a - 满足分配律:
a · (b + c) = a · b + a · c - 几何意义:向量投影的度量
应用场景:
- 注意力机制中的相似度计算
- 余弦相似度计算
- 神经网络激活值计算
- 损失函数中的内积计算
2. 矩阵乘法 (Matrix Multiplication)
符号表示:A × B、A @ B 或 AB
定义:按照矩阵乘法规则进行的线性代数运算。
数学表示:
C = A × B,其中 Cᵢⱼ = Σₖ AᵢₖBₖⱼ
具体案例:
A = [[1, 2], B = [[5, 6],
[3, 4]] [7, 8]]
A × B = [[1×5+2×7, 1×6+2×8], = [[19, 22],
[3×5+4×7, 3×6+4×8]] [43, 50]]
特点要求:
- A的列数必须等于B的行数:A(m×k) × B(k×n) → C(m×n)
- 不满足交换律:
A×B ≠ B×A(一般情况) - 满足结合律:
(A×B)×C = A×(B×C) - 计算复杂度:O(m×n×k)
应用场景:
- 全连接层的线性变换:
y = Wx + b - 卷积操作的底层实现
- 注意力机制中的Q、K、V变换
- 批量数据的前向传播
3. 哈达玛积 / 元素级乘法 (Hadamard Product / Element-wise Multiplication)
符号表示:A ⊙ B 或 A * B(编程中)
定义:两个相同形状的张量对应位置元素相乘。
数学表示:
C = A ⊙ B,其中 Cᵢⱼ = AᵢⱼBᵢⱼ
具体案例:
基础元素级乘法
# 向量
a = [1, 2, 3]
b = [4, 5, 6]
a ⊙ b = [1×4, 2×5, 3×6] = [4, 10, 18]
# 矩阵
A = [[1, 2], B = [[5, 6],
[3, 4]] [7, 8]]
A ⊙ B = [[1×5, 2×6], = [[5, 12],
[3×7, 4×8]] [21, 32]]
广播乘法案例
# 标量广播
2 ⊙ [[1, 2], = [[2, 4],
[3, 4]] [6, 8]]
# 向量广播
[[1, 2, 3], ⊙ [10, 20, 30] = [[10, 40, 90],
[4, 5, 6]] [40, 100, 180]]
编程实现
# PyTorch
import torch
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
c = a * b # 或 torch.mul(a, b)
# TensorFlow
import tensorflow as tf
c = tf.multiply(a, b) # 或 a * b
# NumPy
import numpy as np
c = np.multiply(a, b) # 或 a * b
特点要求:
- 参与运算的张量必须形状相同或可广播
- 结果张量形状与输入相同(或广播后的形状)
- 满足交换律和结合律
- 逐元素操作,高度并行化
- 支持广播机制
应用场景:
- 门控机制:LSTM/GRU中的遗忘门、输入门
- 掩码操作:Dropout、注意力掩码
- 特征融合:多模态特征合并
- 激活函数:ReLU等的梯度计算
- 归一化操作:BatchNorm中的缩放
运算对比总结
| 乘法类型 | 符号 | 输入要求 | 输出形状 | 计算复杂度 | 主要用途 |
|---|---|---|---|---|---|
| 点积 | a · b |
向量维度相同 | 标量 | O(n) | 相似度、投影 |
| 矩阵乘法 | A × B |
A列数=B行数 | (A行×B列) | O(mnk) | 线性变换 |
| 元素级乘法 | A ⊙ B |
形状相同/可广播 | 保持形状 | O(n) | 门控、掩码 |
实际应用示例
注意力机制中的综合应用
# 1. 矩阵乘法:计算注意力分数
scores = Q @ K.T # (seq_len, d_k) @ (d_k, seq_len) → (seq_len, seq_len)
# 2. 元素级乘法:应用掩码
masked_scores = scores ⊙ mask # 屏蔽无效位置
# 3. 点积:在损失函数中计算相似度
similarity = query · key # 计算查询和键的相似度
问题1 :
那怎么理解我们说的点积法计算相似度
当Q和K是多维矩阵时(比如4×3),我们实际上是在进行批量点积计算,这时候会用矩阵乘法来高效实现。
多维情况的具体示例
情况:Q (4×3) 和 K (4×3)
两种计算方式
方式1:逐个计算点积(概念理解)
# 计算每个query与每个key的点积
similarities_manual = np.zeros((4, 4))
for i in range(4): # 遍历每个query
for j in range(4): # 遍历每个key
# 这里是真正的向量点积
similarities_manual[i, j] = np.dot(Q[i], K[j])
print(f"Q[{i}] · K[{j}] = {Q[i]} · {K[j]} = {similarities_manual[i, j]}")
print("\n手动计算结果:")
print(similarities_manual)
方式2:矩阵乘法(高效实现)
# 使用矩阵乘法批量计算所有点积
similarities_matrix = Q @ K.T # (4×3) @ (3×4) = (4×4)
print("矩阵乘法结果:")
print(similarities_matrix)
结果解释
得到的4×4相似度矩阵:
similarities[i,j] = Q[i] · K[j] # 第i个query与第j个key的相似度
# 完整示例
similarities = Q @ K.T
print("相似度矩阵 (4×4):")
print(similarities)
# 结果矩阵的含义:
# [[ 7 5 9 9] <- query 0 与所有key的相似度
# [ 5 4 0 3] <- query 1 与所有key的相似度
# [ 3 2 6 3] <- query 2 与所有key的相似度
# [ 4 3 3 3]] <- query 3 与所有key的相似度
注意力机制中的实际应用
# 完整的注意力计算流程
def scaled_dot_product_attention(Q, K, V, d_k):
"""
Q: (batch_size, seq_len_q, d_k)
K: (batch_size, seq_len_k, d_k)
V: (batch_size, seq_len_v, d_v)
"""
# 1. 计算所有query-key对的点积相似度
scores = Q @ K.transpose(-2, -1) # (..., seq_len_q, seq_len_k)
# 2. 缩放(防止梯度消失)
scores = scores / np.sqrt(d_k)
# 3. Softmax归一化得到注意力权重
attention_weights = softmax(scores, axis=-1)
# 4. 加权求和得到输出
output = attention_weights @ V
return output, attention_weights
# 使用示例
batch_size, seq_len, d_model = 2, 4, 3
Q = np.random.randn(batch_size, seq_len, d_model) # (2, 4, 3)
K = np.random.randn(batch_size, seq_len, d_model) # (2, 4, 3)
V = np.random.randn(batch_size, seq_len, d_model) # (2, 4, 3)
output, weights = scaled_dot_product_attention(Q, K, V, d_model)
print(f"注意力权重形状: {weights.shape}") # (2, 4, 4)
关键理解
- 本质还是点积:每个相似度值都是两个向量的点积
- 矩阵乘法是实现手段:用来批量高效计算所有向量对的点积
- 维度对应关系:
Q @ K.T中的每个元素result[i,j]- 等于
Q[i,:]与K[j,:]的点积 - 即第i个query向量与第j个key向量的相似度
所以无论是1维向量还是多维矩阵,相似度的核心计算都是向量间的点积,只是在多维情况下我们用矩阵乘法来批量计算所有可能的向量对组合。
沪ICP备2025124802号-1