一文了解:LLM Dropout

news2024/10/9 20:54:32

咱们来聊聊,啥样的预测模型才算是好模型?简单来说,就是那种在处理它从没见过的数据时,也能表现得特别棒的模型。老派的泛化理论告诉我们,要想让模型在训练集和测试集上都表现差不多,就得让模型简单点。这个简单,可以是参数少一点,还可以权重衰减,其实就是让参数的值别太大,这也是让模型保持简单性的一个好方法。还有一个概念就是平滑性,意思是说,模型对输入数据的小变化应该不那么敏感。比如在图像分类任务中,我们希望即使图像上有点随机噪声,模型也能正确地识别出来。

时间快进到1995年,有个叫克里斯托弗·毕晓普的大佬,他把这种想法变成了数学上的理论。他证明了,如果在训练时给输入数据加上点噪声,这实际上就相当于做了Tikhonov正则化。他的工作把函数需要平滑(也就是简单)的要求,和对输入扰动的抵抗力,这两者之间的数学关系给说清楚了。

然后到了2014年,Srivastava他们想出了一个绝妙的点子,就是怎么把毕晓普的想法用到神经网络的内部层。他们建议在训练的时候,在计算下一层之前,给网络的每一层都注入点噪声。他们发现,这样做可以让深层神经网络的输入输出映射更加平滑。

他们提出的这个点子,叫做Dropout,现在已经成了训练神经网络的标准操作了。这个操作之所以叫dropout,是因为在训练过程中,我们真的会“丢掉”一些神经元。每次迭代的时候,我们会随机把一些节点的输出置为零,这样下一层的计算就不会用到这些节点了。

直白一些,Dropout是深度神经网络里用来防止模型太复杂、记性太好的一种技巧。就像是,我们故意让网络忘记一些东西,这样它就不会把所有的训练数据都记得太死,从而在遇到新数据时能更好地适应。

简单来说,神经网络就像是一堆小团队,每个团队都忙着处理信息。但是,如果每个团队都只关注自己的工作,不跟别人合作,那整个网络处理信息的能力就会受到影响。所以,dropout就是在训练的时候,随机让一些团队暂时离线,这样剩下的团队就得学会在缺少某些信息的情况下工作。

为啥这么做呢?因为我们不想让模型只在训练数据上表现好,而是真的想让它在现实世界中也能派上用场。如果模型对训练数据记得太清楚,它可能就会忽略掉那些它没见过的新信息,这就是所谓的过拟合。Dropout就是通过让网络“忘记”一些信息,来防止这种情况发生的。

Dropout层的意思就是,在神经网络中故意忽略掉一些信息,好让模型不会过于依赖某些特定的数据点。

就好比我们的大脑,随时都在处理一大堆乱七八糟的信息,但不是所有的信息都是重要的。神经网络也是这样,它的每个单元都在忙忙碌碌地接收和发送信息,但这些信息里头,有的是关键的,有的可能就是干扰项。

数据科学家们用dropout这个技巧,就是想在模型学习的过程中,随机地让一些单元不工作,这样就能减少那些干扰项的影响。具体操作起来,他们会在神经网络的不同层用不同的策略来应用dropout:

  1. 输入层:这就像是神经网络的大门,原始数据就是从这儿进来的。如果有些数据跟我们要解决的问题没啥关系,就可以在这儿用dropout忽略掉。

  2. 中间层或隐藏层:这些层就像是神经网络的加工车间,数据进来后在这里经过一系列的处理。但是,这些处理的结果并不都是最终答案,很多都只是半成品。因为这些半成品里头可能包含了不少噪声,所以数据科学家们会在这些层用dropout来减少噪声。

  3. 输出层:这是神经网络给出最终答案的地方,这里的信息都是最重要的,所以通常不会用dropout。

总的来说,dropout就是数据科学家们用来提高模型泛化能力,避免过拟合的一种手段。通过dropout,可以让模型更加专注于学习那些真正重要的信息。

图片

