首页 > 其他分享 >深度学习基础

深度学习基础

时间:2024-06-13 22:02:43浏览次数:8  
标签:__ nn 梯度 self torch 基础 学习 深度 数据

1、numpy和pandas的比较?

NumPy和Pandas都是Python中用于数据处理的库,但它们的设计目的和功能特性有所不同。以下是NumPy和Pandas的比较:

  1. 设计目的:
    • NumPy 主要是为了科学计算,提供高性能的多维数组对象和数学函数。
    • Pandas 主要是为了数据分析和数据预处理,提供数据结构和数据分析工具。
  2. 数据结构:
    • NumPy 使用 ndarray(N维数组)来存储同一类型的数据,适合进行数学运算和矩阵操作。
    • Pandas 使用 DataFrameSeries,可以存储异构数据(不同类型的数据),适合处理表格数据和时间序列数据。
  3. 功能特性:
    • NumPy 提供了广泛的数学函数和线性代数运算,以及傅里叶变换和随机数生成等功能。
    • Pandas 提供了数据导入导出、数据清洗、数据合并、数据重塑、数据选择、数据分组、时间序列功能等。
  4. 性能:
    • NumPy 通常性能更高,因为它底层是用C语言编写的,并且数组是固定类型的,减少了开销。
    • Pandas 在处理异构数据时更加灵活,但可能会牺牲一些性能,因为它基于NumPy构建并在其之上添加了额外的功能。
  5. 使用场景:
    • 当你需要进行数值计算、线性代数或科学计算时,通常会使用 NumPy
    • 当你需要处理和分析表格数据、执行数据预处理步骤时,通常会使用 Pandas
  6. 集成:
    • NumPy 可以与Pandas无缝集成,因为Pandas的DataFrameSeries对象在底层使用NumPy数组。
    • Pandas 提供了更高级的数据处理功能,但在需要时可以利用NumPy的性能优势。
      在实际应用中,NumPy和Pandas经常一起使用。例如,在数据科学项目中,你可能会使用Pandas加载数据、清洗数据、转换数据,然后使用NumPy进行数学运算和建模。两者都是Python数据科学栈中不可或缺的部分。

2、标准化,归一化,数值化的目的,应用场景,并进行比较

目的:
  1. 标准化(Standardization):

    • 目的: 将数据转换成具有零均值和单位标准差的正态分布。
    • 公式:
      z = x − μ σ ,其中 x 是原始值, μ 是均值, σ 是标准差。 z = \frac{x - \mu}{\sigma} ,其中 x 是原始值, \mu 是均值,\sigma 是标准差。 z=σx−μ​,其中x是原始值,μ是均值,σ是标准差。
  • 应用场景: 当数据分布近似正态分布时,特别是使用基于梯度下降的算法时。
  1. 归一化(Normalization):

    • 目的: 将数据缩放到一个固定的范围,通常是0到1。
    • 公式:
      x norm = x − x min x max − x min ,其中 x 是原始值, x min 和 x max 分别是数据的最小值和最大值。 x_{\text{norm}} = \frac{x - x_{\text{min}}}{x_{\text{max}} - x_{\text{min}}},其中 x 是原始值,x_{\text{min}} 和 x_{\text{max}} 分别是数据的最小值和最大值。 xnorm​=xmax​−xmin​x−xmin​​,其中x是原始值,xmin​和xmax​分别是数据的最小值和最大值。
    • 应用场景: 当数据特征的量级相差很大,或者不确定数据的分布时。
  2. 数值化(Encoding):

    • 目的: 将非数值数据(如分类数据)转换为数值形式,以便机器学习模型可以处理。
    • 方法: 常见的数值化方法包括独热编码(One-Hot Encoding)、标签编码(Label Encoding)等。
    • 应用场景: 处理分类特征或标签时。
应用场景:
  1. 标准化(Standardization):
    • 应用场景: 在机器学习算法中,标准化可以加快学习速度,特别是对于基于梯度下降的算法,如线性回归、逻辑回归、支持向量机等。
  2. 归一化(Normalization):
    • 应用场景: 归一化特别适用于数据特征的量级相差很大时,或者当你不确定数据的分布时。它可以帮助保持不同特征之间的相对重要性。
  3. 数值化(Encoding):
    • 应用场景: 当数据包含分类特征时,数值化是必要的。例如,在处理性别、颜色、国家等分类数据时,需要将它们转换为数值形式。
