一文讲清楚张量、向量、导数、微分、梯度、向量乘法等概念及其在PyTorch中的实现

129 阅读10分钟

概述

想学习神经网络、大模型等底层原理,一些数学上的概念必须搞清楚。本文详细介绍张量、向量、导数、微分、梯度、向量乘法、前馈神经网络等神经网络中相关概念

张量:神经网络中的数据容器

  • 什么是张量?

在神经网络中,所有数据(输入图像、模型权重、梯度)都以张量(Tensor)  形式存在。可以把它理解为 “任意维度的数组”,而标量、向量是它的特殊情况。

  • 什么是标量、向量、多维向量、张量?他们之间有什么区别?

很多人会混淆 “向量” 和 “张量”,核心是要记住:标量是 0 维张量,向量是 1 维张量,矩阵是 2 维张量,更高维的数组就是高维张量。它们的区别用 “维度数(秩)” 和 “索引需求” 就能清晰区分:

类型维度数(秩)数学表示通俗理解代码示例(PyTorch)
标量(Scalar)0 维5、3.14单个数字(无方向)torch.tensor(3.14)
向量(Vector)1 维[1,2,3]、[x,y,z]1 行 / 1 列的有序数字列表torch.tensor([1,2,3])
矩阵(Matrix)2 维[[1,2],[3,4]]行 × 列的表格torch.tensor([[1,2],[3,4]])
高维张量3 维及以上(C,H,W)、(B,C,H,W)多层表格 / 立方体彩色图像:torch.randn(3,224,224)(3 通道,224×224 像素)
  • PyTorch 张量的核心功能

(1)自动微分支持:通过 requires_grad=True 标记张量,自动追踪运算过程,后续用 backward() 计算梯度。

# 创建需要计算梯度的张量(如模型权重) 
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)

(2)设备迁移:轻松在 CPU/GPU 间切换,利用 GPU 加速并行计算。

# 张量迁移到 GPU(需确保有可用 GPU) 
x_gpu = x.cuda() # 或 x.to('cuda')

(3)广播机制:不同形状张量运算时,自动扩展到匹配形状(如 1 维偏置和 2 维权重相加)。

weight = torch.randn(2, 3) # 2×3 矩阵 
bias = torch.randn(3) # 1×3 向量 
result = weight + bias # 自动广播:bias 扩展为 2×3 后相加

导数和微分:神经网络 “优化的数学基础”

神经网络的训练本质是 “通过梯度下降优化损失函数”,而梯度的核心是导数(多变量时为偏导数) 。先搞懂单变量的导数与微分,再扩展到多变量的梯度就很容易。

  • 导数:描述 “变化率”

导数是函数在某一点的 “瞬时变化率”,回答 “自变量变 1 单位时,因变量变多少” 的问题。

(1)数学定义

image.png

(2)通俗理解

