美文网首页
深度学习笔记(二十四)—— 深度学习总结与回顾

深度学习笔记(二十四)—— 深度学习总结与回顾

作者: Nino_Lau | 来源:发表于2019-08-02 10:11 被阅读0次

    本周是深度学习实验课的最后一次课,让我们回顾一下在这个学期中大家都学习到了哪些内容。在前面的课程中我们首先了解了神经网络的结构,如何去搭建神经网络,怎样去训练神经网络,以及神经网络的优化、微调。紧接着我们又学习了深度学习领域当前比较流行的几个大方向,例如分类、语义分割、目标检测、对抗神经网络、自然语言处理等等。接下来的内容是对我们所学的知识的一个总结和升华。

    1.神经网络的基础内容

    1.框架

    当前训练神经网络的框架有许多,例如tensorflow, caffe, pytorch等等,由于pytorch上手简单,使用方便,所以本门课程选择的框架是pytorch.

    2.神经网络的基础单元

    在pytorch框架中,神经网络的最基本的单元是张量(tensor), 由于框架本身已经实现了反向传播的机制,所以我们在搭建网络的过程中只需将大部分精力放在正向传播上,不太需要关心反向传播(梯度消失,梯度爆炸问题除外)。

    3.如何去搭建一个简单的神经网络

    import torch
    import torch.nn as nn
    import torch.optim as optim
    
    class Net(nn.Module):
        def __init__(self, *args):
            self.layer1 = nn.Conv2d(3,64,kernel_size=3, stride=1,padding=0, bias=True)
            self.avg_pool = nn.AvgPool2d(4)
            self.layer2 = nn.Linear(64,10)
            
        
        def forward(self, x):
            out = self.layer1(x)
            out = out.view(x.size(0), -1)
            out = self.layer2(out)
            return out
    

    4.如何去训练一个神经网络

    LR = 0.01
    BATCH_SIZE = 32
    EPOCH = 10
    
    net = Net()
    
    optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9, weight_decay=5e-4)
    criterion = nn.CrossEntropyLoss()
    
    for i in range(EPOCH):
        for data in enumerate(dataloader):
            x, y = data
            x, y = x.cuda(), y.cuda()
            # 模型预测结果
            y_hat = net(x)
            # 计算loss值
            loss = criterion(y, y_hat)
            # 清空优化器,必须在反向传播前进行
            optimizer.zero_grad()
            # 反向传播
            loss[0].backward()
            # 更新网络参数
            optimizer.step()
            
        '''
        这部分根据个人需求添加自己的代码,可以实现打印当前epoch的loss值,
        在训练集上的准确率,在验证集上的准确率,绘图等等操作
        '''
    

    在以上训练过程中,值得大家注意的是:
    建议大家同时打印出模型在训练集和测试集上的准确率,有些同学只关注在测试集上的准确率,忽略了在训练集上的准确率,导致可能出现一种情况,在测试集上的准确率不够理想,就怀疑是模型或者是其他什么地方出了问题。这个时候我们应该看看在训练集上的准确率如何,如果模型在训练集上表现的结果都不是很好,说明模型根本就没有训练好,又怎么能期望它能够在测试集上表现得好呢?这个时候我们首先应该想办法让模型在训练集的准确率达到99%以上(分类网络一般都可以达到近乎100%)。这是初学者很容易犯的一个低级错误,希望能够引起大家的重视。

    5.模型训练的基本技巧

    • 设置随机种子,确保可以复现结果
    • k折交叉验证,验证模型的泛化能力
    • 数据预处理中的均值和方差的设置(目前有两种较常用的做法,一种是使用pretrain_model数据集的均值和方差,一种是使用自己数据集的均值和方差,哪种效果更好,实践出真知)
    • 数据增强,关于transforms里面众多函数的使用,也是根据数据集而定,建议大家多多尝试,
    • 模型的初始化,如果使用的模型提供了pretrain_model建议大家充分利用,可以加速收敛,如果想重新训练就要考虑torch.nn.init里面的众多初始化方法
    • 模型修改,根据自己的需求结合理论知识修改网络,这部分内容需要大家进行多次实验,找到适合自己数据集的较好的模型
    • 优化器,一般来说分类网络我们常用sgd和adam两种优化器,没有绝对的定论哪种更好。sgd的缺点是收敛可能要慢一些,如果调整得当可以得到比较好的结果,adam收敛速度快一些,但是结果可能略逊于sgd
    • batch_size,较大的batch_size才能充分发挥网络中bn层的作用,但是消耗的gpu资源也越多
    • learning_rate,学习率是网络训练过程中至关重要的参数,面对不同的batch_size,不同的优化方式,不同的数据集其最合适的值都是不确定的,我们无法仅凭经验来准确地得出lr值,能做的就是多做实验(可以参考的做法:观察训练过程中loss值和accuracy值,如果两者都上升到一定高度后趋于平缓,这个时候可以考虑调低lr,经过多次实验后,大致可得出lr在何时可能需要衰减)
    • lr与bs的关系,一般越大的bs使用越大的lr,因为越大的bs意味着我们学习的时候,收敛方向的confidence越大,我们前进的方向更加坚定,而较小的bs则显得比较杂乱,无规律性,因此bs较小的时候需要小的学习率保证不至于出错
    • 模型保存,模型的保存分为两种,一种是保存整个模型,另一种是保存模型的参数,一般建议保存模型的参数,因为模型的参数更便于我们灵活地去加载(比如之前提到的只加载部分模型参数),另外,模型的参数实际上是以字典的形式保存下来的。

    以上内容基本上在14周课件中都有实现

    6.训练的高级技巧

    • 过拟合,过拟合典型的表现为训练集损失远远小于验证集损失,而欠拟合则表现为训练集损失大于验证集损失,记住是远远大于,而不是说训练集损失稍微大于验证集损失就判断为过拟合。举个例子,如果遇到训练集损失为0.8,验证集损失为2.0,则可以判断为过拟合
    • dropout,dropout可以减轻过拟合现象,但请不要无脑使用,dropout一般适合全连接层部分,而卷积层由于参数不是很多,所以不太需要dropout,加上的话对模型的泛化能力没有太大影响。
    • 难例挖掘,在深度学习任务中,我们可能会遇到一些比较’棘手‘的数据,这些数据相比较于其他数据更难识别,他们称为hard-negative。我们先使用初始的正负样本训练分类器,然后再用训练出的分类器对样本进行分类,把其中负样本错误分类的那些样本(hard-negative)放入负样本集合,再继续训练分类器,如此反复,直到达到到停止条件(比如分类器性能不再提升)
    • 尝试过拟合一个小数据集,关闭正则化、随机失活、数据扩充,使用训练集的一小部分,让神经网络训练几个周期。确保出现零损失,如果没有,那么很可能什么地方出错了(经典的小trick)

    一个很具体的问题

    第12次作业,数据预处理和decoder输出内容转换成文本的过程
    网络输出是词向量,通过查询字典(embedding)可以转换成对应的index(整数),再查询预先定义的index和词的对应关系,可以找到原始对应的单词

    相关文章

      网友评论

          本文标题:深度学习笔记(二十四)—— 深度学习总结与回顾

          本文链接:https://www.haomeiwen.com/subject/jppkdctx.html