当前位置: 首页 > news >正文

《零基础入门AI:深度学习入门(从PyTorch安装到自动微分)》

一、PyTorch安装与环境配置

PyTorch是由Facebook AI Research开发的深度学习框架,以其动态计算图Pythonic设计而广受欢迎。安装前需确认:

  1. 系统要求

    • 支持Windows/Linux/macOS
    • Python 3.7+(推荐3.8+)
    • 可选NVIDIA GPU(需安装CUDA)
  2. 安装步骤

    1. 访问PyTorch官网
    2. 选择配置(操作系统、包管理器、Python版本、CUDA版本)
    3. 执行安装命令(无GPU示例):
    pip install torch torchvision torchaudio
    
  3. 验证安装

    import torch
    print(torch.__version__)        # 查看版本(如2.1.0)
    print(torch.cuda.is_available()) # 检查GPU支持(返回True/False)
    

常见问题:若安装失败,尝试使用Python虚拟环境或检查pip版本。GPU用户需确保CUDA版本与PyTorch要求匹配。


二、认识人工智能

1. 人工智能(AI)是什么?

AI : 人工智能是使机器模拟人类智能行为**的科学与技术。核心是通过算法让计算机:

  • 感知环境(如摄像头识别物体)
  • 学习知识(如从数据中发现规律)
  • 做出决策(如自动驾驶车辆转弯)

AI本质

  1. 本质是数学计算
  2. 数学是理论关键
  3. 计算机是实现关键:算力
  4. 新的有效算法,需要更大的算力
2. AI实现过程

三要素:数据、网络、算力

① 神经网络:找到合适的数学公式;

② 训练:用已有数据训练网络,目标是求最优解;

③ 推理:用模型预测新样本;

示例:图像识别

数据收集
10万张猫狗图片
模型构建
卷积神经网络
训练
调整参数降低错误率
评估
新图片识别准确率95%
3. 术语关系图
人工智能(AI)
├─ 机器学习(ML) - 让计算机从数据中学习
│   └─ 深度学习(DL) - 使用多层神经网络
├─ 计算机视觉(CV) - 图像/视频理解
└─ 自然语言处理(NLP) - 语言理解与生成
4. AI产业大生态
  • 基础层:硬件(GPU/TPU芯片)、云计算平台
  • 技术层:框架(PyTorch/TensorFlow)、算法模型
  • 应用层:智能医疗、自动驾驶、智能客服

三、初识PyTorch

PyTorch是一个基于Python的深度学习框架,它提供了一种灵活、高效、易于学习的方式来实现深度学习模型。PyTorch最初由Facebook开发,被广泛应用于计算机视觉、自然语言处理、语音识别等领域。

PyTorch使用张量(tensor)来表示数据,可以轻松地处理大规模数据集,且可以在GPU上加速。

PyTorch提供了许多高级功能,如**自动微分(automatic differentiation)、自动求导(automatic gradients)**等,这些功能可以帮助我们更好地理解模型的训练过程,并提高模型训练效率。

PyTorch三大核心优势:
  1. 动态计算图(Define-by-Run)

    • 传统框架(如TensorFlow)需先定义静态计算图
    • PyTorch在执行时动态构建计算图
    • 优势:更灵活调试,支持Python控制流
  2. Python原生体验

    • 与NumPy相似的API设计
    • 无缝集成Python科学生态(Pandas/Matplotlib)
  3. 丰富的工具链

    • TorchVision:图像处理
    • TorchText:文本处理
    • TorchAudio:音频处理
主流深度学习框架对比:
框架特点适用场景
PyTorch动态图,易调试研究、原型开发
TensorFlow静态图,部署成熟工业级部署
Keras高层API,上手简单快速原型设计

四、Tensor概述

PyTorch会将数据封装成张量(Tensor)进行计算,所谓张量就是元素为相同类型的多维矩阵。

张量可以在 GPU 上加速运行。

1. 什么是Tensor?

Tensor是多维数组的泛化形式:

  • 0维:标量(Scalar) → 温度值 25.3
  • 1维:向量(Vector) → [1.2, 3.4, 5.6]
  • 2维:矩阵(Matrix) → 图片像素矩阵
  • 3维+:高阶张量 → 视频数据(宽×高×时间×通道)
2. Tensor核心特点
  • 统一数据容器:所有深度学习数据(图像/文本/音频)最终都转为Tensor
  • 自动微分支持:记录操作历史用于梯度计算
  • 硬件加速:可无缝切换CPU/GPU计算
  • 动态计算图:PyTorch 支持动态计算图,这意味着在每一次前向传播时,计算图是即时创建的。
