【Pytorch神经网络理论篇】 15 过拟合问题的优化技巧(二):Dropout()方法

简介: 异常数据的特点:与主流样本中的规律不同,在一个样本中出现的概率要比主流数据出现的概率低很多。在每次训练中,忽略模型中一些节点,将小概率的异常数据获得学习的机会变得更低。这样,异常数据对模型的影响就会更小。

学你好!本文章于2021年末编写,获得广泛的好评!


故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现,


Pytorch深度学习·理论篇(2023版)目录地址为:


CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录


本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!

https://v9999.blog.csdn.net/article/details/127587345


欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~


d2ae5e198a2d45428a186cb393d70896.png


1 Dropout方法


20180619185225799.png


2.1 Dropout原理


在训练过程中,每次随机选择一部分节点不去进行学习。


2.1.1 从Dropout原理来看过拟合的原因


任何一个模型不能完全把数据分开,在某一类中一定会有一些异常数据,过拟合的问题恰恰是把这些异常数据当成规律来学习了。


2.1.2 异常数据的特点


异常数据的特点:与主流样本中的规律不同,在一个样本中出现的概率要比主流数据出现的概率低很多。在每次训练中,忽略模型中一些节点,将小概率的异常数据获得学习的机会变得更低。这样,异常数据对模型的影响就会更小。


2.1.3 Dropout的缺陷


Dropout会使一部分节点不去学习,所以在增加模型的泛化能力的同时,会使学习速度隆低。这注意样会使模型不太容易学成,于是在使用的过程中需要令理地进行调节,也就是确定到底丢弃多少节点。注意,并不是丢弃的节点越多越好。


2.2 Dropout的实现


2.2.1 Dropout的实现


  • Dropout:对一维的线性数据进行Dropout处理,输入形状是[N,D](N代表次数D代表数据数)。


  • Dropout2D:对二维的平面数据进行Dropout处理,输入形状是[N,C,H,W]和(N代表批次数,C代表通道数,H代表高度,W代表宽度),系统将对整个通道随机设为0。


  • Dropout3D:对三维的立体数据进行Dropout处理,输入形状是[N,C,D,H,W](N代表批次数,C代表通道数,D代表深度,H代表高度,W代表宽度),系统将对整个通道随机设为0。


2.2.2 Dropout函数定义(基于函数形式)


torch.nn.functional.dropout(input,p=0.5,training=False,inplace=False)


  • input:代表输入的模型节点。


  • p:表示丢弃率。如果参数值为1,那么表示全部丢弃(置0)。该参数默认值是0.5,表示丢弃50%的节点。


  • training:表示该函数当前的使用状态。如果参数值是False,那么表明不在训练状态使用,这时将不丢弃任何节点。


  • inplace:表示是否改变输入值,默认是False。


2.2.3 Dropout函数使用的注意事项


  • Dropout改变了神经网络的网络结构,它仅仅是属于训练时的方法。


  • 进行测试时,一般要将函效Dropout的trainimg参数变为False,表示不需要进行丢弃。否则会影响模型的型常输出。


  • 在使用类的方式调用Dropout时,没有training参数,因为Dropout实例化对象会根据模型本身的调用方式来自动调节training参数。

2.3 通过Dropout改善模型的过拟合状况


2.3.1 修改上篇文章中的# 2 搭建网络模型部分


# 2 搭建网络模型
# model = LogicNet(inputdim=2,hiddendim=500,outputdim=2) # 实例化模型,增加拟合能力将hiddendim赋值为500
# 替换为
class Logic_Dropout_Net(LogicNet):
    def __init__(self,inputdim,hiddendim,outputdim):
        super(Logic_Dropout_Net, self).__init__(inputdim,hiddendim,outputdim)
        # 方法2:使用类的方法实现步骤1
        #self.dropout = nn.Dropout(p=0.07)
    def forward(self,x):
        x = self.Linear1(x)
        x = torch.tanh(x)
        # 方法1 使用函数的方式实现
        x = nn.functional.dropout(x,p=0.01,training=self.training)
        # 方法2:使用类的方法实现步骤2
        # x = self.dropout(x)
        x = self.Linear2(x)
        return x
model = Logic_Dropout_Net(inputdim=2,hiddendim=500,outputdim=2) # 初始化模型


2.3.2 Dropout方法---代码总览


Dropout01.py


