多层感知机--防止过拟合的方法

1 权重衰减

为了防止过拟合,要减少模型复杂度。将线性函数权重向量的某个范数度量复杂度,因此将范数作为惩罚项加到最小化损失中。使用L2范数,对权重向量中大分量进行惩罚,使得筛选权重分布均匀的模型,L1范数将模型权重集中一小部分特征。

L2范数惩罚为:torch.sum(w.pow(2))/2

权重衰减被集成到优化算法中,用weight_decay控制

net=nn.Sequential(nn.Linear(num_inputs,1))
for param in net.parameters():
    param.data.normal_()
loss=nn.MSELoss(reduction='none')
num_epochs,lr=100,0.003
trainer=torch.optim.SGD([
         {"param":net[0].weight,"weight_decay":wd},
         {"param":net[0].bias}],lr=lr)

对比没有进行权重衰减的算法:

trainer=torch.optim.SGD(net.parameters(),lr=lr)

对于pytorch中优化器函数感到困惑可以参考这一篇PyTorch: torch.optim 的6种优化器及优化算法介绍_torch.optim.sgd-CSDN博客

torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)

之后常规操作:

for epoch in range(num_epochs):
    for X,y in train_iter:
        trainer.zero_grad()
        l=loss(net(X),y)
        l.mean().backward()
        trainer.step()

2 暂退法

为了让神经网络对噪声稳健,采取对每一层无偏注入噪声。相当于一定概率drop out一些神经元,使得得到的模型不过度依赖任何神经元。暂退法在训练中间使用。

暂退法的从零实现

def dropout_layer(X,dropout):#dropout是概率
    assert 0<=dropout<=1
    if dropout==1:
       return torch.zeros_like(X)
    if dropout==0:
       return X
    mask=(torch.randn(X.shape)>dropout).float()
    return mask*X/(1-dropout)#除以是为了保证均值不变

两种实现方法:

1:

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,num_inputs))))
          if self.training==True:#训练时才使用暂退法
             H1=dropout_layer(H1,dropout1)
          H2=self.relu(self.lin2(H2))
          if self.training==True:#训练时才使用暂退法
             H2=dropout_layer(H2,dropout2)
          out=self.lin3(H2)
          return out


2:

net=nn.Sequential(nn.Flatten(),
       nn.Linear(784,256),
       nn.Relu(),
       nn.Dropout(dropout1),#训练时起作用,测试时不起作用
       nn.Linear(256,256),
       nn.Relu(),
       nn.Dropout(dropout2),
       nn.Linear(256,10))
def init_weight(m):
    if type(m)==nn.Linear:
       nn.init.normal_(m.weight,std=0.01)
net.apply(init_weights);
       

net.apply(init_weights)的作用是将初始化权重函数init_weights应用于神经网络net中的每个线性层(nn.Linear)。具体来说,net.apply(init_weights)会迭代遍历神经网络中的每个模块,并判断其是否为线性层。对于线性层,它会调用init_weights函数来初始化权重。在给定的代码中,init_weights函数会判断输入的模块类型是否为线性层。如果是线性层(nn.Linear),则使用nn.init.normal_来按照指定的均值和标准差进行正态分布的初始化。这里的指定标准差为0.01。通过调用net.apply(init_weights),可以方便地为神经网络中的线性层进行统一的权重初始化操作。这有助于模型在训练过程中更好地收敛,并提高模型的性能。

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值