3. 常见数据类型(dtype)
类型说明示例
torch.float3232位浮点数(最常用)0.12345
torch.int6464位整数42
torch.bool布尔值True

为什么数据类型重要? 不同操作对数据类型敏感,错误类型会导致计算失败或精度损失。


五、Tensor创建:四种核心方法

1. 基础创建
import torch# 从Python列表创建 (自动推断类型)
t1 = torch.tensor([[1, 2], [3, 4]])# 显式指定类型(重要!)
labels = torch.tensor([0, 1], dtype=torch.int64)# :创建特殊值张量
zeros = torch.zeros(2, 3)  # 2×3全零矩阵
ones = torch.ones(3)       # 长度为3的全1向量
2. 函数生成法(预定义模式)
# 单位矩阵(恒等变换)
I = torch.eye(3)  # [[1,0,0],[0,1,0],[0,0,1]]# 对角矩阵(特征值)
D = torch.diag(torch.tensor([1, 2, 3]))
3. 序列张量
# 等差数列:start=0, end=10, step=2
range_tensor = torch.arange(0, 10, 2)  # [0,2,4,6,8]# 线性间隔:start=0, end=1, 分成5份
linspace_tensor = torch.linspace(0, 1, 5)  # [0.0, 0.25, 0.5, 0.75, 1.0]
4. 随机张量(重要!)
# 均匀分布:[0,1)区间
rand_tensor = torch.rand(2, 2)  # 标准正态分布(均值μ,标准差σ):均值0,标准差1 
randn_tensor = torch.randn(3)  # 特定范围整数:[low, high)
randint_tensor = torch.randint(1, 10, (3,))  # 3个1-9的随机整数# 均匀分布(区间[a,b])
biases = torch.FloatTensor(50).uniform_(-0.1, 0.1)# 特殊初始化(Xavier方法)
torch.nn.init.xavier_uniform_(weights)

随机种子的作用torch.manual_seed(42)确保每次生成相同随机数,保证实验可复现


六、Tensor常见属性

1. 关键属性获取
x = torch.rand(2, 3, dtype=torch.float32)print(x.shape)      # 形状:torch.Size([2, 3])
print(x.dtype)      # 数据类型:torch.float32
print(x.device)     # 存储位置:cpu 或 cuda:0
print(x.requires_grad) # 是否需梯度计算:False
2. 设备切换(CPU ↔ GPU)
# 检查GPU可用性
if torch.cuda.is_available():device = torch.device("cuda")y = x.to(device)  # 转移到GPUz = y.cpu()       # 转回CPU
3. 类型转换(重要!)
# 显式转换
a = torch.tensor([1.5, 2.7])
b = a.int()       # 转为整数 → [1, 2](截断小数)
c = a.float()     # 转为单精度浮点# 自动转换(操作中混合类型时)
d = a + torch.tensor(3)  # float + int → float

七、Tensor与NumPy互操作

1.张量转Numpy
  • 浅拷贝

调用numpy()方法可以把Tensor转换为Numpy,此时内存是共享的。

import torchdef test003():# 1. 张量转numpydata_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])data_numpy = data_tensor.numpy()print(type(data_tensor), type(data_numpy))# 2. 他们内存是共享的data_numpy[0, 0] = 100print(data_tensor, data_numpy)if __name__ == "__main__":test003()
  • 深拷贝

使用copy()方法可以避免内存共享:

import torchdef test003():# 1. 张量转numpydata_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])# 2. 使用copy()避免内存共享data_numpy = data_tensor.numpy().copy()print(type(data_tensor), type(data_numpy))# 3. 此时他们内存是不共享的data_numpy[0, 0] = 100print(data_tensor, data_numpy)if __name__ == "__main__":test003()
2.Numpy转张量

也可以分为内存共享和不共享

  • 浅拷贝

from_numpy方法转Tensor默认是内存共享的

import numpy as np
import torchdef test006():# 1. numpy转张量data_numpy = np.array([[1, 2, 3], [4, 5, 6]])data_tensor = torch.from_numpy(data_numpy)print(type(data_tensor), type(data_numpy))# 2. 他们内存是共享的data_tensor[0, 0] = 100print(data_tensor, data_numpy)if __name__ == "__main__":test006()
  • 深拷贝

使用传统的torch.tensor()则内存是不共享的~

import numpy as np
import torchdef test006():# 1. numpy转张量data_numpy = np.array([[1, 2, 3], [4, 5, 6]])data_tensor = torch.tensor(data_numpy)print(type(data_tensor), type(data_numpy))# 2. 内存是不共享的data_tensor[0, 0] = 100print(data_tensor, data_numpy)if __name__ == "__main__":test006()