Dropout的实际例子和用场挺多的,我给你举两个例子来说明它是咋回事:

  1. 太空信号监听:想象一下,有个组织专门监控从宇宙深处传来的声音,他们想找的是那些重复的、有规律的信号,因为这可能意味着外星生命的存在。他们把收集到的声音信号送到神经网络里进行分析。在分析前,科学家们会先筛掉那些听起来乱七八糟、没啥规律的声音。同时,他们还会在神经网络的中间处理环节,故意忽略掉一部分数据,这样可以减少计算量,加快找出结果的速度。

  2. 生化公司研发新材料:再比如,有一家生化公司想研发一种全新的塑料。他们已经知道需要哪些基本元素来组成这种塑料,但具体的配方还不知道。为了节省研究时间和计算资源,他们用了一个神经网络来筛选全球的相关研究资料,但这个网络只关注那些直接和这种分子及其元素有关的研究,其他不相关的信息都会被自动过滤掉。这样做的好处是,他们的AI模型就不会出现过拟合,也就是不会因为数据太杂太乱而做出错误的预测。

最后来聊聊大型语言模型里怎么用dropout来帮忙模型学得更好?

首先,咱们得决定在哪里加dropout。通常是在词嵌入完了之后、每个处理层(比如Transformer或RNN)之后,有时候甚至在输出前也会加一点。

接下来,得挑个合适的dropout率,这个得靠试。一般这个率在0.1到0.5之间,每层可能还不一样,有时候中间那些层可能需要更大一点。

然后,得多做实验,用交叉验证来看看不同的dropout率哪个最好。这个过程可以用些自动化的工具来帮忙。

训练的时候,每次都得随机让一些神经元不工作,但测试的时候就全用上,这样模型就能好好表现了。

如果是特别大的模型,可能得多用点dropout,因为大模型容易记住太多东西,不太容易适应新情况。

dropout还可以和其他方法一起用,比如让权重小一点或者用更多的数据,这样模型能更好地适应各种情况。

训练的时候得看着点,比如损失是不是小了,准确率是不是高了,这些都是dropout有没有用的信号。

还可以用些工具来搞清楚dropout到底是咋帮忙的。

最后,训练和测试的时候dropout得保持一致,别一会儿用一会儿不用的。

用dropout就是为了让模型别太死记硬背,碰到新情况也能应对。这个得好好调调,确保它真能帮上忙,但又不会让模型学得太差。

接下来,我们分别用mxnet,pytorch 及 tensorflow 来简单以代码的方式来从头开始实现一下,注意不保证代码的完整性,只做参考。

要实现单层的dropout函数,我们必须根据层的维度从伯努利(二元)随机变量中抽取尽可能多的样本,其中随机变量以概率(1-p)取值(1)(保留)和概率(p)取值(0)(丢弃)。一种简单的实现方法是首先从均匀分布(U[0, 1])中抽取样本。然后我们可以保留对应样本大于(p)的节点,丢弃其余的。

在下面的代码中,我们实现了一个dropout_layer函数,它以概率dropout丢弃张量输入X中的元素,然后按照上述描述重新缩放剩余部分:将幸存者除以1.0-dropout

from mxnet import autograd, gluon, init, np, npx
from mxnet.gluon import nn
from d2l import mxnet as d2l

npx.set_np()

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在这种情况下,所有元素都被丢弃
    if dropout == 1:
        return np.zeros_like(X)
    # 在这种情况下,所有元素都被保留
    if dropout == 0:
        return X
    mask = np.random.uniform(0, 1, X.shape) > dropout
    return mask.astype(np.float32) * X / (1.0 - dropout)
import torch
from torch import nn
from d2l import torch as d2l

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在这种情况下,所有元素都被丢弃
    if dropout == 1:
        return torch.zeros_like(X)
    # 在这种情况下,所有元素都被保留
    if dropout == 0:
        return X
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)
import tensorflow as tf
from d2l import tensorflow as d2l

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在这种情况下,所有元素都被丢弃
    if dropout == 1:
        return tf.zeros_like(X)
    # 在这种情况下,所有元素都被保留
    if dropout == 0:
        return X
    mask = tf.random.uniform(
        shape=tf.shape(X), minval=0, maxval=1) < 1 - dropout
    return tf.cast(mask, dtype=tf.float32) * X / (1.0 - dropout)