比较:
类型目的应用场景数据转换后的范围对数据分布的假设
标准化零均值,单位标准差适用于数据分布近似正态分布,特别是基于梯度下降的算法不固定,依赖于原始数据正态分布
归一化缩放到固定范围(通常是0到1)特征量级相差很大,或不确定数据的分布0到1之间
数值化将非数值数据转换为数值形式处理分类特征或标签依赖于转换方法

在选择使用哪种预处理技术时,需要根据数据的特点和机器学习算法的要求来决定。通常,标准化和归一化用于数值特征,而数值化用于分类特征。在实际应用中,可能需要结合使用这些技术来获得最佳的性能。

3、Relu

RELU函数,即修正线性单元(Rectified Linear Unit),是深度学习中应用非常广泛的一种激活函数。它的数学表达式简单直观:
f ( x ) = max ⁡ ( 0 , x ) f(x) = \max(0, x) f(x)=max(0,x)
这意味着,对于任何输入值( x ),如果( x )为正,则输出为( x )本身;如果( x )为负,则输出为0。

RELU函数的特点和优势:
  1. 计算效率高:由于RELU函数的简单性,它在前向传播时的计算速度非常快。特别是与Sigmoid和Tanh函数相比,RELU避免了复杂的指数运算和浮点运算,只需要简单的条件判断(if-else)即可完成计算。
  2. 减少梯度消失问题:在反向传播过程中,RELU函数的导数(即斜率)在输入为正时为1,而在输入为负时为0。这使得在输入为正的区域,梯度不会随着层数的增加而消失,有助于深层网络的训练。
  3. 增加网络的稀疏性:由于RELU函数的性质,只有一部分神经元的输出会是非零值,这导致网络中的权重参数有更多的机会变为0,从而减少了参数之间的相互依赖,提高了模型训练的效率,并有助于缓解过拟合问题。
  4. 非线性特性:RELU函数为神经网络引入了非线性特性,使得网络能够捕捉到更加复杂的数据结构和模式。
使用RELU的注意事项:
  1. Dead ReLU问题:如果网络中存在始终为负的输入,那么对应的神经元将永远不会激活,这个问题被称为“Dead ReLU”。为了解决这个问题,可以考虑使用Leaky ReLU或其他变体,如Parametric ReLU(PReLU),这些变体在输入为负时提供了一个小的正斜率。
  2. 输出范围:RELU函数的输出范围始终为非负数,这可能会导致网络的输出无法直接用于后续的比较操作,如分类问题中的softmax层。然而,这可以通过在输出层之前添加一个恒等映射来解决。
    总的来说,RELU及其变体由于其简单性、效率和效果,在深度学习领域得到了广泛的应用。尽管存在一些局限性,但它仍然是设计和训练深度神经网络时最受欢迎的激活函数之一。

4、梯度下降和反向传播

梯度:是一个向量,可以理解为导数+(参数/学习)变化最快的方向

梯度下降是一种优化算法,用于通过迭代的方式找到一个函数的局部最小值。在机器学习中,这个函数通常是损失函数,它衡量的是模型的预测值与真实值之间的差异。梯度下降的基本思想是沿着函数梯度的反方向逐步调整参数,以减少损失函数的值。
梯度下降的计算步骤如下:

  1. 初始化参数
    选择一个初始的参数值 θ 选择一个初始的参数值 \theta 选择一个初始的参数值θ

  2. 计算梯度
    计算当前参数下损失函数的梯度 ∇ θ J ( θ ) ,梯度表示损失函数对每个参数的偏导数。 计算当前参数下损失函数的梯度 \nabla \theta J(\theta) ,梯度表示损失函数对每个参数的偏导数。 计算当前参数下损失函数的梯度∇θJ(θ),梯度表示损失函数对每个参数的偏导数。

  3. 更新参数
    根据梯度和学习率(步长)来更新参数值。更新公式为: θ = θ − α ∇ θ J ( θ ) 其中, α 是学习率,控制着每一步更新的幅度。 根据梯度和学习率(步长)来更新参数值。更新公式为: \theta = \theta - \alpha \nabla \theta J(\theta) 其中,\alpha 是学习率,控制着每一步更新的幅度。 根据梯度和学习率(步长)来更新参数值。更新公式为:θ=θ−α∇θJ(θ)其中,α是学习率,控制着每一步更新的幅度。

  4. 重复迭代:重复步骤2和3,直到满足停止条件,比如梯度的变化非常小(接近0),或者达到预设的迭代次数。
    在实际应用中,梯度下降的实现可以根据数据的特点和问题的复杂性有所不同。以下是一些梯度下降的变体:

  • 批量梯度下降(Batch Gradient Descent):每次更新参数时使用全部的训练数据来计算梯度。这种方法在数据量不大时效果很好,但当数据量大时计算量也会很大。
  • 随机梯度下降(Stochastic Gradient Descent,SGD):每次更新参数时只使用一个随机样本来计算梯度。这种方法计算效率高,但可能收敛速度较慢,且路径更曲折。
  • 小批量梯度下降(Mini-batch Gradient Descent):每次更新参数时使用部分(小批量)训练数据来计算梯度。这种方法结合了批量梯度下降和随机梯度下降的优点,是实际应用中最常用的方法。
    梯度下降是一种简单而强大的优化算法,但它的收敛速度和最终结果很大程度上取决于学习率和初始参数值的选择。因此,通常需要通过实验来调整这些超参数。