为什么需要转换? NumPy在数据预处理中更高效,而Tensor是深度学习计算的标准格式。


八、Tensor常见操作

1.获取元素值

我们可以把单个元素tensor转换为Python数值,这是非常常用的操作

import torchdef test002():data = torch.tensor([18])print(data.item())passif __name__ == "__main__":test002()

注意:

  • 和Tensor的维度没有关系,都可以取出来!

  • 如果有多个元素则报错

  • 仅适用于CPU张量,如果张量在GPU上,需先移动到CPU

  • gpu_tensor = torch.tensor([1.0], device='cuda')
    value = gpu_tensor.cpu().item()  # 先转CPU再提取
    
2. 元素值运算

常见的加减乘除次方取反开方等各种操作,带有_的方法则会替换原始值。

import torchdef test001():# 生成范围 [0, 10) 的 2x3 随机整数张量data = torch.randint(0, 10, (2, 3))print(data)# 元素级别的加减乘除:不修改原始值print(data.add(1))print(data.sub(1))print(data.mul(2))print(data.div(3))print(data.pow(2))# 元素级别的加减乘除:修改原始值data = data.float()data.add_(1)data.sub_(1)data.mul_(2)data.div_(3.0)data.pow_(2)print(data)if __name__ == "__main__":test001()
3. 阿达玛积

阿达玛积是指两个形状相同的矩阵或张量对应位置的元素相乘。它与矩阵乘法不同,矩阵乘法是线性代数中的标准乘法,而阿达玛积是逐元素操作。假设有两个形状相同的矩阵 A和 B,它们的阿达玛积 C=A∘B定义为:
Cij=Aij×BijC_{ij}=A_{ij}×B_{ij} Cij=Aij×Bij
其中:

  • Cij 是结果矩阵 C的第 i行第 j列的元素。
  • Aij和 Bij分别是矩阵 A和 B的第 i行第 j 列的元素。

在 PyTorch 中,可以使用mul函数或者*来实现;

import torchdef test001():data1 = torch.tensor([[1, 2, 3], [4, 5, 6]])data2 = torch.tensor([[2, 3, 4], [2, 2, 3]])print(data1 * data2)def test002():data1 = torch.tensor([[1, 2, 3], [4, 5, 6]])data2 = torch.tensor([[2, 3, 4], [2, 2, 3]])print(data1.mul(data2))if __name__ == "__main__":test001()test002()
4. Tensor相乘

矩阵乘法是线性代数中的一种基本运算,用于将两个矩阵相乘,生成一个新的矩阵。

假设有两个矩阵:

  • 矩阵 A的形状为 m×n(m行 n列)。
  • 矩阵 B的形状为 n×p(n行 p列)。

矩阵 A和 B的乘积 C=A×B是一个形状为 m×p的矩阵,其中 C的每个元素 Cij,计算 A的第 i行与 B的第 j列的点积。计算公式为:
Cij=∑k=1nAik×BkjC_{ij}=∑_{k=1}^nA_{ik}×B_{kj} Cij=k=1nAik×Bkj

矩阵乘法运算要求如果第一个矩阵的shape是 (N, M),那么第二个矩阵 shape必须是 (M, P),最后两个矩阵点积运算的shape为 (N, P)。

在 PyTorch 中,使用@或者matmul完成Tensor的乘法。

import torchdef test006():data1 = torch.tensor([[1, 2, 3], [4, 5, 6]])data2 = torch.tensor([[3, 2], [2, 3], [5, 3]])print(data1 @ data2)print(data1.matmul(data2))if __name__ == "__main__":test006()
5. 元素访问与切片
x = torch.tensor([[1, 2, 3], [4, 5, 6]])# 单元素访问
print(x[0, 1])    # 第0行第1列 → 2# 切片(与Python语法一致)
row = x[1, :]     # 第1行 → [4,5,6]
col = x[:, 1]     # 第1列 → [2,5]
block = x[0:2, 1:3] # 子矩阵 [[2,3],[5,6]]
6. 数学运算
a = torch.tensor([1, 2])
b = torch.tensor([3, 4])# 逐元素运算
add = a + b   # [4, 6]
sub = a - b   # [-2, -2]
mul = a * b   # [3, 8](阿达玛积)
div = b / a   # [3.0, 2.0]# 矩阵乘法
mat_a = torch.tensor([[1, 2], [3, 4]])
mat_b = torch.tensor([[5, 6], [7, 8]])
matmul = mat_a @ mat_b  # [[19,22],[43,50]]
7. 形状操作
x = torch.rand(2, 3)# view:改变形状(元素总数不变)
y = x.view(3, 2)  # 2×3 → 3×2# unsqueeze:增加维度(常用于广播)
z = x.unsqueeze(0)  # [2,3] → [1,2,3]# squeeze:降低维度
torch.squeeze(input, dim=None)# transpose:维度交换
w = x.transpose(0, 1)  # 行变列 → [3,2]
8. 广播机制(Broadcasting)

