01
—
什么是Dropout?
简单来说,Dropout是一种训练神经网络时使用的技术,其目的是防止模型过拟合。过拟合,就好比一个人只吃同一种食物,结果营养不均衡,身体机能失调。在AI中,过拟合意味着模型在训练数据上表现很好,但在新的、未见过的数据上表现很差。
—
如何做Dropout?
Dropout 的原理,通俗的来说就是:每次你做决定时,都会随机忽略一些信息。
比如,当你选择穿什么衣服时,你可能会忽略掉衣柜里的一半衣服。Dropout 技术也是这样,它在训练过程中随机“忽略”一些神经元(即“关闭”它们),让它们不参与到当前的前向传播和反向传播中。这样,模型就不能过度依赖任何一个神经元,从而增强了模型的泛化能力。
又比如:你在健身房里,教练对你说:“今天,我们只做一半的深蹲。”你可能会想:“这是什么鬼训练?”
但这就是Dropout的精髓——通过“做一半”来达到更好的效果:来日方长。
看一段代码:
import torch
import torch.nn as nn
x=torch.ones(100)
print(x.shape)
print(x)
output=nn.Dropout(p=0.1)(x)
print(output)
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
x在dropout之后的值为:
tensor([1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 0.0000, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
0.0000, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 0.0000, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 0.0000, 0.0000, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111, 1.1111, 1.1111, 1.1111, 0.0000, 1.1111, 1.1111, 1.1111, 1.1111,
1.1111])
可以看出,有大约10个值被设置为0了,同时其它的值变大了(放大的倍数为1/(1-p)),相当于对数据进行了放大,这也是为了保证输入的均值不变。
我们看一个简单的Dropout在LLM中的应用:
import torch
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fc1=nn.Linear(10,10)
self.dropout=nn.Dropout(p=0.5)
self.fc2=nn.Linear(10,1)
def forward(self,x):
x=torch.relu(self.fc1(x))
x=self.dropout(x)
x=self.fc2(x)
return x
#初始化模型
net=SimpleNet()
#输入数据
x=torch.randn(6,10)
#训练模型
net.train()
print("Train:")
out_train=net(x)
print(f"out_train shape:{out_train.shape}")
print(out_train)
#推理模型
net.eval()
print("Evaluate:")
out_eval=net(x)
print(f"out_eval shape:{out_eval.shape}")
print(out_eval)
另外一个问题 dropout 会应用在推理阶段吗?答案是不会,推理阶段不需要做Dropout。
03
—
Dropout的好处
Dropout的好处:
1)增强泛化能力:就像多样化饮食可以增强身体健康一样,Dropout通过随机“忽略”神经元,让模型学会从不同的数据角度去理解问题,从而增强其在新数据上的泛化能力。
2)减少过拟合:过拟合就像是挑食,只吃自己喜欢的食物,而Dropout就像是强制你尝试各种食物,让你的营养更均衡。
3)提高计算效率:Dropout通过减少模型的复杂度,可以减少训练和预测时的计算量,这就像是通过减少食物摄入量来提高消化效率。
进技术交流群请添加AINLP小助手微信(id: ainlp2)
请备注具体方向+所用到的相关技术点 关于AINLP
AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括LLM、预训练模型、自动生成、文本摘要、智能问答、聊天机器人、机器翻译、知识图谱、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP小助手微信(id:ainlp2),备注工作/研究方向+加群目的。