loss.backward()就是根据损失函数,对参数(required_grad=True)去计算它的梯度,并且把它累加保存到x.grad,此时还并未更新其梯度

  1. tensor.data:
    • required_grad=False,tensor.data和tensor等价
    • require_grad=True,tensor.data仅获取tensor中的数据
  2. tensor.numpy():
    • require_grad=True不能够直接转化,需要使用tensor.detach().numpy()

5、nn.Modulenn.functional和Sequential

torch.nn.Module

torch.nn.Module是所有神经网络模块的基类。当你创建一个模型时,通常需要继承这个类。它提供了一种组织构建块的方法,允许你定义一个包含多个层和操作的网络。Module类还提供了许多有用的功能,如.parameters().zero_grad().to(device)等,这些方法可以方便地访问和管理模型的参数,以及将模型移动到不同的设备(如CPU或GPU)。

当我们在自定义网络时,有两个方法需要特别注意:

  1. __init__需要调用super方法,继承父类的属性和方法
  2. forward方法必须实现,用定义我们的网络向前计算的过程
示例代码:
import torch.nn as nn
import torch.nn.functional as F
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

注意:nn.Model定义了__call__方法,实现的就是调用forward方法。即SimpleModel的实例,能够直接被传入参数调用,实际调用的是forward方法并传入参数*

# 实例化模型
model=SimpleModel()
# 传入数据,计算结果
predict=model(x)
torch.nn.functional

torch.nn.functional提供了一系列激活函数、池化层、损失函数等,这些都是不需要参数的层或操作。使用torch.nn.functional而不是torch.nn.Module的优点是,你的模型会更加灵活,尤其是在定义复杂的层操作时。然而,这也意味着你需要手动管理更多的细节,如输入数据的形状。

示例代码:
import torch.nn as nn
import torch.nn.functional as F
class FunctionalModel(nn.Module):
    def __init__(self):
        super(FunctionalModel, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2, 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)
比较
  • 构造函数Module通常在构造函数中定义层,而functional直接在forward函数中使用。
  • 参数管理Module类自动处理参数的初始化、更新和序列化。functional需要手动处理这些。
  • 灵活性functional提供更大的灵活性,尤其是在定义动态模型时。
  • 代码组织Module提供了更好的代码组织方式,特别是在大型项目中。
总结

选择Module还是functional取决于你的具体需求。如果你在构建一个标准的、层次结构清晰的模型,Module可能是更好的选择。如果你需要更多的灵活性,或者你的模型比较简单,functional可能更适合。在实际应用中,Modulefunctional经常一起使用,以达到最佳的灵活性和组织性。

Sequential

在PyTorch中,torch.nn.Sequential是一个顺序容器。模块将按照它们在构造器中传递的顺序添加到它里面。也可以通过索引来访问Sequential中的模块。
Sequential的特点是简化了神经网络的构建过程,使得构建神经网络更加直观和方便。
下面是一个使用torch.nn.Sequential构建简单神经网络的例子:

import torch
import torch.nn as nn
# 定义一个简单的神经网络
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        # 使用Sequential定义网络的层
        self.layers = nn.Sequential(
            nn.Linear(10, 20),  # 第一层,10个输入,20个输出
            nn.ReLU(),          # 激活函数
            nn.Linear(20, 10),  # 第二层,20个输入,10个输出
            nn.ReLU(),          # 激活函数
            nn.Linear(10, 1)    # 输出层,10个输入,1个输出
        )
    def forward(self, x):
        # 直接使用Sequential的前向传播
        x = self.layers(x)
        return x