当两个Tensor形状不同时,自动扩展小张量:

A = torch.ones(3, 2)  # 3×2
B = torch.tensor([1, 2])  # 形状(2,)# 广播过程:
#   B自动扩展为 [[1,2],
#              [1,2],
#              [1,2]]
C = A + B  # 结果形状(3,2)

广播规则:从后往前逐维比较,维度需相等或其中一个为1


九、自动微分

自动微分模块torch.autograd负责自动计算张量操作的梯度,具有自动求导功能。自动微分模块是构成神经网络训练的必要模块,可以实现网络权重参数的更新,使得反向传播算法的实现变得简单而高效。

核心

  • 计算图(Computational Graph):记录Tensor操作的有向无环图
  • 梯度(Gradient):函数输出相对于输入的变化率
  • 反向传播(Backpropagation):从输出到输入逐层计算梯度
1. 基础概念

张量

Torch中一切皆为张量,属性requires_grad决定是否对其进行梯度计算。默认是 False,如需计算梯度则设置为True。

计算图

torch.autograd通过创建一个动态计算图来跟踪张量的操作,每个张量是计算图中的一个节点,节点之间的操作构成图的边。

在 PyTorch 中,当张量的 requires_grad=True 时,PyTorch 会自动跟踪与该张量相关的所有操作,并构建计算图。每个操作都会生成一个新的张量,并记录其依赖关系。当设置为 True 时,表示该张量在计算图中需要参与梯度计算,即在反向传播(Backpropagation)过程中会自动计算其梯度;当设置为 False 时,不会计算梯度。

例如:
z=x∗yloss=z.sum()z = x * y\\loss = z.sum() z=xyloss=z.sum()
在上述代码中,x 和 y 是输入张量,即叶子节点,z 是中间结果,loss 是最终输出。每一步操作都会记录依赖关系:

z = x * y:z 依赖于 x 和 y。

loss = z.sum():loss 依赖于 z。

这些依赖关系形成了一个动态计算图,如下所示:

	  x       y\     /\   /\ /z||vloss

叶子节点

在 PyTorch 的自动微分机制中,叶子节点(leaf node) 是计算图中:

  • 由用户直接创建的张量,并且它的 requires_grad=True。
  • 这些张量是计算图的起始点,通常作为模型参数或输入变量。

特征:

  • 没有由其他张量通过操作生成。
  • 如果参与了计算,其梯度会存储在 leaf_tensor.grad 中。
  • 默认情况下,叶子节点的梯度不会自动清零,需要显式调用 optimizer.zero_grad() 或 x.grad.zero_() 清除。

如何判断一个张量是否是叶子节点?

通过 tensor.is_leaf 属性,可以判断一个张量是否是叶子节点。

x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)  # 叶子节点
y = x ** 2  # 非叶子节点(通过计算生成)
z = y.sum()print(x.is_leaf)  # True
print(y.is_leaf)  # False
print(z.is_leaf)  # False

叶子节点与非叶子节点的区别

特性叶子节点非叶子节点
创建方式用户直接创建的张量通过其他张量的运算生成
is_leaf 属性TrueFalse
梯度存储梯度存储在 .grad 属性中梯度不会存储在 .grad,只能通过反向传播传递
是否参与计算图是计算图的起点是计算图的中间或终点
删除条件默认不会被删除在反向传播后,默认被释放(除非 retain_graph=True)

detach():张量 x 从计算图中分离出来,返回一个新的张量,与 x 共享数据,但不包含计算图(即不会追踪梯度)。

特点

  • 返回的张量是一个新的张量,与原始张量共享数据。
  • 对 x.detach() 的操作不会影响原始张量的梯度计算。
  • 推荐使用 detach(),因为它更安全,且在未来版本的 PyTorch 中可能会取代 data。
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x.detach()  # y 是一个新张量,不追踪梯度y += 1  # 修改 y 不会影响 x 的梯度计算
print(x)  # tensor([1., 2., 3.], requires_grad=True)
print(y)  # tensor([2., 3., 4.])

