深度学习的总览及PyTorch

发布时间:2026/8/31 15:35:20
深度学习的总览及PyTorch 1 深度学习概念深度学习Deep Learning是机器学习的分支是一种以人工神经网络为架构对数据进行特征学习的算法。深度学习中的形容词“深度”是指在网络中使用多层。深度学习核心思想是通过模仿人脑的神经网络来处理和分析复杂的数据从大量数据中自动提取复杂特征擅长处理高维数据如图像、语音和文本。1.1 深度学习特点[知道]多层非线性变换深度学习模型由多个层次组成每一层都应用非线性激活函数对输入数据进行变换。较低的层级通常捕捉到简单的特征如边缘、颜色等而更高的层级则可以识别更复杂的模式如物体或面部识别。自动特征提取与传统机器学习算法不同深度学习能够自动从原始数据中学习到有用的特征而不需要人工特征工程。这使得深度学习在许多领域中表现出色。大数据和计算能力深度学习模型通常需要大量的标注数据和强大的计算资源如GPU来进行训练。大数据和高性能计算使得深度学习在图像识别、自然语言处理等领域取得了显著突破。可解释性差深度学习模型内部的运作机制相对不透明被称为“黑箱”这意味着理解模型为什么做出特定决策可能会比较困难。这对某些应用场景来说是一个挑战。1.2常见的深度学习模型[了解]卷积神经网络 (Convolutional Neural Networks, CNN)主要用于图像处理任务如图像分类、目标检测、图像分割等。特点是使用卷积层来自动提取图像中的局部特征并通过池化层减少参数数量提高计算效率。循环神经网络 (Recurrent Neural Networks, RNN)适用于处理序列数据例如自然语言处理NLP、语音识别等。RNN具有记忆功能可以处理输入数据的时间依赖性但标准RNN难以捕捉长期依赖关系。自编码器 (Autoencoders)一种无监督学习模型通常用于降维、特征学习或者异常检测。自编码器由编码器和解码器两部分组成前者将输入压缩成一个较低维度的表示后者尝试从这个低维表示重建原始输入。生成对抗网络 (Generative Adversarial Networks, GAN)包含两个子网络生成器和判别器。生成器负责创建看起来真实的假样本而判别器则试图区分真假样本。GAN广泛应用于图像生成、视频合成等领域。Transformer主要用于自然语言处理NLP任务尤其是机器翻译、文本生成等。Transformer摒弃了传统的递归结构采用自注意力机制self-attention使得它能够并行处理整个句子的信息在机器翻译、文本摘要等任务中表现出色。2 PyTorchPyTorch一个基于Python语言的深度学习框架它将数据封装成张量Tensor来进行处理。PyTorch提供了灵活且高效的工具用于构建、训练和部署机器学习和深度学习模型。PyTorch广泛应用于学术研究和工业界特别是在计算机视觉、自然语言处理、强化学习等领域。2.1 PyTorch特点PyTorch与TensorFlow的比较PyTorch与TensorFlow的区别PyTorch是基于动态图动态计算图的而TensorFlow 1.x是基于静态计算图的TensorFlow 2.x支持动态图。这使得PyTorch在灵活性和调试方面优于TensorFlow尤其是在研究和原型设计中。此外PyTorch的API设计更加贴近Python易于学习和使用。TensorFlow 2.x引入了Eager Execution和PyTorch都支持动态图但PyTorch因其更直观的编程模式和调试支持在学术界和一些工业界应用中更为流行。类似于NumPy的张量计算PyTorch中的基本数据结构是张量Tensor它与NumPy中的数组类似但PyTorch的张量具有GPU加速的能力通过CUDA这使得深度学习模型能够高效地在GPU上运行。自动微分系统PyTorch提供了强大的自动微分功能autograd模块能够自动计算模型中每个参数的梯度。自动微分使得梯度计算过程变得简洁和高效并且支持复杂的模型和动态计算图。深度学习库PyTorch提供了一个名为torch.nn的子模块用于构建神经网络。它包括了大量的预构建的层如全连接层、卷积层、循环神经网络层等损失函数如交叉熵、均方误差等以及优化算法如SGD、Adam等。torch.nn.Module是PyTorch中构建神经网络的基础类用户可以通过继承该类来定义自己的神经网络架构。动态计算图PyTorch使用动态计算图机制允许在运行时构建和修改模型结构具有更高的灵活性适合于研究人员进行实验和模型调试。GPU加速CUDA支持PyTorch提供对GPU的良好支持能够在NVIDIA的CUDA设备上高效地进行计算。用户只需要将数据和模型转移到GPU上PyTorch会自动优化计算过程。通过简单的tensor.to(device)方法可以轻松地将模型和数据从CPU转移到GPU或从一个GPU转移到另一个GPU。跨平台支持PyTorch支持在多种硬件平台如CPU、GPU、TPU等上运行并且支持不同操作系统如Linux、Windows、macOS以及分布式计算环境如多GPU、分布式训练。2.2 张量创建张量是PyTorch中的核心数据抽象PyTorch中的张量就是元素为同一种数据类型的多维矩阵与NumPy数组类似。PyTorch中张量以类的形式封装起来对张量的一些运算、处理的方法数值计算、矩阵操作、自动求导被封装在类中。2.2.1 基本创建torch.tensor(data,dtype) : 根据指定数据创建张量torch.tensor(3.14)torch.tensor([1,2,3,4])torch.tensor(arr1)torch.Tensor(data, size()) : 根据形状创建张量, 其也可用来创建指定数据的张量torch.Tensor(3,5)torch.Tensor([1,2,3])torch.IntTensor()/FloatTensor()... 创建指定类型的张量2.2.2 线性和随机张量torch.arange(start, end, step)固定步长线性张量torch.linspace(start, end, steps)固定元素数线性张量torch.randn/rand(size) 创建随机浮点类型张量torch.randint(low, high, size) 创建随机整数类型张量 左闭右开torch.initial_seed() 和 torch.manual_seed(seed)随机种子设置2.2.3 指定值张量torch.zeros(size) 和 torch.zeros_like(input) 创建全0张量torch.ones(size) 和 torch.ones_like(input) 创建全1张量torch.full(size, fill_value) 和 torch.full_like(input, fill_value) 创建全为指定值张量2.2.4 指定元素类型张量data.type(dtype)data torch.full([2, 3], 10) print(data.dtype) # 将 data 元素类型转换为 float64 类型 data data.type(torch.DoubleTensor) print(data.dtype) # 转换为其他类型 # data data.type(torch.ShortTensor) # data data.type(torch.IntTensor) # data data.type(torch.LongTensor) # data data.type(torch.FloatTensor) # data data.type(dtypetorch.float16)2.3 张量类型转换2.3.1张量转换为NumPy数组使用 t.numpy() 函数可以将张量转换为 ndarray 数组但是共享内存可以使用copy函数避免共享。2.3.2 NumPy数组转换为张量使用torch.from_numpy(ndarray)可以将ndarray数组转换为 tensor张量默认共享内存使用copy函数避免共享。使用torch.tensor(data)可以将ndarray数组转换为tensor张量默认不共享内存。2.3.3 提取标量张量的数值对于只有一个元素的张量使用item()函数将该值从张量中提取出来2.4 张量数值计算2.4.1 基本运算# add, sub, mul, div, neg import torch t1 torch.tensor([1, 2, 3, 4, 5]) t1 t1.float() # 加 # t2 t1 10 # t2 t1.add(10) # 二者等价 # print(t2) t1.add_(10) # 带上下划线, 会修改原数据 print(t1) # # 减 # # t3 t1 - 10 # t3 t1.sub(10) # print(t3) # # # 取反 # t4 t1.neg() # print(t4)2.4.2 点乘运算点乘Hadamard也称为元素级乘积指的是相同形状的张量对应位置的元素相乘使用mul和运算符 * 实现。data1 torch.tensor([[1, 2], [3, 4]]) data2 torch.tensor([[5, 6], [7, 8]]) # 第一种方式 data torch.mul(data1, data2) print(data) # 第二种方式 data data1 * data2 print(data)2.4.3 矩阵乘法运算 矩阵乘法运算要求第一个矩阵 shape: (n, m)第二个矩阵 shape: (m, p), 两个矩阵点积运算 shape 为: (n, p)。- 运算符 用于进行两个矩阵的乘积运算- torch.matmul(input, other) 对进行乘积运算的两矩阵形状没有限定。对于输入shape不同的张量, 对应的最后几个维度必须符合矩阵运算规则# 点积运算 data1 torch.tensor([[1, 2], [3, 4], [5, 6]]) data2 torch.tensor([[5, 6], [7, 8]]) # 方式一: data3 data1 data2 print(data3--, data3) # 方式二: data4 torch.matmul(data1, data2) print(data4--, data4)2.5 张量运算函数import torch data torch.randint(0, 10, [2, 3], dtypetorch.float64) print(data) # 1. 计算均值 # 注意: tensor 必须为 Float 或者 Double 类型 print(data.mean()) print(data.mean(dim0)) # 按列计算均值 print(data.mean(dim1)) # 按行计算均值 # 2. 计算总和 print(data.sum()) print(data.sum(dim0)) print(data.sum(dim1)) # 3. 计算平方 print(torch.pow(data2)) # 4. 计算平方根 print(data.sqrt()) # 5. 指数计算, e^n 次方 print(data.exp()) # 6. 对数计算 print(data.log()) # 以 e 为底 print(data.log2()) print(data.log10())2.6 张量索引操作import torch # 随机生成数据 data torch.randint(0, 10, [4, 5]) print(data) # 1.简单行、列索引 print(data[0]) print(data[:, 0]) # 2.列表索引 # 返回 (0, 1)、(1, 2) 两个位置的元素 print(data[[0, 1], [1, 2]]) # 返回 0、1 行的 1、2 列共4个元素 print(data[[[0], [1]], [1, 2]]) # 3.范围索引 # 前3行的前2列数据 print(data[:3, :2]) # 第2行到最后的前2列数据 print(data[2:, :2]) # 4.布尔索引 # 第三列大于5的行数据 print(data[data[:, 2] 5]) # 第二行大于5的列数据 print(data[:, data[1] 5]) # 5.多维索引 # 随机生成三维数据 data torch.randint(0, 10, [3, 4, 5]) print(data) # 获取0轴上的第一个数据 print(data[0, :, :]) # 获取1轴上的第一个数据 print(data[:, 0, :]) # 获取2轴上的第一个数据 print(data[:, :, 0])2.7 张量形状操作张量形状操作是指对张量的维度进行变换的一系列操作。张量的形状则描述了每个维度上的元素数量。1reshape保证张量数据不变的前提下改变数据的维度2 squeeze和unsqueezesqueeze删除指定位置形状为1的维度不指定位置删除所有形状为1的维度降维unsqueeze在指定位置添加形状为1的维度升维3transpose和permutetranspose实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 把 3 和 4 进行交换, 将张量的形状变为 (2, 4, 3)permute一次交换更多的维度4view和contiguousview函数也可以用于修改张量的形状只能用于修改连续的张量。在PyTorch中有些张量的底层数据在内存中的存储顺序与其在张量中的逻辑顺序不一致view函数无法对这样的张量进行变形处理例如: 一个张量经过了 transpose 或者 permute 函数的处理之后就无法使用 view 函数进行形状操作。contiguous将不连续张量转为连续张量is_contiguous判断张量是否连续,返回True或False2.8 张量拼接操作张量拼接操作用于组合来自不同来源或经过不同处理的数据。1 cat/concat沿着现有维度连接一系列张量。所有输入张量除了指定的拼接维度外其他维度必须匹配。2 stack在一个新的维度上连接一系列张量这会增加一个新维度并且所有输入张量的形状必须完全相同。2.9 自动微分模块自动微分就是自动计算梯度值,也就是计算导数。什么是梯度对函数求导的值就是梯度什么是梯度下降法是一种求最优梯度值的方法,使得损失函数的值最小梯度经典语录对函数求导得到的值就是梯度在数值上的理解在某一个点上对函数求导得到的值就是该点的梯度没有点就无法求导,没有梯度梯度就是上山下山最快的方向在方向上理解)在平面内梯度就是某一点上的斜率y 2x^2 某一点x1的梯度就是这一点上的斜率反向传播传播的是梯度反向传播利用链式法则不断的从后向前求导求出来的值就是梯度所以大家都经常说反向传播传播的是梯度链式法则中梯度相乘就是传说中的梯度传播训练神经网络时最常用的算法就是反向传播。在该算法中参数模型权重会根据损失函数关于对应参数的梯度进行调整。为了计算这些梯度PyTorch内置了名为 torch.autograd 的微分模块。它支持任意计算图的自动梯度计算接下来我们使用这个结构进行自动微分模块的介绍我们使用 backward 方法、grad 属性来实现梯度的计算和访问。 1. 需要有一个允许求导的张量 w 2. 需要通过w计算损失 3. 通过损失计算导数 import torch # 1. 创建一个允许求导的张量 w torch.tensor([10., 20.], requires_gradTrue, dtypetorch.float32) # 2.算一下损失 loss 2*w**2 # 打印加工出loss路径上的导函数 print(loss.grad_fn) # 3.计算导数 # 导数的计算, 不需要显示指定对谁求导, 只需要对loss.backward(), 他就会自动帮你求导 # loss必须是标量, 就需要对loss进行聚合 loss.sum().backward() # w.grad, grad属性记录了损失函数对w的导数 print(w.grad)梯度算法 : 1.定义一个模型参数w张量, requires_grad置为True, 数据类型置为 torch.float32, 作为初始值 2.写一个for循环 3.计算loss损失 4.梯度清零 5.自动求导, loss.backward() 6.通过梯度下降法, 更新模型参数w import torch # 1.定义一个模型参数w张量, requires_grad置为True, 数据类型置为 torch.float32 w torch.tensor([10], requires_gradTrue, dtypetorch.float32) # print(w.grad) # None # 2.写一个for循环 for i in range(10000): # 3.计算loss损失 loss w**2 # 4.梯度清零 # 求导之前, 都要做梯度清零, 原因是torch会对多次迭代的导数自动累加 if w.grad is not None: w.grad.zero_() # 5.自动求导, loss.backward(), 自动对加工出loss的路径上, 所有requires_gradTrue的张量求导 loss.backward() # 6.通过梯度下降法, 更新模型参数w # print(w.grad) # print(w.data) w.data w.data - 0.01*w.grad print(f迭代100轮以后, 模型参数是:{w.data}) # 迭代100轮以后, 模型参数是:tensor([3.5032e-44]), 梯度下降接近收敛