# 创建网络实例
net = SimpleNet()
# 创建一个随机输入张量
input_tensor = torch.randn(1, 10)
# 前向传播
output = net(input_tensor)
print(output)

在这个例子中,我们首先定义了一个名为SimpleNet的神经网络类,它继承自nn.Module。在构造函数中,我们使用nn.Sequential来定义网络的层。在前向传播函数forward中,我们直接调用self.layers(即Sequential容器)来进行前向传播。
使用Sequential的好处是代码更加简洁,层与层之间的连接自动处理,不需要手动定义每一层的输入和输出。这使得网络构建更加直观,特别是对于具有大量层的深层网络。

6、优化器类

优化器(optimizer)可以理解为torch为我们封装的用来更新参数的方法,比如常见的随机梯度下降(SGD)

优化器都是由torch.optim提供的,如:

  1. torch.optim.SGD(参数,学习率)
  2. torch.optim.Adam(参数,学习率)
注意
  1. 参数可以使用model.parameters()来获取,获取模型中所有required_gard=True的参数
  2. 优化器类的使用方法
    1. 实例化
    2. 所有参数梯度置0
    3. 反向传播计算梯度
    4. 跟新参数值
示例如下:
import torch.optim as optim
optimizer = optim.SGD(Model.parameters(),lr=1e-3)        	#1.实例化
optimizer.zero_gard() 										#2.梯度置0
loss.backward() 											#3.反向传播计算梯度
optimizer.step() 											#4.更新参数值

7、损失函数

  • 均方误差:nn.MESLoss(),常用于回归问题
import torch.nn as nn
model = SimpleModel()										
crition = nn.MSELoss()
optimizer = optim.SGD(Model.parameters(),lr=1e-3)   
for i in range(100):
    y_predict = model(x_true)
    loss = crition(y_true,y_predict)
    optimizer.zero_gard()
    loss.backward()
    optimizer.step()
  • 交叉熵损失:nn.CrossEntropyLoss(),常用于分类问题
crition = nn.CrossEntropyLoss()
loss = crition(output,target)
output = F.log_softmax(x,dim=-1)							#1.对输出值计算softmax和取对数
loss = F.nll_loss(output,target)							#2.使用torch中的带权损失

带权损失定义为: l n = − ∑ w i x i l_n=-\sum w_ix_i ln​=−∑wi​xi​, 其中把 l o g ( P ) 作为 x i , 把真实值 Y 作为权重 其中把log(P)作为x_i,把真实值Y作为权重 其中把log(P)作为xi​,把真实值Y作为权重

8、Pytorch中数据的加载

在深度学习中,数据量通常比较大,面对如此大量的数据,不可能一次性的在模型中进行前向传播和反向传播。所以我们会对整个数据进行随机的打乱顺序,把数据整理成一个个batch,同时还对数据进行预处理。

数据集类

数据集类的主要目的是为了提供一种方便的方式来加载、访问和处理数据。在PyTorch中,通常使用Dataset类来定义数据集,并使用DataLoader类来加载数据。

示例如下
import torch
from torch.utils.data import Dataset

class MyDataset(Dataset):
    def __init__(self, data, labels):
        self.data = data
        self.labels = labels
	def __len__(self):
    	return len(self.data)

	def __getitem__(self, index):
    	data_point = self.data[index]
    	label = self.labels[index]
    	return data_point, label

我们需要在自定义的数据集中继承Dataset类,同时还需要实现两个方法

  1. __len__方法,能够实现通过全局的len()方法获取其中的元数个数
  2. __getitem__方法,能够通过传入索引的方式获取数据,如通过dataset[i]获取其中第i个数据
迭代数据集

使用上述方法能够对数据进行读取,但其中还有很多内容没有实现:

  1. 批处理数据
  2. 打乱数据
  3. 使用多线程multiprocessing并行加载数据
示例如下
from torch.utils.data import DataLoader

dataset = MyDataset()
data_loader = DataLoader(dataset = dataset,batch_size = 10,shuffle = True,num_workers = 2)

# 遍历获得每一个batch的结果
for index,(label,contxet) in enumerate(data_loader):
    print(index,label,context)

其中参数含义:

  1. dataset:提前定义的dataset实例
  2. batch_size:传入数据的batch大小
  3. shuffle:表示是否在每一次获取数据的时候提前打乱数据
  4. num_workers:加载数据的线程数

9、模型的保存和加载