反向传播

使用tensor.backward()方法执行反向传播,从而计算张量的梯度。这个过程会自动计算每个张量对损失函数的梯度。例如:调用 loss.backward() 从输出节点 loss 开始,沿着计算图反向传播,计算每个节点的梯度。

梯度

计算得到的梯度通过tensor.grad访问,这些梯度用于优化模型参数,以最小化损失函数。

2. 梯度计算示例
# 步骤1:创建需追踪梯度的Tensor
x = torch.tensor(2.0, requires_grad=True)# 步骤2:构建计算图
y = x**2 + 3*x + 1  # y = x² + 3x + 1# 步骤3:反向传播计算梯度
y.backward()# 步骤4:获取梯度
print(x.grad)  # dy/dx = 2x + 3 = 2*2 + 3 = 7.0
3. 梯度上下文控制
# 禁止梯度跟踪(推理阶段使用)
with torch.no_grad():inference = x * 2  # 不记录计算图# 梯度清零(防止梯度累加)
x.grad.zero_()  # 下次backward前必须清零# 分离计算图(保留值但断开连接)
detached_y = y.detach()
4. 向量梯度计算
def test003():# 1. 创建张量:必须为浮点类型x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)# 2. 操作张量y = x ** 2# 3. 计算梯度,也就是反向传播y.backward()# 4. 读取梯度值print(x.grad)if __name__ == "__main__":test003()
5. 多向量梯度计算
import torchdef test004():# 创建两个张量,并设置 requires_grad=Truex = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)y = torch.tensor([4.0, 5.0, 6.0], requires_grad=True)# 前向传播:计算 z = x * yz = x * y# 前向传播:计算 loss = z.sum()loss = z.sum()# 查看前向传播的结果print("z:", z)  # 输出: tensor([ 4., 10., 18.], grad_fn=<MulBackward0>)print("loss:", loss)  # 输出: tensor(32., grad_fn=<SumBackward0>)# 反向传播:计算梯度loss.backward()# 查看梯度print("x.grad:", x.grad)  # 输出: tensor([4., 5., 6.])print("y.grad:", y.grad)  # 输出: tensor([1., 2., 3.])if __name__ == "__main__":test004()
6. 数学原理:链式法则

对于复合函数 z=f(g(x))z = f(g(x))z=f(g(x))
∂z∂x=∂z∂g⋅∂g∂x\frac{\partial z}{\partial x} = \frac{\partial z}{\partial g} \cdot \frac{\partial g}{\partial x}xz=gzxg

为什么需要梯度清零? 默认情况下梯度会累加,训练循环中需手动清零防止批次间干扰

http://www.dtcms.com/a/318544.html

相关文章:

  • Anthropic于本周一推出了其旗舰模型的升级版Claude Opus 4.1
  • 《第十三篇》深入解析 `kb_api.py`:知识库的创建、删除与查询接口
  • 基于Vue 3 的智能支付二维码弹窗组件设计与实现
  • Effective C++ 条款26: 尽可能延后变量定义式的出现时间
  • 007 前端( JavaScript HTML DOM+Echarts)
  • 【保留小数精度不舍入】2022-10-8
  • MaxKB 使用 MCP 连接 Oracle (免安装 cx_Oracle 和 Oracle Instant Client)
  • 智慧水务管理系统
  • C++、STL面试题总结(二)
  • 三、Envoy的管理接口
  • 数据科学与计算pandas
  • 沉寂半年,Kimi归来!
  • 地铁和城市宏基因组项目metaSUB
  • 脂质体转染、物理转染(电穿孔)与病毒转染:原理及操作步骤详解
  • nlp-词汇分析
  • 【Dify学习笔记】:Dify搭建表单信息提交系统
  • windows系统创建ubuntu系统
  • C++线程中 detach() 和 join() 的区别
  • hf的国内平替hf-mirror
  • AT32的freertos下modbus TCP移植
  • cdn是什么
  • 快手小店客服自动化回复
  • 记一次连接池泄漏导致的线上事故排查与修复
  • 从基础功能到自主决策, Agent 开发进阶路怎么走
  • 赋能智能制造,向成电子XC3576H/XC3588H工业主板引领AI工控新时代
  • 什么是RabbitMQ?
  • 基于单片机GD32E103的HID按键问题分析
  • 【网络运维】Linux:SELinux简介和配置
  • STM32U5 外部中断不响应问题分析
  • 【android bluetooth 协议分析 03】【蓝牙扫描详解 4】【BR/EDR扫描到设备后如何上报给app侧】