【神经网络】正则化缓解过拟合-Dropout

🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法,初步涉猎人工智能和前端开发。
🦅个人主页:@逐梦苍穹
📕所属专栏:人工智能
🌻gitee地址:xzl的人工智能代码仓库
✈ 您的一键三连,是我创作的最大动力🌹

1、简介

在训深层练神经网络时,由于模型参数较多,在数据量不足的情况下,很容易过拟合

回顾知识:欠拟合和过拟合-引入正则化:https://xzl-tech.blog.csdn.net/article/details/132799737

Dropout 就是在神经网络中一种缓解过拟合的方法。
实现: 在每次训练过程中,以一定概率 p 随机将一部分神经元的输出设为0,这些被忽略的神经元在当前训练步骤中不参与计算。
image.png
其他正则化方法:

  • Elastic Net:结合了L1和L2正则化,适用于稀疏数据和多重共线性数据。
  • 早停(Early Stopping):在验证集上监控模型性能,当性能不再提升时停止训练。
  • 数据增强(Data Augmentation):通过对训练数据进行随机变换来增加数据量,从而提高模型的泛化能力。

2、Dropout 层的原理和使用

我们知道,缓解过拟合的方式就是降低模型的复杂度,而 Dropout 就是通过减少神经元之间的连接,把稠密的神经网络神经元连接,变成稀疏的神经元连接,从而达到降低网络复杂度的目的。
我们先通过一段代码观察下丢弃层的效果:

# -*- coding: utf-8 -*-
# @Author: CSDN@逐梦苍穹
# @Time: 2024/7/29 3:12

import torch  # 导入PyTorch库
import torch.nn as nn  # 导入PyTorch中的神经网络模块


def test():
    # 初始化丢弃层,丢弃概率为0.8
    dropout = nn.Dropout(p=0.8)
    # 初始化输入数据,随机生成5x8的整数矩阵,并转换为浮点数
    inputs = torch.randint(0, 10, size=[5, 8]).float()
    print("Inputs:")
    print(inputs)  # 打印输入数据
    print('-' * 50)

    # 通过丢弃层处理输入数据
    outputs = dropout(inputs)
    print("Outputs after Dropout:")
    print(outputs)  # 打印输出数据


if __name__ == '__main__':
    test()  # 调用测试函数

程序输出结果:

"C:\Program Files\Python39\python.exe" D:\Python\AI\神经网络\9-正则化Dropout\丢弃层.py 
Inputs:
tensor([[7., 9., 7., 2., 6., 1., 2., 9.],
        [1., 8., 4., 6., 1., 2., 5., 1.],
        [7., 5., 4., 8., 2., 9., 7., 2.],
        [0., 2., 9., 7., 8., 0., 7., 8.],
        [8., 3., 1., 0., 9., 3., 6., 6.]])
--------------------------------------------------
Outputs after Dropout:
tensor([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
        [ 5.,  0.,  0., 30.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0., 40.,  0.,  0., 35.,  0.],
        [ 0., 10.,  0.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  0., 30.,  0.]])

Process finished with exit code 0

我们将 Dropout 层的概率 p 设置为 0.8,此时经过 Dropout 层计算的张量中就出现了很多 0 , 概率 p 设置值越大,则张量中出现的 0 就越多
上面结果的计算过程如下:

  1. 先按照 p 设置的概率,随机将部分的张量元素设置为 0
  2. 为了校正张量元素被设置为 0 带来的影响,需要对非 0 的元素进行缩放,其缩放因子为 1 ( 1 − p ) \frac{1}{(1 - p)} (1p)1,上面代码中 p 的值为 0.8, 根据公式缩放因子为 1 ( 1 − 0.8 ) = 5 \frac{1}{(1 - 0.8)} = 5 (10.8)1=5
  3. 比如:第 3 个元素,原来是 5,乘以缩放因子之后变成 25。

我们也发现了,丢弃概率 p 的值越大,则缩放因子的值就越大,相对其他未被设置的元素就要更多的变大。
丢弃概率 P 的值越小,则缩放因子的值就越小,相对应其他未被置为 0 的元素就要有较小的变大。
当张量某些元素被设置为 0 时,对网络会带来什么影响?
比如上面这种情况,如果输入该样本,会使得某些参数无法更新,请看下面的代码:

# -*- coding: utf-8 -*-
# @Author: CSDN@逐梦苍穹
# @Time: 2024/7/29 3:18
import torch  # 导入PyTorch库
import torch.nn as nn  # 导入PyTorch中的神经网络模块

# 设置随机数种子
torch.manual_seed(0)

def caculate_gradient(x, w):
    # 前向计算 y = x @ w 并求和
    y = x @ w
    y = y.sum()
    # 反向传播计算梯度
    y.backward()
    # 打印梯度
    print('Gradient:', w.grad.reshape(1, -1).squeeze().numpy())

def test01():
    # 初始化权重
    w = torch.randn(15, 1, requires_grad=True)
    # 初始化输入数据
    x = torch.randint(0, 10, size=[5, 15]).float()
    # 计算梯度
    caculate_gradient(x, w)

def test02():
    # 初始化权重
    w = torch.randn(15, 1, requires_grad=True)
    # 初始化输入数据
    x = torch.randint(0, 10, size=[5, 15]).float()
    # 初始化丢弃层,丢弃概率为0.8
    dropout = nn.Dropout(p=0.8)
    # 应用丢弃层
    x = dropout(x)
    # 计算梯度
    caculate_gradient(x, w)

if __name__ == '__main__':
    test01()  # 调用不使用Dropout的测试函数
    print('-' * 70)
    test02()  # 调用使用Dropout的测试函数

程序输出结果:

"C:\Program Files\Python39\python.exe" D:\Python\AI\神经网络\9-正则化Dropout\张量为0对梯度的影响.py 
Gradient: [19. 15. 16. 13. 34. 23. 20. 22. 23. 26. 21. 29. 28. 22. 29.]
----------------------------------------------------------------------
Gradient: [ 5.  0. 35.  0.  0. 45. 40. 40.  0. 20. 25. 45. 55.  0. 10.]

Process finished with exit code 0

注意:

矩阵1 * 矩阵2 为阿达玛积
矩阵1 @ 矩阵2为正常的矩阵乘法

从程序结果来看,是否经过 Dropout 层对梯度的计算产生了不小的影响,
例如:经过 Dropout 层之后有一些梯度为 0,这使得参数无法得到更新,从而达到了降低网络复杂度的目的。

3、小结

dropout 层的使用,其作用用于控制网络复杂度,达到正则化的目的,类似于 L2 正则化对线性回归的作用

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逐梦苍穹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值