# 保存模型
torch.save(model.state_dict(), 'model.pth')
# 加载模型
model = SimpleModel()
model.load_state_dict(torch.load('model.pth'))

标签:__,nn,梯度,self,torch,基础,学习,深度,数据
From: https://blog.csdn.net/qq_56547436/article/details/139575738

相关文章

  • 学习日志-C51-串口通信
    学习日志-C51-串口通信串口控制LED灯亮灭1.常见通信串口比较分类1:单工:只能由甲向乙传输信号,一根传输线。半双工:数据可以在双方传输,但同一时刻只能单方传输,发送数据的同时不能接收数据,一根传输线。全双工:数据可以在双方传输,发送数据的同时也能接收数据,需两根传输线。......
  • 机器学习归一化特征编码
    特征缩放因为对于大多数的机器学习算法和优化算法来说,将特征值缩放到相同区间可以使得获取性能更好的模型。就梯度下降算法而言,例如有两个不同的特征,第一个特征的取值范围为1——10,第二个特征的取值范围为1——10000。在梯度下降算法中,代价函数为最小平方误差函数,所以在使用......
  • 基于python-CNN深度学习的手势识别数字-含数据集+pyqt界面
    代码下载:https://download.csdn.net/download/qq_34904125/89379220本代码是基于pythonpytorch环境安装的。下载本代码后,有个requirement.txt文本,里面介绍了如何安装环境,环境需要自行配置。或可直接参考下面博文进行环境安装。深度学习环境安装教程-anaconda-python-pyto......
  • 基于python_cnn深度学习的decks的裂缝识别-含数据集+pyqt界面
    代码下载:https://download.csdn.net/download/qq_34904125/89379212本代码是基于pythonpytorch环境安装的。下载本代码后,有个requirement.txt文本,里面介绍了如何安装环境,环境需要自行配置。或可直接参考下面博文进行环境安装。深度学习环境安装教程-anaconda-python-pyto......
  • 线段树学习笔记
    线段树(SegmentTree)是一种基于分治思想的数据结构,可以在\(\mathcal{O}(\log~n)\)的时间内完成区间修改和区间查询等操作。1.1线段树基础此部分介绍普通线段树的基本思想与操作。1.1.1基本思想线段树本质上就是一棵二叉树,它的每一个节点表示一段区间的信息,对于一个长度不为......
  • Linux结业测试题,旨在检测ip网络配置,文件权限等基础
    Linux期末结业考试一、评分方式(总分100分,理论40分在职教云考试)主要涉及的知识和技能点*分值权重*Linux的最小安装10%激活网络,并正确设置ip地址10%克隆1台机器,并正确设置ip地址10%SSH免密互信服务10%文件和目录操作10%权限操作10%二、项目步骤及实现linux虚拟机安装(1)通......
  • hive函数学习
    复制粘贴到MD文档中查看更方便Hive函数学习目录Hive函数学习SQL练习Hive常用函数关系运算数值计算条件函数(主要使用场景是数据清洗的过程中使用,有些构建表的过程也是需要的)日期函数重点!!!字符串函数Hive中的wordCount1.1 Hive窗口函数1.1.1 聚合开窗函数聚合开窗函数实战:实战1......
  • 隐语课程学习笔记6-逻辑回归LR与广义线性模型GLM开发实践
    隐语第6课,开始介绍具体的机器学习算法以及使用隐语模型进行真实数据的建模实验。首先介绍广义线性模型,广义线性模型(GLM)是线性模型的扩展,通过联系函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。它的特点是不强行改变数据的自然度量,数据可以具有非线性和非......
  • 隐语课程学习笔记5-隐私保护机器学习算法概要
    隐语课程第5课,简单介绍了隐语的算法能力,包括预处理、隐私求交、决策树模型、线性回归模型、神经网络模型,并且支持数据水平切分(横向联邦)、垂直切分(纵向联邦)、混合切分(横纵向联邦)。隐语提供了包括对DataFrame的封装,以及提供联邦ndarray的封装,和python的使用基本一致,上手较快,比......
  • [论文学习] 全密态数据库密态计算关键技术综述
    原文链接全密态数据库的功能和挑战其概述。全密态数据库的应用个场景和3种典型架构。后续3章对3种架构的关键技术做总结和分析。基于软件的加密方案。基于可信硬件TEE的关键技术。基于软硬融合的关键技术。保护访问模式的相关技术的总结分析。未来展望全密态数据库概述......