MXNET:丢弃法
作者:@houkai
本文为作者原创,转载请注明出处:https://www.cnblogs.com/houkai/p/9521030.html
除了前面介绍的权重衰减以外,深度学习模型常常使用丢弃法(dropout)来应对过拟合问题。
方法与原理
为了确保测试模型的确定性,丢弃法的使用只发生在训练模型时,并非测试模型时。当神经网络中的某一层使用丢弃法时,该层的神经元将有一定概率被丢弃掉。
设丢弃概率为 。具体来说,该层任一神经元在应用激活函数后,有 的概率自乘 0,有 的概率自除以 做拉伸。丢弃概率是丢弃法的超参数。
多层感知机中,隐层节点的输出:
设丢弃概率为 ,并设随机变量 有 概率为 0,有 概率为 1。那么,使用丢弃法的隐藏单元 的计算表达式变为
注意到测试模型时不使用丢弃法。由于 ,同一神经元在模型训练和测试时的输出值的期望不变。
输出层:
都无法过分依赖 中的任一个。这样通常会造成 表达式中的权重参数 都接近 0。因此,丢弃法可以起到正则化的作用,并可以用来应对过拟合。
实现
按照drop_prob丢弃X中的值。
def dropout(X, drop_prob):
assert 0 <= drop_prob <= 1
keep_prob = 1 - drop_prob
# 这种情况下把全部元素都丢弃。
if keep_prob == 0:
return X.zeros_like()
mask = nd.random.uniform(0, 1, X.shape) < keep_prob
return mask * X / keep_prob
定义网络参数:三层网络结构,针对minst任务。
num_inputs = 784
num_outputs = 10
num_hiddens1 = 256
num_hiddens2 = 256
W1 = nd.random.normal(scale=0.01, shape=(num_inputs, num_hiddens1))
b1 = nd.zeros(num_hiddens1)
W2 = nd.random.normal(scale=0.01, shape=(num_hiddens1, num_hiddens2))
b2 = nd.zeros(num_hiddens2)
W3 = nd.random.normal(scale=0.01, shape=(num_hiddens2, num_outputs))
b3 = nd.zeros(num_outputs)
params = [W1, b1, W2, b2, W3, b3]
for param in params:
param.attach_grad()
将全连接层和激活函数 ReLU 串起来,并对激活函数的输出使用丢弃法。我们可以分别设置各个层的丢弃概率。通常,建议把靠近输入层的丢弃概率设的小一点。网络结构如下:
drop_prob1 = 0.2
drop_prob2 = 0.5
def net(X):
X = X.reshape((-1, num_inputs))
H1 = (nd.dot(X, W1) + b1).relu()
# 只在训练模型时使用丢弃法。
if autograd.is_training():
# 在第一层全连接后添加丢弃层。
H1 = dropout(H1, drop_prob1)
H2 = (nd.dot(H1, W2) + b2).relu()
if autograd.is_training():
# 在第二层全连接后添加丢弃层。
H2 = dropout(H2, drop_prob2)
return nd.dot(H2, W3) + b3
训练和测试:
num_epochs = 5
lr = 0.5
batch_size = 256
loss = gloss.SoftmaxCrossEntropyLoss()
train_iter, test_iter = gb.load_data_fashion_mnist(batch_size)
gb.train_cpu(net, train_iter, test_iter, loss, num_epochs, batch_size, params,
lr)
结果输出:
epoch 1, loss 0.9913, train acc 0.663, test acc 0.931
epoch 2, loss 0.2302, train acc 0.933, test acc 0.954
epoch 3, loss 0.1601, train acc 0.953, test acc 0.958
epoch 4, loss 0.1250, train acc 0.964, test acc 0.973
epoch 5, loss 0.1045, train acc 0.969, test acc 0.974
Gluon 实现
在训练模型时,Dropout 层将以指定的丢弃概率随机丢弃上一层的输出元素;在测试模型时,Dropout 层并不发挥作用。
使用 Gluon,我们可以更方便地构造多层神经网络并使用丢弃法。
import sys
sys.path.append('..')
import gluonbook as gb
from mxnet import autograd, gluon, init, nd
from mxnet.gluon import loss as gloss, nn
drop_prob1 = 0.2
drop_prob2 = 0.5
net = nn.Sequential()
net.add(nn.Flatten())
net.add(nn.Dense(256, activation="relu"))
# 在第一个全连接层后添加丢弃层。
net.add(nn.Dropout(drop_prob1))
net.add(nn.Dense(256, activation="relu"))
# 在第二个全连接层后添加丢弃层。
net.add(nn.Dropout(drop_prob2))
net.add(nn.Dense(10))
net.initialize(init.Normal(sigma=0.01))
训练和结果:
num_epochs = 5
batch_size = 256
loss = gloss.SoftmaxCrossEntropyLoss()
train_iter, test_iter = gb.load_data_fashion_mnist(batch_size)
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.5})
train_iter, test_iter = gb.load_data_fashion_mnist(batch_size)
gb.train_cpu(net, train_iter, test_iter, loss, num_epochs, batch_size,None, None, trainer)
# output
epoch 1, loss 0.9815, train acc 0.668, test acc 0.927
epoch 2, loss 0.2365, train acc 0.931, test acc 0.952
epoch 3, loss 0.1634, train acc 0.952, test acc 0.968
epoch 4, loss 0.1266, train acc 0.963, test acc 0.972
epoch 5, loss 0.1069, train acc 0.969, test acc 0.976
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架