• 深度学习——(9)神经网络参数详解


    深度学习——(9)神经网络参数详解

    1. 卷积神经网络

    • 卷积网络中的输入和层与传统神经网络有些区别,需重新设计,训练模块基本一致
    • 上一节全连接层将像素点扩展一个向量,假设的前提是每个像素点之间都是相互独立的
    • 图像之间的像素点往往是有关联的,所以使用卷积可以考虑更多图像间像素点的联系。
    • 一般在处理图像的过程中更多使用的是卷积,全连接一般只用于最后几层做分类映射或者回归的映射

    2. 上代码

    2.1 package

    import torch
    import torch.nn as nn
    import torch.optim as optim
    import torch.nn.functional as F
    from torchvision import datasets,transforms  
    import matplotlib.pyplot as plt
    import numpy as np
    %matplotlib inline
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2 读取数据

    # 定义超参数 
    input_size = 28  #图像的总尺寸28*28
    num_classes = 10  #标签的种类数
    num_epochs = 3  #训练的总循环周期
    batch_size = 64  #一个批次的大小,64张图片
    # 训练集
    train_dataset = datasets.MNIST(root='./data',  
                                train=True,   
                                transform=transforms.ToTensor(),  
                                download=True) 
    # 测试集
    test_dataset = datasets.MNIST(root='./data', 
                               train=False, 
                               transform=transforms.ToTensor())
    # 构建batch数据
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                               batch_size=batch_size, 
                                               shuffle=True)
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset, 
                                               batch_size=batch_size, 
                                               shuffle=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2.3 卷积网络模块构建

    • 一般卷积层,relu层,池化层可以组在一起成为一个block
    • 注意卷积最后结果还是一个特征图,需要把图转换成向量才能做分类或者回归任务(maxpooling)
    • 一般图像是通道数优先:12828,也有通道数最后的:28281
    • in_channels:输入图像的通道数
    • out_channels:输出的特征图个数
    • padding:考虑边界像素点,对于不是中心堆成的图,resize会改变图像的形状,做padding避免此问题。
    • 卷积后图像大小计算:(h-kernel+2*padding)/stride + 1(向下取整)
    • 一般padding设置方法:kernel5,padding=2;kernel3,padding=1
    • maxpooling:希望将图像压缩,变为原来的一半
    • view和reshape操作一样的:将64,7,7变为6477
    class CNN(nn.Module):
        def __init__(self):
            super(CNN, self).__init__()
            self.conv1 = nn.Sequential(         # 输入大小 (1, 28, 28)
                nn.Conv2d(
                    in_channels=1,              # 灰度图
                    out_channels=16,            # 要得到几多少个特征图
                    kernel_size=5,              # 卷积核大小
                    stride=1,                   # 步长
                    padding=2,                  # 如果希望卷积后大小跟原来一样,需要设置padding=(kernel_size-1)/2 if stride=1
                ),                              # 输出的特征图为 (16, 28, 28)
                nn.ReLU(),                      # relu层
                nn.MaxPool2d(kernel_size=2),    # 进行池化操作(2x2 区域), 输出结果为: (16, 14, 14)
            )
            self.conv2 = nn.Sequential(         # 下一个套餐的输入 (16, 14, 14)
                nn.Conv2d(16, 32, 5, 1, 2),     # 输出 (32, 14, 14)
                nn.ReLU(),                      # relu层
                nn.Conv2d(32, 32, 5, 1, 2),
                nn.ReLU(),
                nn.MaxPool2d(2),                # 输出 (32, 7, 7)
            )
            
            self.conv3 = nn.Sequential(         # 下一个套餐的输入 (16, 14, 14)
                nn.Conv2d(32, 64, 5, 1, 2),     # 输出 (32, 14, 14)
                nn.ReLU(),             # 输出 (64, 7, 7)
            )
            
            self.out = nn.Linear(64 * 7 * 7, 10)   # 全连接层得到的结果
    
        def forward(self, x): # 前向传播
            x = self.conv1(x)
            x = self.conv2(x)
            x = self.conv3(x)
            x = x.view(x.size(0), -1)           # flatten操作,第一个维度不变结果为:(batch_size, 32 * 7 * 7),-1表示自动计算
            output = self.out(x)      #上面把卷积得到的特征图转换为二维图
            return output
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    2.4 计算准确率

    def accuracy(predictions, labels):
        pred = torch.max(predictions.data, 1)[1] 
        rights = pred.eq(labels.data.view_as(pred)).sum() 
        return rights, len(labels) 
    
    • 1
    • 2
    • 3
    • 4

    2.5 训练网络

    # 实例化
    net = CNN() 
    #损失函数
    criterion = nn.CrossEntropyLoss() 
    #优化器
    optimizer = optim.Adam(net.parameters(), lr=0.001) #定义优化器,普通的随机梯度下降算法
    
    #开始训练循环
    for epoch in range(num_epochs):
        #当前epoch的结果保存下来
        train_rights = [] 
        
        for batch_idx, (data, target) in enumerate(train_loader):  #针对容器中的每一个批进行循环
            net.train()                             
            output = net(data) 
            loss = criterion(output, target) 
            optimizer.zero_grad() 
            loss.backward() 
            optimizer.step() 
            right = accuracy(output, target) 
            train_rights.append(right) 
    
      # 不是每个epoch都进行验证的  
            if batch_idx % 100 == 0: 
                
                net.eval() 
                val_rights = [] 
                
                for (data, target) in test_loader:
                    output = net(data) 
                    right = accuracy(output, target) 
                    val_rights.append(right)
                    
                #准确率计算
                train_r = (sum([tup[0] for tup in train_rights]), sum([tup[1] for tup in train_rights]))
                val_r = (sum([tup[0] for tup in val_rights]), sum([tup[1] for tup in val_rights]))
    
                print('当前epoch: {} [{}/{} ({:.0f}%)]\t损失: {:.6f}\t训练集准确率: {:.2f}%\t测试集正确率: {:.2f}%'.format(
                    epoch, batch_idx * batch_size, len(train_loader.dataset),
                    100. * batch_idx / len(train_loader), 
                    loss.data, 
                    100. * train_r[0].numpy() / train_r[1], 
                    100. * val_r[0].numpy() / val_r[1]))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这里插入图片描述

  • 相关阅读:
    unity脚本_Mathf和Math c#
    “创新启变 聚焦增长”极狐(GitLab)媒体沟通会,共话智能时代软件开发新生态
    《最新出炉》系列入门篇-Python+Playwright自动化测试-51- 字符串操作 - 上篇
    I2C相关实验
    微软放弃“封禁”商业开源!
    G1D30-NLP(Tokenizer)&DP(交叠子问题)
    第十站:Java白——测试与调试的艺术
    STM32F4X UCOSIII任务消息队列
    TI/德州仪器 TPS2051CDBVR 功率电子开关
    服务器git安装python包失败,如何手动下载github项目包并安装到虚拟环境中(简单易懂)
  • 原文地址:https://blog.csdn.net/qq_43368987/article/details/126632177