基础代码实操和自动求导)
一、环境搭建AnacondaVSCPyTorch。VSC我已经有了只需安装插件这就不详说了。组件推荐版本/类型必装/选装核心作用Anaconda2025.03 或更高(Python 3.12)必装包管理器 虚拟环境隔离Visual Studio Code最新稳定版(v1.90)已装代码编辑器VSC 插件 - Python最新版(ms-python.python)必装语法高亮、调试、环境识别VSC 插件 - Pylance最新版(ms-python.vscode-pylance)必装类型检查与智能提示依赖Python插件PyTorch2.5.1 或 2.6.0(稳定版)必装深度学习框架1.Anacondahttps://repo.anaconda.com/archive/Anaconda3-2025.12-1-Windows-x86_64.exeAnaconda是一个Python/R 数据科学发行版简单说它是一个打包好的 Python 环境 大量预装的数据科学工具包。2.PyTorch深度学习框架做深度学习 / AI 项目的。用于构建和训练神经网络由 MetaFacebook开发广泛应用于计算机视觉、NLP、强化学习等用 Anaconda安装 PyTorch 特别方便如果你是 NVIDIA 显卡用户GPU 版conda会自动检测你的驱动并匹配兼容的 CUDA 版本。conda install pytorch torchvision torchaudio -c conda-forge如果你没有 NVIDIA 显卡CPU 版conda install pytorch torchvision torchaudio cpuonly -c conda-forge// 创建专属环境 conda create -n pytorch_env python3.12 conda activate pytorch_env3.VSC在vsc中开发运行时记得切pytorch_env二、PyTorch基础1.基本操作1.1 数学运算1创建张量方法说明示例torch.tensor(data)从 Python 数据创建torch.tensor([1, 2, 3])torch.zeros(shape)全0张量torch.zeros(2, 3)torch.ones(shape)全1张量torch.ones(2, 3)torch.rand(shape)均匀分布 [0,1)torch.rand(2, 3)torch.randn(shape)标准正态分布torch.randn(2, 3)torch.randint(low, high, shape)随机整数 [low, high)torch.randint(1, 10, (2, 3))torch.arange(start, end, step)等差数列torch.arange(0, 10, 2)torch.linspace(start, end, steps)等间隔数列torch.linspace(0, 1, 5)torch.eye(n)单位矩阵torch.eye(3)torch.empty(shape)未初始化内存垃圾值torch.empty(2, 3)import torch # 1.创建张量。创建张量可以里理解为声明变量、张量与python普通变量的区别张量可以在GPU运行速度翻倍能用来计算梯度可以直接批量计算。 #随机int,生成一个 2行3列 的张量,每个元素是在 [1, 10) 范围内的随机整数即 1 到 9,manual_seed(42) 保证每次运行结果一样 torch.manual_seed(42) atorch.randint(1,10,(2,3),dtypetorch.int8) print(a) # 随机0-1均匀分布:生成一个 2行3列 的张量,每个元素是在 [0, 1) 区间内的随机浮点数均匀分布,manual_seed(42) 保证每次运行结果一样 torch.manual_seed(42) btorch.rand((2,3),dtypetorch.float16) print(b) # 把张量 bfloat16 类型转换为 NumPy 数组 b.numpy() print(b.numpy()) # 创建一个标量张量0维张量数值是 1数据类型是 int16 ctorch.tensor(1,dtypetorch.int16) # 创建一个标量张量数值是 1.0数据类型是 float32 dtorch.tensor(1.0,dtypetorch.float32) # 专门用于标量张量只有一个元素的张量把它转换成 Python 原生数值类型 d.item() print(d.item()) # 多元素用 tolist() y torch.tensor([1, 2, 3]) print(y.tolist()) # [1, 2, 3] # 从 Python 列表创建张量 e torch.tensor([1, 2, 3, 4]) # 查看形状、数据类型 print(e.shape) # torch.Size([4]) print(e.dtype) # torch.int64默认 # 改变形状 f e.reshape(2, 2) print(f) # tensor([[1, 2], [3, 4]])张量属性属性说明示例.shape张量形状元组t.shape→torch.Size([2, 3]).size()同.shapet.size()→torch.Size([2, 3]).dtype数据类型t.dtype→torch.float32.device所在设备CPU/GPUt.device→device(typecpu).ndim维度数量t.ndim→2.numel()元素总数t.numel()→6.requires_grad是否需要梯度t.requires_grad→True/False张量数据类型类型用途内存占用torch.float32深度学习默认绝大多数场景深度学习标准4字节torch.float16省显存、加速混合精度训练GPU 加速省显存2字节torch.int64索引、标签8字节torch.int32节省内存的整数4字节torch.int8极省内存量化模型1字节torch.bool条件判断、掩码1字节精度规则类型提升低精度 → 高精度 int16 float32 → float32 # 自动提升 int8 int32 → int32 # 自动提升PyTorch 在处理不同类型张量的运算时会遵循类型提升规则低精度类型会自动提升为高精度类型避免数据丢失。2对比普通变量与张量对比维度普通 Python 变量PyTorch 张量本质Python 对象的引用指向内存中的整数、字符串、列表等一个连续内存块存储大量同类型数值类似数组能装什么任意类型int, float, str, list, dict, 自定义对象...只能是数值int, float且所有元素类型必须一致计算方式解释器逐行执行循环慢向量化运算底层 C/CUDA 实现极快硬件支持只能 CPU✅ CPU GPU.to(cuda)自动求导❌ 不支持✅ 支持requires_gradTrue存储结构分散在堆内存中元素可能不连续连续内存块访问效率高典型用途逻辑控制、字符串处理、数据结构存储数值计算、深度学习、科学计算3使用场景场景用谁为什么存放图片、音频、文本向量张量数据量大需要 GPU 加速和批量运算神经网络权重和偏置张量需要自动求导来更新记录训练日志loss、acc普通变量就是单个数字不需要张量的超能力字符串处理、文件路径普通变量张量不支持字符串简单的数学计算ab都可以少量数据用普通变量即可杀鸡不用牛刀大量数据排序、统计张量或 NumPy向量化操作快得多4代数运算运算运算符函数是否支持广播说明加法torch.add(a, b)✅ 支持对应元素相加减法-torch.sub(a, b)✅ 支持对应元素相减乘法逐元素*torch.mul(a, b)✅ 支持对应元素相乘哈达玛积除法/torch.div(a, b)✅ 支持对应元素相除幂运算**torch.pow(a, b)✅ 支持a 的 b 次方取负-torch.neg(a)N/A取每个元素的相反数绝对值-torch.abs(a)N/A取每个元素的绝对值平方根-torch.sqrt(a)N/A取每个元素的平方根指数-torch.exp(a)N/Ae 的 a 次方自然对数-torch.log(a)N/Aln(a)取整-torch.floor(a)torch.ceil(a)torch.round(a)N/A向下/向上/四舍五入取整取余%torch.remainder(a, b)✅ 支持a 除以 b 的余数大部分逐元素运算如加减乘除确实要求形状完全一致但 PyTorch 有一个“外挂”叫“广播机制Broadcasting”可以在特定条件下让形状不同的张量也能运算广播从最后一个维度开始往前比较两个张量的形状必须满足以下条件之一维度大小相等比如都是 3其中一个维度大小是 1可以被拉伸其中一个张量缺少这个维度视为 1import torch A torch.tensor([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3) B torch.tensor([10, 20, 30]) # 形状 (3,) C A B print(C)[[110, 220, 330], → [[11, 22, 33], [410, 520, 630]] [14, 25, 36]]如果两个张量在某个维度上既不相等也没有 1就无法广播直接报错。6向量/矩阵运算运算运算符函数形状要求说明向量点积内积-torch.dot(a, b)两者都是 1D且长度相同对应元素相乘再求和 → 标量矩阵乘法2Dtorch.mm(a, b)a: (m×n), b: (n×p)标准矩阵乘法 → (m×p)批量矩阵乘法3Dtorch.bmm(a, b)a: (b×n×m), b: (b×m×p)批量矩阵乘法 → (b×n×p)通用矩阵乘法任意维度torch.matmul(a, b)自动适配最推荐自动处理各种维度向量×矩阵torch.matmul(a, b)a: (n,), b: (n, m)→ (m,)矩阵×向量torch.matmul(a, b)a: (m, n), b: (n,)→ (m,)外积-torch.outer(a, b)两者都是 1Da 和 b 的外积 → (len(a), len(b))矩阵转置.Ttorch.transpose(a, 0, 1)2D行列互换矩阵求逆-torch.inverse(a)方阵 (n×n)矩阵的逆矩阵行列式-torch.det(a)方阵 (n×n)计算行列式标量特征值/特征向量-torch.linalg.eig(a)方阵 (n×n)计算特征值和特征向量1.2 元素选取重要方式示例返回类型是否共享内存修改是否影响原张量整数索引a[2, 3]标量或降维张量❌ 复制❌ 不会整数张量索引花式索引a[[2, 3], [1, 2]]新张量形状同索引形状❌ 复制❌ 不会切片a[1:4, 2:5]视图View✅共享✅会切片 整数索引混合a[1:4, 2]视图View✅共享✅会切片 花式索引混合a[1:4, [1, 2]]可能复制⚠️ 不保证视图❌ 不保证❌ 可能不会clone()a[1:4].clone()独立副本❌ 不共享❌ 不会索引torch.manual_seed(42) atorch.randint(1,10,(4,4),dtypetorch.int8) # tensor([[7, 6, 8, 5], # [1, 3, 8, 6], # [5, 3, 5, 5], # [9, 1, 1, 5]], dtypetorch.int8) ixa[[2,3],[2]] # [2,3]指2行3行 [2]指2列索引从0开始计 print(ix) #tensor([5, 1], dtypetorch.int8) ix[1]8 #当前只有索引 0 和 1 print(a) # a是不变的哈切片# 切片 # atensor([[7, 6, 8, 5], # [1, 3, 8, 6], # [5, 3, 5, 5], # [9, 1, 1, 5]], dtypetorch.int8) slicea[:2,:3] #取前两行索引 0 和 1和前 3 列索引 012 slice[0][2]12 #修改值 print(a) #原张量a发生变化了 tensor([[ 7, 6, 12, 5], # [ 1, 3, 8, 6], # [ 5, 3, 5, 5], # [ 9, 1, 1, 5]], dtypetorch.int8)假设张量a是列0 列1 列2 列3 行0 1 2 3 4 行1 5 6 7 8 ← 前两行行0行1 行2 9 10 11 12 ↑ ↑ 前3列 第4列不取 (列0,1,2)执行slice a[:2, :3]后slice得到的是绿色框里的部分slice [[1, 2, 3], ← 行0列0-2 [5, 6, 7]] ← 行1列0-2:单独使用 全部取:n从开头取到第 n-1 个前 n 个m:n从第 m 个取到第 n-1 个m:从第 m 个取到最后::k步长为 k本质上都是mnk上面的写法是省略的写法m起始索引包含n结束索引不包含k步长默认为 1参数步长为正step 0步长为负step 0start默认值0开头-1末尾即最后一个元素stop默认值张量长度末尾之后负的 张量长度 减 1开头之前取值方向从左到右正向从右到左反向克隆# 克隆clone后是新副本 torch.manual_seed(42) qtorch.rand((2,3),dtypetorch.float16) # tensor([[0.8823, 0.9150, 0.3828], # [0.9595, 0.3904, 0.6011]], dtypetorch.float16) slice1q[:2,:1].clone() print(slice1) # tensor([[0.8823], # [0.9595]], dtypetorch.float16) slice1[1][0]12 #修改值 print(q) # tensor([[0.8823, 0.9150, 0.3828], # [0.9595, 0.3904, 0.6011]], dtypetorch.float16)极值# qtensor([[0.8823, 0.9150, 0.3828], # [0.9595, 0.3904, 0.6011]], dtypetorch.float16) print(q.max()) #全局最大值 #tensor(0.9595, dtypetorch.float16) print(q.min()) #全局最小值 #tensor(0.3828, dtypetorch.float16) print(q.max(0)) #每列最大值 等价q.max(dim0) # torch.return_types.max( # valuestensor([0.9595, 0.9150, 0.6011], dtypetorch.float16), # indicestensor([1, 0, 1])) print(q.min(1)) #行最小值等价q.max(dim1) # valuestensor([0.3828, 0.3904], dtypetorch.float16), # indicestensor([2, 1]))张量 q (2行 × 3列): 列0 列1 列2 行0 0.8823 0.9150 0.3828 ← 行0的最小值在列2 (0.3828) 行1 0.9595 0.3904 0.6011 ← 行1的最小值在列1 (0.3904) ↑ ↑ ↑ 列0最大 列1最大 列2最大 在行1 在行0 在行1 (0.9595) (0.9150) (0.6011)1.3 元素修改步骤操作类别PyTorch函数/方法说明代码示例调整shape改变形状torch.reshape()/tensor.view()返回新的形状视图view要求内存连续x torch.randn(4, 6)y x.view(3, 8)z x.reshape(2, 12)压缩/扩展维度torch.squeeze()/torch.unsqueeze()删除/增加大小为1的维度x torch.randn(1, 3, 1, 5)y x.squeeze()# (3,5)z x.unsqueeze(0)# (1,1,3,1,5)转置交换维度torch.transpose()/tensor.permute()交换指定维度 / 按新顺序重排维度x torch.randn(2, 3, 4)y x.transpose(0, 1)# (3,2,4)z x.permute(2, 0, 1)# (4,2,3)展平torch.flatten()将指定维度展平为一维x torch.randn(2, 3, 4)y x.flatten(start_dim1)# (2,12)调整类型数据类型转换tensor.to(dtype)/tensor.type()改变张量的数据类型x torch.tensor([1, 2])y x.to(torch.float32)z x.type(torch.float64)设备转换tensor.to(device)在CPU/GPU之间移动张量x torch.randn(3,4)y x.to(cuda)z x.to(cpu)调整维度增加新维度torch.unsqueeze()在指定位置插入大小为1的新维度同上面同上 unsqueeze删除维度大小为1torch.squeeze()删除所有或指定大小为1的维度同上面同上 squeeze维度重排torch.permute()/tensor.transpose()任意交换维度顺序 / 交换两个维度同上同上 permute / transpose拆分按块拆分torch.chunk()将张量沿指定维度均匀拆分为多个块x torch.randn(4, 8)chunks x.chunk(2, dim1)# 两个 (4,4)按大小拆分torch.split()沿指定维度按指定大小或列表拆分x torch.randn(4, 8)splits x.split([3, 5], dim1)# (4,3), (4,5)按索引拆分torch.index_select()按索引选择特定行/列非严格拆分但常用x torch.randn(4, 8)indices torch.tensor([0, 2])y x.index_select(0, indices)# (2,8)合并拼接torch.cat()沿已有维度拼接不增加维度a torch.randn(2,3)b torch.randn(2,3)c torch.cat([a,b], dim0)# (4,3)堆叠torch.stack()沿新维度堆叠增加维度a torch.randn(2,3)b torch.randn(2,3)c torch.stack([a,b], dim0)# (2,2,3)2.自动求导在训练神经网络时我们需要不断调整参数权重和偏置让模型的预测结果越来越准。怎么调整→ 使用梯度下降Gradient Descent梯度是什么→ 梯度是损失函数对参数的偏导数它指出了参数应该“往哪个方向调”能让损失下降得最快。求梯度需要计算导数神经网络动辄百万、千万级别的参数手动求导根本不现实。于是PyTorch提供了自动求导Autograd机制你只需要定义好前向计算输入→输出PyTorch会自动帮你算出所有参数的梯度。1数学公式理解2训练过程┌─────────────────────────────────────────────────────┐ │ 训练过程 │ │ │ │ ① 提前准备好样本 ② 随机初始化 ③ 计算误差 │ │ (x, y) θ 组 → h(x) - y │ │ (固定不变) (动态值) (判断差多少) │ │ ↑ │ │ │ │ │ ⑤ 更新 θ 组 ←──────────④ 梯度下降 │ │ (动态调整) (根据误差方向调整) │ │ │ │ │ ⑥ 重复 ①~⑤ 很多次... │ │ ↓ │ │ ⑦ 最终 θ 组固定下来收敛模型训练完成 │ └─────────────────────────────────────────────────────┘(x, y)样本值(x, y)样本值就是训练集Training Set。作用它们是“标准答案”或“老师”。在训练开始前这些数据已经收集好了比如过去一年的房价、猫狗的图片标签。模型最终学得好不好就是看预测出来的 h(x) 跟这些提前准备好的 y 像不像。θ 组参数θ 组参数叫模型的权重Weights或参数Parameters。作用它们就像是一块橡皮泥或者是收音机上的调频旋钮。一开始它们是随机的比如全是0或者随机小数。在训练过程中它们会动态地、一步一步地通过梯度下降发生变化。最终它们会固定下来变成一组最优的值。这时候模型就“训练好了”。梯度下降假设损失函数是 J(θ)θ^2一个简单的抛物线我们想找到使 J 最小的 θ。手动计算过程步骤θθ 值梯度 J′(θ)2θJ′(θ)2θ更新α0.1α0.1新 θθ初始10.020.010−0.1×208.08.0第2步8.016.08−0.1×166.46.4第3步6.412.86.4−0.1×12.85.125.12...............第N步≈ 0≈ 0趋近0≈ 0代入到“房价预测”场景假设我们要预测房价提前准备的样本 (x, y)x面积80㎡100㎡120㎡y真实房价200万250万300万θ 组动态调整的参数假设模型是一开始θ00,θ11,预测 80㎡ 只有 80万离谱误差巨大。训练中通过梯度下降θ1 从 1 慢慢变成 2.5θ0 从 0 慢慢变成 0。最终θ00,θ12.5。模型变成 h(x)2.5x。预测 80㎡ 得出 200万完美匹配3PyTorch# 自动求导 # 1.第一个参数1.0data:传入 1.0Python 浮点数→ 创建一个 0 维标量张量值为 1.0dtype 默认是 torch.float32。也可以传列表、嵌套列表来创建向量/矩阵 # 2.requires_gradTrue:表示这个张量是否需要被追踪梯度,只有浮点张量才能设 requires_gradTrue xtorch.tensor(2.0,requires_gradTrue) yx**23*x1 y.backward() print(x , x.item()) # x 2.0 print(y , y.item()) # y 11.0 print(dy/dx , x.grad.item()) #dy/dx 7.0 # 向量 x1torch.tensor([1.0,2.9,3.5],requires_gradTrue) wtorch.tensor([3.0,5.1,4.5],requires_gradTrue) btorch.tensor([3.0,6.0,3.0],requires_gradTrue) yw*x1b # backward() 要求标量 y.sum().backward() print(dy/dx , x1.grad) # dy/dx tensor([3.0000, 5.1000, 4.5000]) print(dy/dw , w.grad) # dy/dw tensor([1.0000, 2.9000, 3.5000]) print(dy/db , b.grad) # dy/db tensor([1., 1., 1.])3.其他框架分类工具名称所属公司 / 组织流行程度与现状基本操作层PyTorchMeta (Facebook)极流行AI顶会论文中占比达80%是当前研究与开发的主流框架。TensorFlowGoogle流行市场占有率约37.5%是企业级生产部署的重要选择。MXNetApache 基金会已淘汰曾由AWS支持但官方已停止维护不建议在新项目中使用。集成、优化层KerasGoogle流行TensorFlow官方高层API用户友好适合快速搭建原型。PyTorch LightningGrid.ai (社区项目)流行为PyTorch提供轻量级封装将工程代码与科学逻辑分离便于大规模训练。FastAIfast.ai (社区项目)小众但口碑好在PyTorch之上构建以极少的代码实现高质量基线在教育领域很受欢迎。模型应用层TransformersHugging Face极流行提供数千个预训练模型的统一接口GitHub星标超16万是NLP和基础模型时代的标准。ModelScope (魔搭)阿里巴巴达摩院国内流行国内最大的开源模型社区之一提供模型体验、训练、部署一站式服务。Paddle系列 (飞桨)百度特定领域流行中国首个自主研发的产业级深度学习平台在中文NLP、OCR等场景有独特优势。做研究或跟踪前沿模型PyTorchTransformers是当前最常见的组合。面向企业生产部署TensorFlow/Keras或PaddlePaddle在工程化方面有成熟的工具链。快速验证想法或做教学演示FastAI和Keras的上手成本会低很多。国内中文场景ModelScope和Paddle系列的本土化支持会更有优势。如果下次有人给你推荐一个新的 AI 框架你可以用这张图里的四个维度问自己接口友好吗我大概要花多久才能写个 Demo 出来定位匹配吗它是适合做研究快速试错还是适合明天上线给客户用性能可迭代吗如果未来数据量涨 10 倍这个框架有现成的优化方案吗社区有活人吗遇到问题我能多快找到答案或源码有人理你吗