MXNET:丢弃法

除了前面介绍的权重衰减以外,深度学习模型常常使用丢弃法(dropout)来应对过拟合问题。

方法与原理

为了确保测试模型的确定性,丢弃法的使用只发生在训练模型时,并非测试模型时。当神经网络中的某一层使用丢弃法时,该层的神经元将有一定概率被丢弃掉。

设丢弃概率为 $p$。具体来说,该层任一神经元在应用激活函数后,有 $p$ 的概率自乘 0,有 $1−p$ 的概率自除以 $1−p$ 做拉伸。丢弃概率是丢弃法的超参数。

多层感知机中,隐层节点的输出:

$$h_i = \phi(x_1 w_1^{(i)} + x_2 w_2^{(i)} + x_3 w_3^{(i)} + x_4 w_4^{(i)} + b^{(i)}),$$

设丢弃概率为 $p$,并设随机变量$\xi_i$ 有 $p$ 概率为 0,有 $1−p$ 概率为 1。那么,使用丢弃法的隐藏单元 $h_i$ 的计算表达式变为

$$h_i = \frac{\xi_i}{1-p} \phi(x_1 w_1^{(i)} + x_2 w_2^{(i)} + x_3 w_3^{(i)} + x_4 w_4^{(i)} + b^{(i)}).$$

注意到测试模型时不使用丢弃法。由于 $\mathbb{E} (\frac{\xi_i}{1-p}) =\frac{\mathbb{E}(\xi_i)}{1-p}=1$,同一神经元在模型训练和测试时的输出值的期望不变。

输出层: $$o_1 = \phi(h_1 w_1' + h_2 w_2' + h_3 w_3' + h_4 w_4' + h_5 w_5' + b')$$

都无法过分依赖 $h_1,…,h_5$ 中的任一个。这样通常会造成 $o_1$ 表达式中的权重参数 $w_1',…,w_5'$ 都接近 0。因此,丢弃法可以起到正则化的作用,并可以用来应对过拟合。

实现

按照drop_prob丢弃X中的值。

1def dropout(X, drop_prob): 2 assert 0 <= drop_prob <= 1 3 keep_prob = 1 - drop_prob 4 # 这种情况下把全部元素都丢弃。 5 if keep_prob == 0: 6 return X.zeros_like() 7 mask = nd.random.uniform(0, 1, X.shape) < keep_prob 8 return mask * X / keep_prob

定义网络参数:三层网络结构,针对minst任务。

1num_inputs = 784 2num_outputs = 10 3num_hiddens1 = 256 4num_hiddens2 = 256 5 6W1 = nd.random.normal(scale=0.01, shape=(num_inputs, num_hiddens1)) 7b1 = nd.zeros(num_hiddens1) 8W2 = nd.random.normal(scale=0.01, shape=(num_hiddens1, num_hiddens2)) 9b2 = nd.zeros(num_hiddens2) 10W3 = nd.random.normal(scale=0.01, shape=(num_hiddens2, num_outputs)) 11b3 = nd.zeros(num_outputs) 12 13params = [W1, b1, W2, b2, W3, b3] 14for param in params: 15 param.attach_grad()

将全连接层和激活函数 ReLU 串起来,并对激活函数的输出使用丢弃法。我们可以分别设置各个层的丢弃概率。通常,建议把靠近输入层的丢弃概率设的小一点。网络结构如下:

1drop_prob1 = 0.2 2drop_prob2 = 0.5 3 4def net(X): 5 X = X.reshape((-1, num_inputs)) 6 H1 = (nd.dot(X, W1) + b1).relu() 7 # 只在训练模型时使用丢弃法。 8 if autograd.is_training(): 9 # 在第一层全连接后添加丢弃层。 10 H1 = dropout(H1, drop_prob1) 11 H2 = (nd.dot(H1, W2) + b2).relu() 12 if autograd.is_training(): 13 # 在第二层全连接后添加丢弃层。 14 H2 = dropout(H2, drop_prob2) 15 return nd.dot(H2, W3) + b3

训练和测试:

1num_epochs = 5 2lr = 0.5 3batch_size = 256 4loss = gloss.SoftmaxCrossEntropyLoss() 5train_iter, test_iter = gb.load_data_fashion_mnist(batch_size) 6gb.train_cpu(net, train_iter, test_iter, loss, num_epochs, batch_size, params, 7 lr)

结果输出:

1epoch 1, loss 0.9913, train acc 0.663, test acc 0.931 2epoch 2, loss 0.2302, train acc 0.933, test acc 0.954 3epoch 3, loss 0.1601, train acc 0.953, test acc 0.958 4epoch 4, loss 0.1250, train acc 0.964, test acc 0.973 5epoch 5, loss 0.1045, train acc 0.969, test acc 0.974

Gluon 实现

在训练模型时,Dropout 层将以指定的丢弃概率随机丢弃上一层的输出元素;在测试模型时,Dropout 层并不发挥作用。 使用 Gluon,我们可以更方便地构造多层神经网络并使用丢弃法。

1import sys 2sys.path.append('..') 3import gluonbook as gb 4from mxnet import autograd, gluon, init, nd 5from mxnet.gluon import loss as gloss, nn 6 7drop_prob1 = 0.2 8drop_prob2 = 0.5 9 10net = nn.Sequential() 11net.add(nn.Flatten()) 12net.add(nn.Dense(256, activation="relu")) 13# 在第一个全连接层后添加丢弃层。 14net.add(nn.Dropout(drop_prob1)) 15net.add(nn.Dense(256, activation="relu")) 16# 在第二个全连接层后添加丢弃层。 17net.add(nn.Dropout(drop_prob2)) 18net.add(nn.Dense(10)) 19net.initialize(init.Normal(sigma=0.01))

训练和结果:

1num_epochs = 5 2batch_size = 256 3loss = gloss.SoftmaxCrossEntropyLoss() 4train_iter, test_iter = gb.load_data_fashion_mnist(batch_size) 5 6trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.5}) 7train_iter, test_iter = gb.load_data_fashion_mnist(batch_size) 8gb.train_cpu(net, train_iter, test_iter, loss, num_epochs, batch_size,None, None, trainer) 9# output 10epoch 1, loss 0.9815, train acc 0.668, test acc 0.927 11epoch 2, loss 0.2365, train acc 0.931, test acc 0.952 12epoch 3, loss 0.1634, train acc 0.952, test acc 0.968 13epoch 4, loss 0.1266, train acc 0.963, test acc 0.972 14epoch 5, loss 0.1069, train acc 0.969, test acc 0.976
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap

MXNET:丢弃法 - HelloWorld