import sklearn.datasets
import torch
import numpy as np
import  matplotlib.pyplot as plt
from torch import nn
from LogicNet_fun import LogicNet,moving_average,predict,plot_decision_boundary
# 1 构建数据集
np.random.seed(0) # 设置随机数种子
X , Y =sklearn.datasets.make_moons(40,noise=0.2) # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y==0),axis=1) # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y==1),axis=1) # 获取第2组数据索引
# 显示数据
plt.title("train moons data")
plt.scatter(X[arg,0],X[arg,1],s=100,c='b',marker='+',label = 'data1')
plt.scatter(X[arg2,0],X[arg2,1],s=40,c='r',marker='o',label = 'data2')
plt.legend()
plt.show()
# 2 搭建网络模型
# model = LogicNet(inputdim=2,hiddendim=500,outputdim=2) # 实例化模型,增加拟合能力将hiddendim赋值为500
# 替换为
class Logic_Dropout_Net(LogicNet):
    def __init__(self,inputdim,hiddendim,outputdim):
        super(Logic_Dropout_Net, self).__init__(inputdim,hiddendim,outputdim)
        # 方法2:使用类的方法实现步骤1
        #self.dropout = nn.Dropout(p=0.07)
    def forward(self,x):
        x = self.Linear1(x)
        x = torch.tanh(x)
        # 方法1 使用函数的方式实现
        x = nn.functional.dropout(x,p=0.01,training=self.training)
        # 方法2:使用类的方法实现步骤2
        # x = self.dropout(x)
        x = self.Linear2(x)
        return x
model = Logic_Dropout_Net(inputdim=2,hiddendim=500,outputdim=2) # 初始化模型
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器:反向传播过程中使用。
# 3 训练模型+训练过程loss可视化
xt = torch.from_numpy(X).type(torch.FloatTensor) # 将numpy数据转化为张量
yt = torch.from_numpy(Y).type(torch.LongTensor) # 将numpy数据转化为张量
epochs = 1000 # 定义迭代次数
losses = [] # 损失值列表
for i in range(epochs):
    loss = model.getloss(xt,yt)
    losses.append(loss.item()) # 保存损失值中间状态
    optimizer.zero_grad() # 清空梯度
    loss.backward() # 反向传播损失值
    optimizer.step() # 更新参数
avgloss = moving_average(losses) # 获得损失值的移动平均值
plt.figure(1)
plt.subplot(211)
plt.xlabel('step number')
plt.ylabel('Training loss')
plt.title('step number vs Training loss')
plt.show()
# 4 模型结果可视化,观察过拟合现象
plot_decision_boundary(lambda x: predict(model,x),X,Y)
from sklearn.metrics import accuracy_score
print("训练时的准确率",accuracy_score(model.predict(xt),yt))
# 重新生成两组半圆数据
Xtest,Ytest = sklearn.datasets.make_moons(80,noise=0.2)
plot_decision_boundary(lambda x: predict(model,x),Xtest,Ytest)
Xtest_t = torch.from_numpy(Xtest).type(torch.FloatTensor) # 将numpy数据转化为张量
Ytest_t = torch.from_numpy(Ytest).type(torch.LongTensor)
print("测试时准确率",accuracy_score(model.predict(Xtest_t),Ytest_t))


LogicNet_fun.py


import torch.nn as nn #引入torch网络模型库
import torch
import numpy as np
import matplotlib.pyplot as plt
# 1.2 定义网络模型
class LogicNet(nn.Module): #继承nn.Module类,构建网络模型
    def __init__(self,inputdim,hiddendim,outputdim): #初始化网络结构 ===》即初始化接口部分
        super(LogicNet,self).__init__()
        self.Linear1 = nn.Linear(inputdim,hiddendim) #定义全连接层
        self.Linear2 = nn.Linear(hiddendim,outputdim) #定义全连接层
        self.criterion = nn.CrossEntropyLoss() #定义交叉熵函数
    def forward(self,x):# 搭建用两个全连接层组成的网络模型 ===》 即正向接口部分:将网络层模型结构按照正向传播的顺序搭建
        x = self.Linear1(x)# 将输入传入第一个全连接层
        x = torch.tanh(x)# 将第一个全连接层的结果进行非线性变化
        x = self.Linear2(x)# 将网络数据传入第二个全连接层
        return x
    def predict(self,x):# 实现LogicNet类的预测窗口 ===》 即预测接口部分:利用搭建好的正向接口,得到模型预测结果
        #调用自身网络模型,并对结果进行softmax()处理,分别的出预测数据属于每一个类的概率
        pred = torch.softmax(self.forward(x),dim=1)# 将正向结果进行softmax(),分别的出预测结果属于每一个类的概率
        return torch.argmax(pred,dim=1)# 返回每组预测概率中最大的索引
    def getloss(self,x,y):# 实现LogicNet类的损失值接口 ===》 即损失值计算接口部分:计算模型的预测结果与真实值之间的误差,在反向传播时使用
        y_pred = self.forward(x)
        loss = self.criterion(y_pred,y)# 计算损失值的交叉熵
        return loss
# 1.5 训练可视化
def moving_average(a,w=10): #计算移动平均损失值
    if len(a) < w:
        return a[:]
    return [val if idx < w else sum(a[(idx - w):idx]) / w for idx, val in enumerate(a)]
