• 现代卷积网络实战系列2:PyTorch构建训练函数、LeNet网络


    🌈🌈🌈现代卷积网络实战系列 总目录

    本篇文章的代码运行界面均在Pycharm中进行
    本篇文章配套的代码资源已经上传

    1、MNIST数据集处理、加载、网络初始化、测试函数
    2、训练函数、PyTorch构建LeNet网络
    3、PyTorch从零构建AlexNet训练MNIST数据集
    4、PyTorch从零构建VGGNet训练MNIST数据集
    5、PyTorch从零构建GoogLeNet训练MNIST数据集
    6、PyTorch从零构建ResNet训练MNIST数据集

    4、训练函数

    4.1 调用训练函数

    train(epochs, net, train_loader, device, optimizer, test_loader, true_value)
    
    • 1

    因为每一个epoch训练结束后,我们需要测试一下这个网络的性能,所有会在训练函数中频繁调用测试函数,所有测试函数中所有需要的参数,训练函数都需要
    这七个参数,是训练一个神经网络所需要的最少参数

    4.2 训练函数

    训练函数中,所有训练集进行多次迭代,而每次迭代又会将数据分成多个批次进行迭代

    def train(epochs, net, train_loader, device, optimizer, test_loader, true_value):
        for epoch in range(1, epochs + 1):
            net.train()
            all_train_loss = []
            for batch_idx, (data, target) in enumerate(train_loader):
                data = data.to(device)
                target = target.to(device)
                optimizer.zero_grad()
                output = net(data)
                loss = F.cross_entropy(output, target)
                loss.backward()
                optimizer.step()
                cur_train_loss = loss.item()
                all_train_loss.append(cur_train_loss)
            train_loss = np.round(np.mean(all_train_loss) * 1000, 2)
            print('\nepoch step:', epoch)
            print('training loss: ', train_loss)
            test(net, test_loader, device, true_value, epoch)
        print("\nTraining finished")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 定义训练函数
    2. 安装epochs迭代数据
    3. 进入pytorch的训练模式
    4. all_train_loss 存放训练集5万张图片的损失值
    5. 按照batch取数据
    6. 数据进入GPU
    7. 标签进入GPU
    8. 梯度清零
    9. 当前batch进入网络后得到输出
    10. 根据输出得到当前损失
    11. 反向传播
    12. 梯度下降
    13. 获取损失的损失值(PyTorch框架中的数据)
    14. 把当前batch的损失加入all_train_loss数组中,结束batch的迭代
    15. 将5张图片的损失计算出来并且进行求平均,这里乘以1000是因为我觉得计算出的损失太小了,所以乘以1000,方便看损失的变化,保留两位有效数字
    16. 打印当前epoch
    17. 打印损失
    18. 调用测试函数,测试当前训练的网络的性能,结束epoch的迭代
    19. 打印训练完成

    5、LeNet

    向传播来优化学习策略,而是采用的无监督学习的方案,这其实限制了Neocognitron模型。反向传播算法于1974年哈佛大学的 Paul Werbos 提出,并由LeCun于1989将反向传播算法引入了卷积神经网络并且用于手写数字识别任务上,这个就是LeNet-1,通过几年的迭代,LeNet在1998的手写体数字识别任务上取得了很大的成功,这个版本的LeNet就是著名的LeNet-5。为什么LeNet-5这么被广泛使用呢?因为LeNet-5在美国被大规模用于自动对银行支票上的手写数字进行分类。在LeNet之前,字符识别主要是通过手工特征工程来完成特征提取,然后利用机器学习模型来学习手工特征进行分类。因此,特征工程就是一个很大的问题,究竟什么样的特征是需要的特征呢?LeNet-5可以自己学习图像的特征,这就意味着,网络模型自己学习特征成为可能,手工提取特征将成为过去式。卷积还可以被看作是“滑动平均”的推广。
    
    • 1

    5.1 网络结构

    LeNet可以说是首次提出卷积神经网络的模型
    主要包含下面的网络层:

    1. 5*5的二维卷积
    2. sigmoid激活函数(这里使用了relu)
    3. 5*5的二维卷积
    4. sigmoid激活函数
    5. 数据一维化
    6. 全连接层
    7. 全连接层
    8. softmax分类器

    将网络结构打印出来:

    LeNet(
    -------(conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
    -------(conv2): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
    -------(conv2_drop): Dropout2d(p=0.5, inplace=False)
    -------(fc1): Linear(in_features=320, out_features=50, bias=True)
    -------(fc2): Linear(in_features=50, out_features=10, bias=True)
    )

    5.2 PyTorch构建LeNet

    class LeNet(nn.Module):
        def __init__(self, num_classes):
            super(LeNet, self).__init__()
            self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
            self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
            self.conv2_drop = nn.Dropout2d()
            self.fc1 = nn.Linear(320, 50)
            self.fc2 = nn.Linear(50, num_classes)
    
        def forward(self, x):
            x = F.relu(F.max_pool2d(self.conv1(x), 2))
            x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
            x = x.view(-1, 320)
            x = F.relu(self.fc1(x))
            x = F.dropout(x, training=self.training)
            x = self.fc2(x)
            return F.log_softmax(x, dim=1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这个时候已经是一个完整的项目了,看看10个epoch训练过程的打印:

    D:\conda\envs\pytorch\python.exe A:\0_MNIST\train.py

    Reading data…
    train_data: (60000, 28, 28) train_label (60000,)
    test_data: (10000, 28, 28) test_label (10000,)

    Initialize neural network
    test loss: 2301.68
    test accuracy: 11.3 %

    epoch step: 1
    training loss: 634.74
    test loss: 158.03
    test accuracy: 95.29 %

    epoch step: 2
    training loss: 324.04
    test loss: 107.62
    test accuracy: 96.55 %

    epoch step: 3
    training loss: 271.25
    test loss: 88.43
    test accuracy: 97.04 %

    epoch step: 4
    training loss: 236.69
    test loss: 70.94
    test accuracy: 97.61 %

    epoch step: 5
    training loss: 211.05
    test loss: 69.69
    test accuracy: 97.72 %

    epoch step: 6
    training loss: 199.28
    test loss: 62.04
    test accuracy: 97.98 %

    epoch step: 7
    training loss: 187.11
    test loss: 59.65
    test accuracy: 97.98 %

    epoch step: 8
    training loss: 178.79
    test loss: 53.89
    test accuracy: 98.2 %

    epoch step: 9
    training loss: 168.75
    test loss: 51.83
    test accuracy: 98.43 %

    epoch step: 10
    training loss: 160.83
    test loss: 50.35
    test accuracy: 98.4 %

    Training finished
    进程已结束,退出代码为 0

    可以看出基本上只要一个epoch就可以得到很好的训练效果了,后续的epoch中的提升比较小

  • 相关阅读:
    知识图谱内容梳理
    Helm Subcharts And Global Values practical operation
    OKLink携手CertiK在港举办Web3生态安全主题论坛
    namespace命名空间
    vue中动态设置source标签
    2022年最新《谷粒学院开发教程》:9 - 前台课程模块
    Linux源码安装软件包时--prefix的配置建议
    如何在 R 中执行幂回归
    【LeetCode热题100】--49.字母异位词分组
    1034. 边界着色-深度优先遍历
  • 原文地址:https://blog.csdn.net/weixin_50592077/article/details/133175045