我们可以在一些示例上测试dropout_layer函数。在下面的代码行中,我们以概率0、0.5和1通过dropout操作传递我们的输入X

X = np.arange(16).reshape(2, 8)
print(dropout_layer(X, 0))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1))
X= torch.arange(16, dtype = torch.float32).reshape((2, 8))
print(X)
print(dropout_layer(X, 0.))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1.))
X = tf.reshape(tf.range(16, dtype=tf.float32), (2, 8))
print(X)
print(dropout_layer(X, 0.))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1.))

接下来,定义模型参数,我们可以使用Fashion-MNIST数据集。下面定义了一个具有两个隐藏层,每个隐藏层包含256个单元的MLP。

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

W1 = np.random.normal(scale=0.01, size=(num_inputs, num_hiddens1))
b1 = np.zeros(num_hiddens1)
W2 = np.random.normal(scale=0.01, size=(num_hiddens1, num_hiddens2))
b2 = np.zeros(num_hiddens2)
W3 = np.random.normal(scale=0.01, size=(num_hiddens2, num_outputs))
b3 = np.zeros(num_outputs)

params = [W1, b1, W2, b2, W3, b3]
for param in params:
    param.attach_grad()
num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
num_outputs, num_hiddens1, num_hiddens2 = 10, 256, 256

这个时候,可以定义模型了。

下面的模型在每个隐藏层的输出(激活函数之后)应用dropout。我们可以为每层分别设置dropout概率。一个常见的趋势是在接近输入层的地方设置较低的dropout概率。下面我们将第一层和第二层的dropout概率分别设置为0.2和0.5。我们确保dropout只在训练期间激活。

dropout1, dropout2 = 0.2, 0.5

def net(X):
    X = X.reshape(-1, num_inputs)
    H1 = npx.relu(np.dot(X, W1) + b1)
    # 仅在训练模型时使用dropout
    if autograd.is_training():
        # 在第一个全连接层之后添加一个dropout层
        H1 = dropout_layer(H1, dropout1)
    H2 = npx.relu(np.dot(H1, W2) + b2)
    if autograd.is_training():
        # 在第二个全连接层之后添加一个dropout层
        H2 = dropout_layer(H2, dropout2)
    return np.dot(H2, W3) + b3
dropout1, dropout2 = 0.2, 0.5

class Net(nn.Module):
    def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,
                 is_training = True):
        super(Net, self).__init__()
        self.num_inputs = num_inputs
        self.training = is_training
        self.lin1 = nn.Linear(num_inputs, num_hiddens1)
        self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)
        self.lin3 = nn.Linear(num_hiddens2, num_outputs)
        self.relu = nn.ReLU()

    def forward(self, X):
        H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))
        # 仅在训练模型时使用dropout
        if self.training == True:
            # 在第一个全连接层之后添加一个dropout层
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.training == True:
            # 在第二个全连接层之后添加一个dropout层
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out

net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)
dropout1, dropout2 = 0.2, 0.5

class Net(tf.keras.Model):
    def __init__(self, num_outputs, num_hiddens1, num_hiddens2):
        super().__init__()
        self.input_layer = tf.keras.layers.Flatten()
        self.hidden1 = tf.keras.layers.Dense(num_hiddens1, activation='relu')
        self.hidden2 = tf.keras.layers.Dense(num_hiddens2, activation='relu')
        self.output_layer = tf.keras.layers.Dense(num_outputs)

    def call(self, inputs, training=None):
        x = self.input_layer(inputs)
        x = self.hidden1(x)
        if training:
            x = dropout_layer(x, dropout1)
        x = self.hidden2(x)
        if training:
            x = dropout_layer(x, dropout2)
        x = self.output_layer(x)
        return x

net = Net(num_outputs, num_hiddens1, num_hiddens2)

最后,进行训练和测试。

num_epochs, lr, batch_size = 10, 0.5, 256
loss = gluon.loss.SoftmaxCrossEntropyLoss()
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,
              lambda batch_size: d2l.sgd(params, lr, batch_size))