比如 (y = x^2) 的导数是 (y' = 2x):

  • 当 (x=1) 时,导数为 2 → 此时 x 每增加 1,y 增加约 2;
  • 当 (x=2) 时,导数为 4 → 此时 x 每增加 1,y 增加约 4。

导数的几何意义是 “函数图像在该点的切线斜率”,斜率越大,函数在该点变化越快。

  • 微分:描述 “微小变化量”

微分是用 “导数” 近似计算 “因变量的微小变化量”,回答 “自变量变一小点时,因变量具体变多少” 的问题。

(1)数学定义

image.png

(2)通俗理解

还是以 (y = x^2) 为例,当 (x=1)、(dx=0.01) 时:

  • 实际变化量 (\Delta y = (1.01)^2 - 1^2 = 0.0201);
  • 微分 (dy = 2 \times 1 \times 0.01 = 0.02),与实际变化量几乎一致(误差可忽略)。

image.png 微分的本质是 “用切线的变化量近似曲线的变化量”,这是梯度下降中 “用梯度更新参数” 的核心逻辑 —— 参数更新量 = 梯度 × 学习率(本质是微分的应用)。

梯度 = 标量(因变量 y)对单个变量(自变量 x)的导数

多维数组的梯度:标量对 “数组每个元素” 的偏导数集合

当张量是多维数组(比如 2 维矩阵、3 维图像张量)时,“梯度” 的定义会扩展,但核心逻辑不变:梯度是 “标量因变量” 对 “多维自变量数组中每个元素” 的偏导数,最终梯度的形状和自变量数组完全一致

  • PyTorch如何实现

手动计算复杂函数的导数(如神经网络的损失函数对权重的偏导数)几乎不可能,PyTorch 的 “自动微分” 功能帮我们自动完成这一过程,核心是计算图(Computation Graph)

import torch 
# 1. 定义自变量张量(需计算梯度) 
x = torch.tensor([2.0], requires_grad=True) # 叶子节点 

# 2. 前向传播:构建计算图(记录运算过程) 
y = x ** 2 # 中间变量:y = x² 
loss = y - 5 # 因变量(损失函数):loss = x² - 5 

# 3. 反向传播:自动计算梯度(loss 对 x 的导数) 
loss.backward() # 沿计算图反向推导,用链式法则算梯度 

# 4. 查看梯度(loss 对 x 的导数:d(loss)/dx = 2x,x=2 时梯度为 4) 
print(x.grad) # 输出:tensor([4.])

下面用一个具体的示例,来讲解梯度

  • 自变量x=[[a,b],[c,d]]
  • 因变量y=x+2
  • 因变量z=yy3
  • out=z.mean()

现在求:求out对x的梯度(导数)。

因为x=[[a,b],[c,d]],所以y=[[a+2,b+2],[c+2,d+2]],则z=[[3*(a+2)²,3*(b+2)²],[3*(c+2)²,3*(d+2)²]],mean()表示求z的平均值,则x的梯度=[[3*(a+2)² , 3*(b+2)²],[ 3*(c+2)² + 3*(d+2)²]]) / 4,即=[[23(a+2), 23(b+2)],[ 23(c+2) ,[ 23(d+2)]]/4=[[1.5a+3,1.5b+3],[1.5c+3,1.5d+3]]=1.5x+3

另外一种计算方法:out=z/4=(x+2)*(x+2)*3/4=1.5x+3

Pytorch代码如下:

x = torch.randn(2, 2, requires_grad=True)
print(x)
#tensor([[ 0.7871,  0.3476],
#        [-0.5405,  2.0334]], requires_grad=True)

# 执行某些操作
y = x + 2
z = y * y * 3
out = z.mean()

# 反向传播,计算梯度
out.backward()

# 查看 x 的梯度
print(x.grad)
#tensor([[4.1806, 3.5214],
#        [2.1892, 6.0500]])

print("用公式计算的梯度:")
m = x * 1.5 + 3
print(m) # 可以发现m和out是相等的
#tensor([[4.1806, 3.5214],
#        [2.1892, 6.0500]], grad_fn=<AddBackward0>)

向量运算: 神经网络 “并行计算的核心”

神经网络中,“输入特征→隐藏层输出” 的计算本质是向量与矩阵的乘法。常用的向量运算包括 “标量乘”“点积(内积)”“叉积(外积)”,其中点积是最核心的运算。

先明确:向量运算的输入是 “1 维张量”,不同运算的核心区别是 “结果类型” 和 “适用场景”。

运算类型数学定义结果类型核心用途Pytorch实现
向量 × 标量向量每个元素乘以标量(如 [1,2,3]×2 = [2,4,6])向量特征缩放(如归一化后的系数调整)

vec = torch.tensor([1, 2, 3]) 
scalar = 2
result = vec * scalar
print(result) # 输出:tensor([2, 4, 6])
点积(内积)对应元素相乘后求和(如 [1,2]・[3,4] = 1×3 + 2×4 = 11)标量隐藏层输出计算(特征 × 权重求和)

a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6]) 
# 方式1:torch.dot()(专门用于1维向量) 
dot1 = torch.dot(a, b) 
# 方式2:torch.matmul()(通用矩阵乘法,1维时等价于点积) 
dot2 = torch.matmul(a, b) 
# 方式3:@ 运算符(重载后等价于matmul) 
dot3 = a @ b 
print(dot1) # 输出:tensor(32)(1×4 + 2×5 + 3×6 = 32)
叉积(外积)仅 3 维向量可用,结果是与原向量垂直的新向量(如 [1,0,0]×[0,1,0] = [0,0,1])向量3D 图形学、物理模拟(如方向计算)

a = torch.tensor([1, 0, 0]) # x轴单位向量 
b = torch.tensor([0, 1, 0]) # y轴单位向量 
cross = torch.cross(a, b) 
print(cross) # 输出:tensor([0, 0, 1])(z轴单位向量,符合右手定则)
  • 向量运算在神经网络中的应用
# 输入特征(1个样本,3个特征)
x = torch.tensor([0.5, 0.3, 0.2])
# 隐藏层权重(3个输入特征 → 2个输出特征)
w = torch.tensor([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])
# 隐藏层偏置(2个输出特征)
b = torch.tensor([0.1, 0.1])

# 隐藏层输出计算:x(1×3)与 w(3×2)矩阵乘法 → 1×2 向量,再加偏置 b
hidden = torch.matmul(x, w) + b
# 激活函数(ReLU):引入非线性
hidden_relu = torch.relu(hidden)

