day22_深度学习与PyTorch入门一、深度学习概述1. 概念深度学习具体是什么呢一句话概括深度学习模仿人类大脑的运行方式依赖算法自动提取特征而不需要人工设计特征。传统机器学习需要人工设计特征并手动提取而深度学习把提取特征这事儿也交给了算法自己。这也是为什么深度学习经常被称为黑盒子——模型学到的特征是人眼难以直接理解的。深度学习擅长处理高维数据比如图像每个像素都是特征、文本每个词都是特征。2. 深度学习的优缺点优点精度高— 性能优于其他机器学习算法某些领域甚至超越了人类水平可以近似任意非线性函数— 随着硬件发展深层网络的表达能力越来越强生态丰富— 有大量的框架和开源库可供调用缺点黑箱问题— 很难解释模型到底是怎么做出判断的训练时间长— 需要大量的计算资源GPU、TPU等超参数多— 网络结构复杂需要调整的参数多容易过拟合— 在部分数据集上表现不佳需要正则化手段3. 深度学习发展史深度学习并非一夜爆红它经历了三个主要时期时期时间关键事件符号主义1950s-1970s1943年McCulloch-Pitts提出神经元模型1956年达特茅斯会议提出AI概念1957年Rosenblatt提出感知器1962年跳棋程序战胜人类统计主义1980s-20001986年BP算法成熟多层神经网络可训练1997年深蓝战胜卡斯帕罗夫1993年SVM提出神经网络与深度学习2006-至今2006年Hinton提出DBN开启深度学习复兴2012年AlexNet大幅赢得ImageNet比赛2016年AlphaGo战胜李世石2017年Transformer框架出现2018年BERT/GPT诞生2022年ChatGPT引爆AIGC浪潮2025年开启智能体时代关键转折点2012年AlexNet在ImageNet图像识别竞赛中以巨大优势夺冠这是深度学习爆发的标志性事件2017年Transformer的出现则彻底改变了NLP领域。4. 主流算法模型深度学习不是单一的算法而是一族方法下面是最主流的几种模型适用场景核心特点卷积神经网络CNN图像识别、视频分析、医学影像擅长处理带有空间关系的数据通过卷积核提取局部特征循环神经网络RNN/LSTM/GRU语音识别、音乐生成、NLP处理序列数据中的时间动态性有记忆能力Transformer复杂语言理解与生成BERT、GPT系列的基础用自注意力机制替代循环结构自编码器Autoencoder数据降维、去噪、异常检测通过编码-解码结构学习数据的压缩表示生成对抗网络GAN图像生成、艺术创作、数据增强生成器与判别器互相博弈生成逼真数据二、主流深度学习框架1. 四大框架对比目前最主流的深度学习框架有以下四个框架出生地特点适合谁TensorFlowGoogle计算图架构、分布式训练强、底层C构建速度快、生态强大但学术圈已式微做工程/部署的小伙伴PyTorchMeta原Facebook⭐动态图、代码量少、入门爽、学术界霸主几乎所有顶会论文代码都用它写想做学术的绝对首选PaddlePaddle飞桨百度动态图/静态图都支持、部署方便、有专门平台和工具包算力有限或想用国产框架的ONNX多家大厂联合并不是训练框架而是一种中间格式用于模型格式转换Pytorch→ONNX→其他不用刻意学用到再看一句话总结做学术搞研究选PyTorch做工程部署选TensorFlow搞国产生态选PaddlePaddle模型转换靠ONNX。2. PyTorch简介PyTorch 是基于 Python 的深度学习框架核心概念是张量Tensor。它提供了灵活高效的工具用于构建、训练和部署深度学习模型。安装极其简单pipinstalltorch-ihttps://pypi.tuna.tsinghua.edu.cn/simple三、PyTorch张量操作详解1. 什么是张量张量Tensor是 PyTorch 的核心数据抽象简单理解就是多维数组。它与 NumPy 的ndarray非常相似但多了一个杀手锏——支持GPU加速CUDA。维度名称0维标量scalar1维向量vector2维矩阵matrix3维及以上张量tensor关键区别PyTorch张量与NumPy数组类似但通过CUDA可以在GPU上高效运行大幅加速深度学习模型的训练。2. 张量的创建方法importtorch# 1. 根据指定数据创建datatorch.tensor([[1,2],[3,4]])print(data)# tensor([[1, 2], [3, 4]])# 2. 根据形状创建未初始化datatorch.Tensor(2,3)# 2行3列# 3. 指定类型创建data_inttorch.IntTensor([1,2,3])data_floattorch.FloatTensor([1.1,2.2,3.3])# 4. 创建线性张量arange_datatorch.arange(0,10,2)# [0, 2, 4, 6, 8]linspace_datatorch.linspace(0,1,5)# [0, 0.25, 0.5, 0.75, 1]# 5. 创建随机张量torch.random.manual_seed(42)# 固定随机种子rand_datatorch.rand(2,3)# [0,1)均匀分布randn_datatorch.randn(2,3)# 标准正态分布randint_datatorch.randint(0,10,(2,3))# [0,10)随机整数# 6. 创建全0/全1/全指定值张量zeros_datatorch.zeros(2,3)# 全0ones_datatorch.ones(2,3)# 全1full_datatorch.full((2,3),7)# 全为7# 还有 ones_like / zeros_like / full_like 可模仿形状3. 张量类型转换datatorch.tensor([1,2,3])# 方法一直接转换data_floatdata.float()# torch.float32data_doubledata.double()# torch.float64data_intdata.int()# torch.int32data_longdata.long()# torch.int64data_halfdata.half()# torch.float16# 方法二用 type() 方法data_fp32data.type(torch.float)data_i32data.type(torch.int)4. 张量与NumPy互转importnumpyasnp# 张量 → numpy共享内存修改一个会影响另一个data_tensortorch.tensor([1,2,3])data_numpydata_tensor.numpy()# 共享内存data_numpy_copydata_tensor.numpy().copy()# 不共享内存# numpy → 张量共享内存data_npnp.array([4,5,6])data_tensor_sharedtorch.from_numpy(data_np)# 共享内存data_tensor_newtorch.tensor(data_np)# 不共享内存# 标量张量 ↔ 数字scalartorch.tensor(3.14)print(scalar.item())# 3.14⚠️注意tensor.numpy()和torch.from_numpy()是共享内存的修改其中一个会影响另一个。如果不希望共享用.copy()或torch.tensor()。5. 张量基本运算# 1. 基本算术运算atorch.tensor([1,2,3])btorch.tensor([4,5,6])print(ab)# tensor([5, 7, 9])print(a-b)# tensor([-3, -3, -3])print(a*b)# tensor([4, 10, 18])print(a/b)# tensor([0.25, 0.40, 0.50])# 函数形式带下划线的为原地操作会修改原张量torch.add(a,b)# add, sub, mul, diva.add_(b)# 原地加法a a b注意下划线# 2. 矩阵乘法matrix_atorch.tensor([[1,2],[3,4]])matrix_btorch.tensor([[5,6],[7,8]])print(matrix_a matrix_b)# 使用 运算符print(torch.matmul(matrix_a,matrix_b))# 使用 matmul 函数# 3. 常见运算函数datatorch.tensor([1.0,2.0,3.0,4.0])print(torch.sum(data))# 求和10.0print(torch.mean(data))# 均值2.5print(torch.sqrt(data))# 平方根print(torch.pow(data,2))# 平方tensor([1, 4, 9, 16])print(torch.exp(data))# 指数print(torch.log(data))# 对数6. 张量索引操作张量的索引和 NumPy 完全一致非常直观datatorch.randint(0,10,(3,4))print(data)# 假设输出# tensor([[5, 1, 8, 3],# [9, 2, 6, 0],# [4, 7, 2, 5]])# 格式张量[行, 列]# 1. 单索引print(data[1,2])# 第2行第3列 → 6# 2. 列表索引print(data[[0,2],:])# 第1行和第3行的所有列# 3. 切片索引print(data[0:2,1:3])# 前两行的第2~4列# 4. 布尔索引maskdata5print(data[mask])# 所有大于5的元素# 5. 多维索引print(data[1])# 第2行所有列7. 张量形状操作datatorch.arange(12)# tensor([0, 1, 2, ..., 11])# reshape — 重塑形状最常用reshapeddata.reshape(3,4)print(reshaped.shape)# torch.Size([3, 4])# view — 类似reshape但要求内存连续vieweddata.view(3,4)# data本身连续所以可以# 对于不连续的张量先 contiguous 再 viewtransposeddata.reshape(3,4).transpose(0,1)# transposed 是不连续的viewedtransposed.contiguous().view(4,3)# squeeze — 删除长度为1的维度data_with_dim1data.reshape(1,3,1,4)# shape: [1, 3, 1, 4]squeezeddata_with_dim1.squeeze()# shape: [3, 4]# unsqueeze — 增加长度为1的维度data_2dtorch.tensor([[1,2,3],[4,5,6]])# shape: [2, 3]unsqueezeddata_2d.unsqueeze(0)# shape: [1, 2, 3]# transpose — 交换两个维度data_3dtorch.randn(2,3,4)transposeddata_3d.transpose(1,2)# shape: [2, 4, 3]# permute — 任意重排所有维度permuteddata_3d.permute(2,0,1)# shape: [4, 2, 3]reshape vs viewreshape更智能自动处理不连续的张量view更快但要求内存连续不连续时需配合contiguous()使用。8. 张量拼接操作data1torch.randint(0,10,(1,2,3))data2torch.randint(0,10,(1,2,3))print(data1:,data1)print(data2:,data2)# 1. cat — 沿已有维度拼接不增加维度# dim0 拼接 → shape: [2, 2, 3]cat_dim0torch.cat([data1,data2],dim0)# dim1 拼接 → shape: [1, 4, 3]cat_dim1torch.cat([data1,data2],dim1)# dim2 拼接 → shape: [1, 2, 6]cat_dim2torch.cat([data1,data2],dim2)# 2. stack — 在新维度上堆叠会增加一个维度data3torch.randint(0,10,(2,3))data4torch.randint(0,10,(2,3))# dim0 → shape: [2, 2, 3]在第一个维度前插入新维度stack_dim0torch.stack([data3,data4],dim0)# dim1 → shape: [2, 2, 3]在第二个维度前插入新维度stack_dim1torch.stack([data3,data4],dim1)# dim2 → shape: [2, 3, 2]在第三个维度前插入新维度stack_dim2torch.stack([data3,data4],dim2)cat vs stack 的区别cat不改变张量的维度数只在现有维度上拼接stack会增加一个新维度要求所有输入张量的形状完全相同。四、实操案例完整张量操作流水线下面是一个综合案例将我们学过的张量操作串起来走一遍importtorchimportnumpyasnp# # 1. 创建数据 — 模拟一个3通道2x2的图像# torch.random.manual_seed(42)imagetorch.randint(0,256,(3,2,2))# shape: [3, 2, 2]print(原始图像张量形状:,image.shape)# # 2. 类型转换 — 转为浮点型便于计算# image_floatimage.float()print(转换后类型:,image_float.dtype)# # 3. 归一化 — 将像素值缩放到[0,1]# image_normimage_float/255.0print(归一化后的均值:,torch.mean(image_norm).item())# # 4. 增加批次维度 — 模型需要4D输入# image_batchimage_norm.unsqueeze(0)# shape: [1, 3, 2, 2]print(增加批次维度后:,image_batch.shape)# # 5. 展平 — 将图像变为一维向量# image_flatimage_batch.reshape(1,-1)# shape: [1, 12]print(展平后形状:,image_flat.shape)# # 6. 转 NumPy 数组# image_numpyimage_flat.numpy()print(转换为NumPy数组, 类型:,type(image_numpy))# # 7. 数学运算 — 模拟简单的特征变换# weightstorch.randn(12,4)# 随机权重biastorch.randn(4)# 随机偏置outputtorch.matmul(image_flat,weights)biasprint(线性变换后输出形状:,output.shape)# # 8. 激活函数 — 模拟ReLU# output_activatedtorch.relu(output)print(激活后输出:,output_activated)# # 9. 拼接多张图像模拟batch处理# image2torch.rand(1,12)# 第二张图像batchtorch.cat([image_flat,image2],dim0)# shape: [2, 12]print(拼接batch后形状:,batch.shape)print(\n✅ 完整流水线执行完毕)五、总结知识点一句话总结深度学习用深层神经网络自动提取特征无需人工设计深度学习 vs MLDL是ML的子集DL自动提取特征ML需要人工特征工程主流模型CNN处理图像、RNN处理序列、Transformer处理语言、GAN生成数据PyTorch学术界主流框架动态图、上手快、生态丰富张量TensorPyTorch的核心数据抽象类似NumPy但支持GPU加速张量创建tensor()、Tensor()、ones/zeros/full、rand/randn/randint、arange/linspace张量运算 - * /、/matmul、sum/mean/sqrt/pow/exp/log形状操作reshape通用、view连续内存、squeeze/unsqueeze增减维度、transpose/permute交换维度拼接操作cat沿现有维度拼接不增维、stack新维度堆叠增一维NumPy互转tensor.numpy()和torch.from_numpy()共享内存.copy()和torch.tensor()不共享