num_epochs, lr, batch_size = 10, 0.5, 256
loss = nn.CrossEntropyLoss(reduction='none')
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
num_epochs, lr, batch_size = 10, 0.5, 256
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
trainer = tf.keras.optimizers.SGD(learning_rate=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

图片

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2199988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

以一个B站必剪应用Bug过一下CVSS 4.0评分

Bug的内容就是Mac上的必剪无法完成B站视频上传新手任务。 这个从B站客服那里确认了。 没多大事儿,这是个设备相关的bug,我们也可以认为这样的小bug对用户是无害的,此时评分为0,无影响,但从学习角度出发我们将部分评分提高到L,也就是假设这是个CVE的话,聊一下安全问题。…

为什么推荐你一定要弄懂千门八将108局,学会做局思维的人有多么的厉害?

在纷繁复杂的社会与商业环境中&#xff0c;能够洞悉事物本质、预见趋势并巧妙布局的人&#xff0c;往往能在竞争中脱颖而出&#xff0c;成为时代的弄潮儿。而“千门八将108局”这一古老而深邃的智慧体系&#xff0c;不仅蕴含了中国传统文化中对于策略、心理学、人际交往的深刻理…

Java 集合实现类

Java 集合实现类 ​ Java 提供了一套实现了 Collection 接口的标准集合类。其中一些是具体类&#xff0c;这些类可以直接拿来使用&#xff0c;而另外一些是抽象类&#xff0c;提供了接口的部分实现 序号类描述1AbstractCollection 实现了大部分的集合接口。2AbstractList 继承…

java中日期时间类的api

目录 1. Instant 类 构造方法 1&#xff09;Instant.now()&#xff1a;获取当前时间戳。 常用方法 1&#xff09;plus(Duration duration) 2&#xff09;minus(Duration duration) 3&#xff09;toEpochMilli() 4&#xff09;ofEpochMilli(long epochMilli) 5&#xff09;案例:…

网站建设公司哪家好?好的网站建设公司应该有哪些特别之处?

面对众多的网站建设公司&#xff0c;企业该如何选择呢&#xff1f;如何才能避坑呢&#xff1f;本文将探讨好的网站建设公司应该具备的特别之处 案例&#xff0c;这是最直观的表现&#xff0c;一个好的网站建设公司必然拥有为数众多的的案例展示&#xff0c;且这些案例质量高&a…

基于resnet网络【系列】多类别图像识别、迁移学习:猫狗分类实战

目录 1、前言 2、resnet 猫狗分类实战 2.1 训练 2.2 推理 3、更换数据集训练 1、前言 ResNet&#xff08;残差网络&#xff09;是一种深度卷积神经网络架构&#xff0c;广泛用于图像分类任务。它是由微软研究院的研究人员于2015年推出的&#xff0c;以其通过使用残差连接…

Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)

引言 想象一下&#xff0c;只要描述你想要的画面&#xff0c;电脑就能帮你画出来。这在几年前还像是科幻小说里的场景&#xff0c;但随着神经网络和潜在扩散模型&#xff08;LDM&#xff09;技术的发展&#xff0c;现在已经成为可能。OpenAI 推出的 DALLE 工具&#xff0c;因其…

vue项目刷新后h5样式失效

vue项目刷新后h5样式失效 今天遇到一个bug&#xff0c;有一个Element的message组件&#xff0c;用它做的一个进度条&#xff0c;它是写在一个页面上&#xff0c;并且是用js控制dom元素的 web端一切正常&#xff0c;h5如果从别的页面跳过来也正常&#xff0c;但是&#xff0c;H…

服装生产管理:SpringBoot框架的高效策略

5 系统的实现 5.1 登录界面的实现 用户要想进入本系统必须进行登录操作&#xff0c;进入对应角色登录界面&#xff0c;在登录界面输入系统账号、登录密码&#xff0c;选择登录类型&#xff0c;点击登录按钮进行登录系统&#xff0c;管理员登录界面展示如图5-1所示&#xff0c…

【STM32开发之寄存器版】(八)-定时器的编码器接口模式

一、前言 1.1 编码器接口原理 编码器模式主要用于检测旋转编码器的转动方向和转动速度。旋转编码器一般输出两路相位相差90度的脉冲信号&#xff08;称为A相和B相&#xff09;&#xff0c;通过这两路信号&#xff0c;定时器可以判断编码器的旋转方向&#xff0c;并计数转动的脉…