print(hidden_relu)  # 输出:tensor([0.3700, 0.5400])

前馈神经网络:神经网络的 “基础架构”

搞懂了张量、导数、向量运算,再理解前馈神经网络(Feedforward Neural Network, FNN)就很简单 —— 它是 “用向量运算传递数据,用梯度下降优化参数” 的分层架构。

  • 什么是前馈神经网络

前馈神经网络是 “数据从输入层→隐藏层→输出层单向流动,无循环或反馈” 的神经网络,核心特点是:

(1)分层结构:包含输入层(Input Layer)、隐藏层(Hidden Layer)、输出层(Output Layer),隐藏层可多层(多层时称为深度神经网络,DNN);

(2)无反馈:数据只向前传递,不会从后层反馈到前层(区别于 RNN、LSTM 等循环神经网络);

(3)非线性激活:隐藏层和输出层需加入激活函数(如 ReLU、Sigmoid),否则多层网络等价于单层线性模型。

  • 前馈神经网络的核心组成

用 “单隐藏层 FNN” 为例,结构如下:

(1) 输入层:接收原始数据,每个节点对应一个特征(如输入一张图片的像素,或一个样本的属性);

(2) 隐藏层:对输入特征进行 “线性变换(向量点积)+ 非线性激活”,提取高层特征(如从像素中提取边缘、纹理);

(3) 输出层:根据任务输出结果(分类任务用 Softmax 输出类别概率,回归任务直接输出连续值);

(4) 参数:包括各层的权重(Weight)和偏置(Bias),是模型需要通过训练优化的核心。

  • 前馈神经网络的训练流程

前馈神经网络的训练本质是 “最小化损失函数”,流程可分为 “前向传播” 和 “反向传播” 两步,循环迭代直到收敛:

(1) 前向传播:计算预测值与损失

  • 输入层:接收批量样本张量(如 (B, D),B 是批量数,D 是输入特征数);
  • 隐藏层:用 torch.matmul(x, w) + b 计算线性输出,再用激活函数(如 ReLU)引入非线性;
  • 输出层:计算预测值(如分类任务用 torch.softmax() 输出概率);
  • 损失计算:用损失函数(如分类用交叉熵 torch.nn.CrossEntropyLoss(),回归用 MSE torch.nn.MSELoss())计算预测值与真实标签的差距。

(2)反向传播:计算梯度并更新参数

  • 梯度计算:调用 loss.backward(),自动计算损失函数对所有可训练参数(权重、偏置)的梯度;
  • 参数更新:用优化器(如 SGD、Adam)根据梯度更新参数,公式为:参数 = 参数 - 学习率 × 梯度
  • 梯度清零:每次反向传播后需用 optimizer.zero_grad() 清零梯度,避免梯度累积。

PyTorch 实现简单前馈神经网络(代码示例)

用 PyTorch 的 torch.nn 模块可快速搭建前馈神经网络,无需手动实现向量运算和梯度计算:

import torch
import torch.nn as nn
import torch.optim as optim

# 1. 定义前馈神经网络模型
class SimpleFNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(SimpleFNN, self).__init__()
        # 隐藏层:线性变换 + ReLU 激活
        self.hidden = nn.Linear(input_dim, hidden_dim)
        self.relu = nn.ReLU()
        # 输出层:线性变换(分类任务后续加 Softmax)
        self.output = nn.Linear(hidden_dim, output_dim)
    
    def forward(self, x):
        # 前向传播流程
        x = self.hidden(x)
        x = self.relu(x)
        x = self.output(x)
        return x

# 2. 初始化模型、损失函数、优化器
input_dim = 3  # 输入特征数
hidden_dim = 2  # 隐藏层节点数
output_dim = 2  # 输出类别数(如二分类)

model = SimpleFNN(input_dim, hidden_dim, output_dim)
criterion = nn.CrossEntropyLoss()  # 分类任务损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)  # SGD 优化器

# 3. 模拟训练数据(批量数=2,输入特征数=3;真实标签=2个样本的类别)
x_train = torch.tensor([[0.5, 0.3, 0.2], [0.1, 0.4, 0.5]])
y_train = torch.tensor([0, 1])  # 真实标签(0类和1类)

# 4. 训练迭代(1次迭代)
optimizer.zero_grad()  # 梯度清零
y_pred = model(x_train)  # 前向传播:计算预测值
loss = criterion(y_pred, y_train

总结

本文围绕神经网络底层数学概念展开,解析了张量作为数据容器的核心作用,阐述导数、微分与优化的关联,详解向量运算在并行计算中的关键地位,还介绍了前馈神经网络的结构与训练流程。这些概念是理解神经网络和大模型的基础,结合PyTorch实践可加深掌握。