def moving_average_to_simp(a,w=10): #
    if len(a) < w:
        return a[:]
    val_list = []
    for idx, val in enumerate(a):
        if idx < w:# 如果列表 a 的下标小于 w, 直接将元素添加进 xxx 列表
            val_list.append(val)
        else:#  向前取 10 个元素计算平均值, 添加到 xxx 列表
            val_list.append(sum(a[(idx - w):idx]) / w)
def plot_losses(losses):
    avgloss = moving_average(losses)#获得损失值的移动平均值
    plt.figure(1)
    plt.subplot(211)
    plt.plot(range(len(avgloss)),avgloss,'b--')
    plt.xlabel('step number')
    plt.ylabel('Training loss')
    plt.title('step number vs Training loss')
    plt.show()
# 1.7 数据可视化模型
def predict(model,x): #封装支持Numpy的预测接口
    x = torch.from_numpy(x).type(torch.FloatTensor)
    model = LogicNet(inputdim=2, hiddendim=3, outputdim=2)
    ans = model.predict(x)
    return ans.numpy()
def plot_decision_boundary(pred_func,X,Y): #在直角模型中实现预测结果的可视化
    #计算范围
    x_min ,x_max = X[:,0].min()-0.5 , X[:,0].max()+0.5
    y_min ,y_max = X[:,1].min()-0.5 , X[:,1].max()+0.5
    h=0.01
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    #根据数据输入进行预测
    Z = pred_func(np.c_[xx.ravel(),yy.ravel()])
    Z = Z.reshape(xx.shape)
    #将数据的预测结果进行可视化
    plt.contourf(xx,yy,Z,cmap=plt.cm.Spectral)
    plt.title("Linear predict")
    arg = np.squeeze(np.argwhere(Y==0),axis=1)
    arg2 = np.squeeze(np.argwhere(Y==1),axis=1)
    plt.scatter(X[arg,0],X[arg,1],s=100,c='b',marker='+')
    plt.scatter(X[arg2,0],X[arg2,1],s=40,c='r',marker='o')
    plt.show()


2.4 全连接网络与泛化能力


  • 全连接网络是一个通用的近似框架。只要有足够多的神经元、即使只有一个隐藏层的整网络,利用常用的Sigmoid、ReLU等激活函数,就可以无限逼近任何连续函数。


  • 浅层的网络具有更好的拟合能力,但是泛化能力相对较弱。


  • 深层的网络具有更好的泛化能力,但是拟合能力相对较弱。


2.4.1 wide_deep模型


wide_deep模型就是利用了深层网络与浅层网络的特征实现的组合模型,该模型由以下两个模型的输出结果叠加而成。


   wide模型是一个单层线性模型(浅层全连接网络模型)。


   deep模型是一个深度的全连接模型(深层全连接网络模型)。

目录
相关文章
|
3月前
|
机器学习/深度学习 算法 调度
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
398 0
|
2月前
|
机器学习/深度学习 数据可视化 网络架构
PINN训练新思路:把初始条件和边界约束嵌入网络架构,解决多目标优化难题
PINNs训练难因多目标优化易失衡。通过设计硬约束网络架构,将初始与边界条件内嵌于模型输出,可自动满足约束,仅需优化方程残差,简化训练过程,提升稳定性与精度,适用于气候、生物医学等高要求仿真场景。
368 4
PINN训练新思路:把初始条件和边界约束嵌入网络架构,解决多目标优化难题
|
2月前
|
机器学习/深度学习 算法
采用蚁群算法对BP神经网络进行优化
使用蚁群算法来优化BP神经网络的权重和偏置,克服传统BP算法容易陷入局部极小值、收敛速度慢、对初始权重敏感等问题。
339 5
|
2月前
|
机器学习/深度学习 数据采集 人工智能
深度学习实战指南:从神经网络基础到模型优化的完整攻略
🌟 蒋星熠Jaxonic,AI探索者。深耕深度学习,从神经网络到Transformer,用代码践行智能革命。分享实战经验,助你构建CV、NLP模型,共赴二进制星辰大海。
|
2月前
|
机器学习/深度学习 人工智能 算法
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
165 0
|
2月前
|
机器学习/深度学习 数据采集 边缘计算
基于灰色神经网络的预测方法
基于灰色神经网络的预测方法
178 0
|
3月前
|
机器学习/深度学习 并行计算 算法
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
|
3月前
|
机器学习/深度学习 编解码 并行计算
【创新未发表!】基于BKA算法优化-BP、HO算法优化-BP、CP算法优化-BP、GOOSE算法优化-BP、NRBO算法优化-BP神经网络回归预测比较研究(Matlab代码)
【创新未发表!】基于BKA算法优化-BP、HO算法优化-BP、CP算法优化-BP、GOOSE算法优化-BP、NRBO算法优化-BP神经网络回归预测比较研究(Matlab代码)
209 0
|
3月前
|
机器学习/深度学习 算法 PyTorch
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
189 0
|
3月前
|
机器学习/深度学习 传感器 数据采集
基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)
基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)
632 0

热门文章

最新文章

推荐镜像

更多