【PyTorch 深度学习】6.PyTorch理解更多神经网络优化方法

1.了解不同的优化器

关于各种优化器的理解和选择问题,可以看我之前写的这篇博客:
https://blog.csdn.net/qq_40314507/article/details/79933289

2.书写优化器代码

我们分别用SGD,Momentum,RMSprop,Adam作为优化器,训练前面几篇博客的数据,看看效果如何。

2.1定义网络

代码如下:

class module_net(nn.Module):
    def __init__(self, num_input, num_hidden, num_output):
        super(module_net, self).__init__()
        self.layer1 = nn.Linear(num_input, num_hidden)
        
        self.layer2 = nn.ReLU()
        
        self.layer3 = nn.Linear(num_hidden, num_hidden)
        
        self.dropout3 = nn.Dropout(p=0.5)

        self.layer4 = nn.ReLU()

        self.layer5 = nn.Linear(num_hidden, num_hidden)

        self.dropout5 = nn.Dropout(p=0.5)

        self.layer6 = nn.ReLU()
        
        self.layer7 = nn.Linear(num_hidden, num_output)
        
        
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.dropout3(x)
        x = self.layer4(x)
        x = self.layer5(x)
        x = self.dropout5(x)
        x = self.layer6(x)
        x = self.layer7(x)
        
        return x

2.2为每个优化器创建一个网络类

为了对比每一种优化器, 我们给他们各自创建一个神经网络, 但这个神经网络都来自同一个 Net 形式.

net_SGD         = module_net(8,10,1)
net_Momentum    = module_net(8,10,1)
net_RMSprop     = module_net(8,10,1)
net_Adam        = module_net(8,10,1)
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]

2.3创建不同的优化器

接下来在创建不同的优化器, 用来训练不同的网络. 并创建一个 loss_func 用来计算误差. 我们用几种常见的优化器, SGD , Momentum , RMSprop , Adam .

opt_SGD         = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum    = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop     = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam        = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))

loss_func = torch.nn.MSELoss()
losses_his = [[], [], [], []]   # 记录 training 时不同神经网络的 loss
Accuracy_list = [[],[],[],[]]   # 记录 training 时不同神经网络的 准确率
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]
criterion = nn.BCEWithLogitsLoss().to(device) # CrossEntropyLoss=softmax+cross entropy

2.4初始化正则项

weight_decay=0.01 # 正则化参数
for net  in nets:
    if weight_decay>0:
        reg_loss=Regularization(net, weight_decay, p=2).to(device)
    else:
        print("no regularization")

2.5训练

for e in range(100):
    for net, opt, l_his ,acc_his in zip(nets, optimizers, losses_his,Accuracy_list):
        out = net.forward(Variable(x))   #这里省略了 mo_net.forward()
        loss = criterion(out, Variable(y))
        #--------------------用于求准确率-------------------------#
        out_class=(out[:]>0).float()  #将out矩阵中大于0的转化为1,小于0的转化为0,存入a中
        right_num=torch.sum(y==out_class).float()  #分类对的数值
        precision=right_num/out.shape[0]  #准确率
        #--------------------求准确率结束-------------------------#
        opt.zero_grad()    
        loss.backward()
        opt.step()
        if (e + 1) % 1 == 0:
            l_his.append(loss.data[0])
            acc_his.append(precision)
            
        if (e + 1) % 50 == 0:
            print('epoch: {}, loss: {},precision{},right_num{}'.format(e+1, loss.data[0],precision,right_num))

2.6画图

我这里只训练了100次,我们来看看loss曲线和acc曲线,代码如下:

x1=list(range(100))
labels_loss=["SGD_loss","Momentum_loss","RMSprop_loss","Adam_loss"]
labels_acc=["SGD_acc","Momentum_acc","RMSprop_acc","Adam_acc"]
plt.figure()
for i in range(4):
    plt.plot(x1, losses_his[i])
    plt.legend(labels =labels_loss,loc = 'upper right')
plt.close(0)
plt.figure()
for i in range(4):
    plt.plot(x1, Accuracy_list[i])
    plt.legend(labels =labels_acc,loc = 'lowver right')

结果:
在这里插入图片描述在这里插入图片描述
我们可以看到最快的RMSprop,最慢的SGD。

2.7测试集测试

代码:

x_test_tensor=x_test_tensor.float()
y_test_tensor=y_test_tensor.float()
opt_name=['SGD','Momentum','RMSprop','Adam']
for net ,name in zip(nets,opt_name):
    out_test=net.forward(Variable(x_test_tensor)) 
    loss_test = criterion(out_test, Variable(y_test_tensor))
    out_test_class=(out_test[:]>0).float()  #将out矩阵中大于0的转化为1,小于0的转化为0,存入a中
    right_num_test=torch.sum(y_test_tensor==out_test_class).float()  #分类对的数值
    precision_test=right_num_test/out_test.shape[0]  #准确率
    loss_test=loss_test.data[0]
    print('opt:{}, loss_test:{}, precision_test:{}, right_num_test:{}'.format(name,loss_test,precision_test,right_num_test))

结果如下:
在这里插入图片描述
Adam效果最好。

3.测试优化器

3.1增加迭代次数

我们上面只迭代了100次,几种优化器效果都还可以,如果我们增加迭代次数呢,首先我增加到1000次,loss和acc曲线如下:
在这里插入图片描述在这里插入图片描述
这时候RMSprop的loss值甚至到了0.3左右,但这时候测试集表现如何呢?我们来看看:
在这里插入图片描述
说明后面两个过拟合严重。
我们现在迭代一万次再来看看,首先是loss曲线和acc曲线:
在这里插入图片描述在这里插入图片描述
最低也达到了0.3以下,我们来看看测试集表现:
在这里插入图片描述
可以看见,过拟合更加严重了。

3.2减小网络层数

我们数据量不多,但是用了好几层网络,现在我们减小网络层数后再来看看效果。
修改后的网络:

class module_net(nn.Module):
    def __init__(self, num_input, num_hidden, num_output):
        super(module_net, self).__init__()
        self.layer1 = nn.Linear(num_input, num_hidden)
        
        self.dropout1 = nn.Dropout(p=0.5)
       
        self.layer2 = nn.ReLU()
        
        self.layer3 = nn.Linear(num_hidden, num_output)
        
    def forward(self, x):
        x = self.layer1(x)
        x = self.dropout1(x)
        x = self.layer2(x)
        x = self.layer3(x)

直接迭代一万次:
在这里插入图片描述在这里插入图片描述
可以看到SGD虽然最慢,但最终在此数据集上,它与其他三个模型都会相遇到同一水平上。
在测试集上:
在这里插入图片描述
loss值相差不大。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值