嵌入式学习-线性表Day03-栈

嵌入式学习-线性表Day03-栈 栈 顺序栈 2&#xff09;入栈 3&#xff09;出栈 链式栈 栈 什么是栈? 只能在一端进行插入和删除操作的线性表&#xff08;又称为堆栈&#xff09;&#xff0c;进行插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底 栈特点&#xff1a; 先进…

儿童(青少年)可以参加哪些含金量高的比赛?

随着素质教育的推进&#xff0c;越来越多的家长和老师开始关注如何培养孩子的综合素质和能力。而参加各类比赛&#xff0c;不仅可以锻炼孩子的思维、动手能力和团队合作精神&#xff0c;还能帮助孩子在学习的过程中找到兴趣点和成就感。尤其是一些含金量高的比赛&#xff0c;不…

什么是静态加载-前端

什么是前端静态加载 在前端开发中&#xff0c;静态加载是一种常见且重要的技术。简单来说&#xff0c;前端静态加载指的是在页面加载时将所需的资源&#xff08;如HTML、CSS、JavaScript、图片等&#xff09;一并加载到用户的浏览器中。这种方式有助于提高页面的加载速度和用户…

【宽搜】6. leetcode 513 找树左下角的值

1 题目描述 题目链接&#xff1a;找树左下角的值 2 题目解析 思路&#xff1a; 可以使用 层序遍历&#xff0c; 将每一层的值都存入到一个vector< int> 中&#xff0c;当这一层是最后一层的时候&#xff0c;将vector< int>中的第一个值返回即可。 3 代码 cla…

RemoteView(kotlin)

使用场景&#xff1a;通知栏&桌面部件 自定义通知栏 通知权限申请 manifest配置 <uses-permission android:name"android.permission.POST_NOTIFICATIONS" />权限动态申请 package com.example.kotlinlearn.Common;import android.Manifest; import an…

国产长芯微LDUM8801光耦兼容的单通道隔离式栅极驱动器P2P替代UCC23513 FOD8342 TLP5751成本低,质量更好

描述 LDUM8801是单通道兼容光耦输入的隔离式栅极驱动器&#xff0c;可应用于驱动IGBT、SiC 和 MOSFET。它可以提供5A的峰值拉/灌电流。支持150kV/μs的最小共模瞬态免疫&#xff08;CMTI&#xff09;&#xff0c;确保了系统的鲁棒性。驱动器的最大电源电压为32V。 其与光耦式栅…

【计网】【计网】从零开始学习http协议 ---理解http重定向和请求方法

去光荣地受伤&#xff0c; 去勇敢地痊愈自己。 --- 简嫃 《水问》--- 从零开始学习http协议 1 知识回顾2 认识网络重定向3 http请求方法3.1 http常见请求方法3.2 postman工具进行请求3.3 处理GET和POST参数 1 知识回顾 前面两篇文章中我们学习并实现了http协议下的请求与应…

【LeetCode】每日一题 2024_10_9 找到按位或最接近 K 的子数组(LogTrick、位运算)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;找到按位或最接近 K 的子数组 代码与解题思路 今天是 2100 的题目&#xff0c;难度略高&#xff0c;不在我的能力范围&#xff0c;推荐题解&#xff1a;两种方法&#xff1a;LogTrick/滑…

设计模式——门面模式 | 外观模式

哈喽&#xff0c;各位盆友们&#xff01;我是你们亲爱的学徒小z&#xff0c;今天给大家分享的文章是设计模式的——门面模式。 文章目录 定义通用类图1.通用结构2.优点3.缺点 使用场景注意事项1.一个子系统可以有多个门面2.门面不参与子系统内的业务逻辑 定义 定义&#xff1a;…

【Flutter】合并多个流Stream

1.说明 无意间发现了一个好用的库rxdart&#xff0c;它为 Dart 的 Stream 添加了额外的功能。 2.功能 &#xff08;1&#xff09;合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意&#xff1a;如果dart文件中同时使用了getx&#xff0c;需要隐…