【Réseau de neurones convolutifs de construction】

Construire des réseaux de neurones convolutifs

  • L'entrée et la couche du réseau convolutif sont quelque peu différentes du réseau neuronal traditionnel et doivent être repensées, et les modules de formation sont fondamentalement les mêmes

Couche entièrement connectée : lot 784, il n'y a pas de connexion entre chaque pixel.
Couche convolutive : lot
1 28 28, il y a une connexion entre chaque pixel.

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

Lire d'abord les données

  • Construire l'ensemble de formation et l'ensemble de test (ensemble de validation) séparément
  • DataLoader pour récupérer les données de manière itérative
# 定义超参数 
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)

Construction de module de réseau convolutif

  • La couche de convolution générale, la couche relu, la couche de mise en commun peuvent être écrites sous forme de package
  • Notez que le résultat final de la convolution est toujours une carte de caractéristiques, qui doit être convertie en un vecteur pour effectuer des tâches de classification ou de régression

L'image est une convolution bidimensionnelle conv2
la vidéo est une convolution tridimensionnelle conv3
un seul vecteur est une convolution unidimensionnelle
site officiel conv1 La formule de calcul pour la largeur et la longueur de sortie de conv2d
insérez la description de l'image ici

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(         # 输入大小 (1, 28, 28)
            nn.Conv2d(
                in_channels=1,              # 1:灰度图;3:RGB
                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(         # 下一个套餐的输入 (32, 7, 7)
            nn.Conv2d(32, 64, 5, 1, 2),     # 输出 (64, 7, 7)
            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, 64 * 7 * 7)
        output = self.out(x)
        return output

La précision comme critère d'évaluation

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

Former le modèle de réseau

# 实例化
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) 

    
        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]))

insérez la description de l'image ici

pratique

  • Ajoutez une autre couche de convolution, quel est l'effet ?
  • Pourquoi la couche entièrement connectée dans la tâche en cours 32 7 7 Que représente chaque nombre ?

Je suppose que tu aimes

Origine blog.csdn.net/qq_60498436/article/details/132164436
conseillé
Classement