[Semana 2] Redes neuronales convolucionales

CONV

1.
MNIST El conjunto de datos MNIST es un conjunto de imágenes de 70 000 dígitos escritas a mano por estudiantes de secundaria de EE. UU. y empleados de la Oficina del Censo. Cada imagen está etiquetada con el número que representa. MNIST tiene un total de 70.000 imágenes, cada una con 784 características. Los píxeles de la imagen son 28*28 píxeles y cada función representa la intensidad de un píxel, desde 0 (blanco) hasta 255 (negro).
inserte la descripción de la imagen aquí

2. Arquitectura CNN
La arquitectura CNN común apila algunas capas convolucionales (por lo general, cada capa convolucional es seguida por una capa ReLU), luego una capa de agrupación, luego varias otras capas convolucionales (+ReLU), y luego otra capa de agrupación, y así sucesivamente. . A medida que la red convolucional continúa desarrollándose, la imagen se vuelve cada vez más pequeña, pero debido a la existencia de la capa convolucional, la imagen también suele ser más profunda (es decir, tiene más mapas de características). En la parte superior de la pila se agrega una red neuronal de alimentación directa regular que consta de varias capas completamente conectadas (+ReLU) con la última capa que genera predicciones (por ejemplo, una capa de softmax que genera probabilidades de clase estimadas).
inserte la descripción de la imagen aquí
3.
El núcleo de la red neuronal convolucional CNN es la convolución. En la capa de convolución de CNN, hay pequeñas cuadrículas cuadradas llenas de números. Se denominan núcleos de convolución (kernel). Después de que la imagen original pase a través de la capa de entrada, se convertirá en una matriz llena de escala de grises o valores RGB. Alinee el kernel de convolución con la matriz de la imagen, multiplique y agregue los números en las cuadrículas correspondientes y luego complete los números obtenidos en la nueva matriz, que es la convolución. El núcleo de convolución mueve la operación en la imagen a cierta distancia, lo que se denomina tamaño de paso. La nueva matriz resultante puede reflejar algunas características de la imagen, por lo que se denomina mapa de características. Son tanto la salida de esta capa como la la siguiente capa entrada de. Al establecer diferentes núcleos de convolución, podemos encontrar varias características. Diseñe el kernel de convolución a través del entrenamiento (el entrenamiento es permitir que la red determine automáticamente el número en el kernel de convolución de acuerdo con los datos existentes y sus etiquetas), y las características extraídas por la última capa de convolución son más abstractas.
La capa de agrupación puede seleccionar las características principales de la imagen. El Maxpooling comúnmente utilizado es para retener el valor máximo del área de cobertura de la ventana. Después de agrupar la matriz, los parámetros se reducirán considerablemente.
La capa completamente conectada generalmente se encuentra al final de la red y puede reunir las características extraídas para dar la probabilidad de que la imagen sea cierta.
Las CNN son muy buenas para procesar imágenes. Tratar los sonidos como gráficos permite el reconocimiento de voz y tratar las palabras como vectores permite la traducción automática.
4. Estructura de red típica: AlexNet, VGG, GooleNet, ResNet
5. Ejercicio de código
(1) Primero, cargue el conjunto de datos utilizando el conjunto de datos MNIST.
PyTorch contiene conjuntos de datos de uso común, como MNIST y CIFAR10. Llame a torchvision.datasets para descargar estos datos de forma remota a local. A continuación se explica cómo usar MNIST:

torchvision.datasets.MNIST(root,train=True,transform=None,target_transform=None,download=False)
#root为数据集下载到本地后的根目录,包括training.pt和test.pt文件。
#train,如果设置为True,从training.pt创建数据集,否则从test.pt创建。
#download,如果设置为True,从互联网下载数据并放到root文件夹下。
#transform,一种函数或变换,输入PIL图片,返回变换之后的数据。
#target_transform一种函数或变换,输入目标,进行变换。

El método para descargar el conjunto de datos MNIST:
vale la pena señalar que DataLoader es una clase relativamente importante, y las operaciones comunes proporcionadas son: batch_size (el tamaño de cada lote), shuffer (ya sea o no y operaciones aleatorias retrógradas), num_workers ( Use varios procesos secundarios al cargar datos)

input_size  = 28*28   # MNIST上的图像尺寸是 28x28
output_size = 10      # 类别为 0 到 9 的数字,因此为十类

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=True, download=True,
        transform=transforms.Compose(
            [transforms.ToTensor(),
             transforms.Normalize((0.1307,), (0.3081,))])),
    batch_size=64, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=False, transform=transforms.Compose([
             transforms.ToTensor(),
             transforms.Normalize((0.1307,), (0.3081,))])),
    batch_size=1000, shuffle=True)

Parte de las imágenes en el conjunto de datos se pueden mostrar después de la descarga

plt.figure(figsize=(8, 5))
for i in range(20):
    plt.subplot(54, i + 1)
    image, _ = train_loader.dataset.__getitem__(i)
    plt.imshow(image.squeeze().numpy(),'gray')
    plt.axis('off');

Los siguientes son los resultados que se muestran, y puede ver 20 imágenes en escala de grises seleccionadas al azar:
inserte la descripción de la imagen aquí
(2) Al crear una
red de definición de red, debe heredar nn.Module, implementar su método de avance y colocar la capa con parámetros aprendibles en el red En el constructor _init_.
Siempre que la función de avance se defina en una subclase de nn.Module, la función de retroceso se implementará automáticamente (usando autograd).

class FC2Layer(nn.Module):
    def __init__(self, input_size, n_hidden, output_size):
        # nn.Module子类的函数必须在构造函数中执行父类的构造函数
        # 下式等价于nn.Module.__init__(self)        
        super(FC2Layer, self).__init__()
        self.input_size = input_size
        # 这里直接用 Sequential 就定义了网络,注意要和下面 CNN 的代码区分开
        self.network = nn.Sequential(
            nn.Linear(input_size, n_hidden), 
            nn.ReLU(), 
            nn.Linear(n_hidden, n_hidden), 
            nn.ReLU(), 
            nn.Linear(n_hidden, output_size), 
            nn.LogSoftmax(dim=1)
        )
    def forward(self, x):
        # view一般出现在model类的forward函数中,用于改变输入或输出的形状
        # x.view(-1, self.input_size) 的意思是多维的数据展成二维
        # 代码指定二维数据的列数为 input_size=784,行数 -1 表示我们不想算,电脑会自己计算对应的数字
        # 在 DataLoader 部分,我们可以看到 batch_size 是64,所以得到 x 的行数是64
        # 大家可以加一行代码:print(x.cpu().numpy().shape)
        # 训练过程中,就会看到 (64, 784) 的输出,和我们的预期是一致的

        # forward 函数的作用是,指定网络的运行过程,这个全连接网络可能看不啥意义,
        # 下面的CNN网络可以看出 forward 的作用。
        x = x.view(-1, self.input_size)
        return self.network(x)
    
class CNN(nn.Module):
    def __init__(self, input_size, n_feature, output_size):
        # 执行父类的构造函数,所有的网络都要这么写
        super(CNN, self).__init__()
        # 下面是网络里典型结构的一些定义,一般就是卷积和全连接
        # 池化、ReLU一类的不用在这里定义
        self.n_feature = n_feature
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=n_feature, kernel_size=5)
        self.conv2 = nn.Conv2d(n_feature, n_feature, kernel_size=5)
        self.fc1 = nn.Linear(n_feature*4*4, 50)
        self.fc2 = nn.Linear(50, 10)    
    
    # 下面的 forward 函数,定义了网络的结构,按照一定顺序,把上面构建的一些结构组织起来
    # 意思就是,conv1, conv2 等等的,可以多次重用
    def forward(self, x, verbose=False):
        x = self.conv1(x)
        x = F.relu(x)
        x = F.max_pool2d(x, kernel_size=2)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, kernel_size=2)
        x = x.view(-1, self.n_feature*4*4)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        x = F.log_softmax(x, dim=1)
        return x

Definir funciones de entrenamiento y prueba.

# 训练函数
def train(model):
    model.train()
    # 主里从train_loader里,64个样本一个batch为单位提取样本进行训练
    for batch_idx, (data, target) in enumerate(train_loader):
        # 把数据送到GPU中
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))


def test(model):
    model.eval()
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        # 把数据送到GPU中
        data, target = data.to(device), target.to(device)
        # 把数据送入模型,得到预测结果
        output = model(data)
        # 计算本次batch的损失,并加到 test_loss 中
        test_loss += F.nll_loss(output, target, reduction='sum').item()
        # get the index of the max log-probability,最后一层输出10个数,
        # 值最大的那个即对应着分类结果,然后把分类结果保存在 pred 里
        pred = output.data.max(1, keepdim=True)[1]
        # 将 pred 与 target 相比,得到正确预测结果的数量,并加到 correct 中
        # 这里需要注意一下 view_as ,意思是把 target 变成维度和 pred 一样的意思                                                
        correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()

    test_loss /= len(test_loader.dataset)
    accuracy = 100. * correct / len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        accuracy))
     

(3) Capacitación en una pequeña red totalmente conectada (Red totalmente conectada)

n_hidden = 8 # number of hidden units(隐藏层单元数为8)
model_fnn = FC2Layer(input_size, n_hidden, output_size)
model_fnn.to(device)
optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_fnn)))
train(model_fnn)
test(model_fnn)

inserte la descripción de la imagen aquí
(4) Entrenamiento en Redes Neuronales Convolucionales

# Training settings 
n_features = 6 # number of feature maps(卷积核的个数)
model_cnn = CNN(input_size, n_features, output_size)
model_cnn.to(device)
optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_cnn)))
train(model_cnn)
test(model_cnn)

inserte la descripción de la imagen aquí
En comparación, se puede ver que la precisión de la red neuronal convolucional con los mismos parámetros es mucho mayor que la de la conexión completa. (CNN puede extraer mejor la información de la imagen a través de la convolución y la agrupación)

(5) Interrumpir el orden de los píxeles y entrenar y probar en las dos redes nuevamente
En CNN, la capa convolucional y la capa de agrupación son dos componentes importantes de la red neuronal convolucional. La capa convolucional extrae las características locales de la imagen a través del kernel de convolución, mientras que la capa de agrupación reduce la cantidad de valores de salida al reducir el tamaño de la entrada, lo que reduce la información redundante. Si se interrumpen los píxeles, se destruirán las propiedades originales de correlación local en la imagen, lo que afectará las capacidades de extracción y procesamiento de la capa convolucional y la capa de agrupación para las características de la imagen.

# 这里解释一下 torch.randperm 函数,给定参数n,返回一个从0到n-1的随机整数排列
perm = torch.randperm(784)
plt.figure(figsize=(8, 4))
for i in range(10):
    image, _ = train_loader.dataset.__getitem__(i)
    # permute pixels
    image_perm = image.view(-1, 28*28).clone()
    image_perm = image_perm[:, perm]
    image_perm = image_perm.view(-1, 1, 28, 28)
    plt.subplot(4, 5, i + 1)
    plt.imshow(image.squeeze().numpy(), 'gray')
    plt.axis('off')
    plt.subplot(4, 5, i + 11)
    plt.imshow(image_perm.squeeze().numpy(), 'gray')
    plt.axis('off')

Después de alterar los píxeles, puede ver que la imagen tiene forma de copo de nieve.
inserte la descripción de la imagen aquí
Redefina la función de entrenamiento y la función de prueba (el conjunto es básicamente el mismo que antes, pero el orden de los datos se agrega al desorden)

# 对每个 batch 里的数据,打乱像素顺序的函数
def perm_pixel(data, perm):
    # 转化为二维矩阵
    data_new = data.view(-1, 28*28)
    # 打乱像素顺序
    data_new = data_new[:, perm]
    # 恢复为原来4维的 tensor
    data_new = data_new.view(-1, 1, 28, 28)
    return data_new

# 训练函数
def train_perm(model, perm):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        # 像素打乱顺序
        data = perm_pixel(data, perm)

        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

# 测试函数
def test_perm(model, perm):
    model.eval()
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        data, target = data.to(device), target.to(device)

        # 像素打乱顺序
        data = perm_pixel(data, perm)

        output = model(data)
        test_loss += F.nll_loss(output, target, reduction='sum').item()
        pred = output.data.max(1, keepdim=True)[1]                                            
        correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()

    test_loss /= len(test_loader.dataset)
    accuracy = 100. * correct / len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        accuracy))

(6) Entrenamiento y pruebas en una red completamente conectada

perm = torch.randperm(784)
n_hidden = 8 # number of hidden units

model_fnn = FC2Layer(input_size, n_hidden, output_size)
model_fnn.to(device)
optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_fnn)))

train_perm(model_fnn, perm)
test_perm(model_fnn, perm)

Por favor agregue una descripción de la imagen
(7) Entrenamiento y pruebas en redes neuronales convolucionales

perm = torch.randperm(784)
n_features = 6 # number of feature maps

model_cnn = CNN(input_size, n_features, output_size)
model_cnn.to(device)
optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_cnn)))

train_perm(model_cnn, perm)
test_perm(model_cnn, perm)

Por favor agregue una descripción de la imagen
A partir de la comparación, se puede ver que el rendimiento de la red completamente conectada básicamente no ha cambiado, pero la precisión de la red neuronal convolucional ha disminuido, lo que afecta la relación local de los píxeles utilizados en la red convolucional. la relación entre píxeles no puede ser explotada.

CNN_CIFAR10

1. Para datos visuales, PyTorch ha creado un paquete llamado totchvision, que incluye un módulo de carga de datos torchvision.datasets que admite la carga de conjuntos de datos públicos como Imagenet, CIFAR10, MNIST y un módulo de conversión de datos torch.utils.data que admite la carga de imágenes. datos .DataLoader.
Lo siguiente utilizará el conjunto de datos CIFAR10, que contiene diez categorías: 'avión', 'automóvil', 'pájaro', 'gato', 'venado', 'perro', 'rana', 'caballo', 'barco', ' camión'. El tamaño de la imagen en CIFAR-10 es 3x32x32, que es el canal de color de 3 capas de RGB, y el tamaño de cada canal es 32*32.

inserte la descripción de la imagen aquí
2. Primero, cargue y normalice CIFAR10 usando torchvision. La salida del conjunto de datos de torchvision es una PILImage en el rango [0,1], y los convertimos en tensores con un rango normalizado de [-1,1].
El siguiente código dice 0.5, que está escrito en el código fuente de PyTorch:
input[channel] = (input[channel] - mean[channel]) / std[channel]
Esto es: ((0,1)-0.5)/ 0.5 =(-1,1).

import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# 使用GPU训练,可以在菜单 "代码执行工具" -> "更改运行时类型" 里进行设置
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# 注意下面代码中:训练的 shuffle 是 True,测试的 shuffle 是 false
# 训练时可以打乱顺序增加多样性,测试是没有必要
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=8,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

3. A continuación se muestran algunas imágenes en CIFAR10:

def imshow(img):
    plt.figure(figsize=(8,8))
    img = img / 2 + 0.5     # 转换到 [0,1] 之间
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

# 得到一组图像
#images, labels = iter(trainloader).next()
images, labels = next(iter(trainloader))
# 展示图像
imshow(torchvision.utils.make_grid(images))
# 展示第一行图像的标签
for j in range(8):
    print(classes[labels[j]])

inserte la descripción de la imagen aquí
4. A continuación, defina la función de red/pérdida y el optimizador.

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 网络放到GPU上
net = Net().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

5. Capacitar a la red:

for epoch in range(10):  # 重复多轮训练
    for i, (inputs, labels) in enumerate(trainloader):
        inputs = inputs.to(device)
        labels = labels.to(device)
        # 优化器梯度归零
        optimizer.zero_grad()
        # 正向传播 + 反向传播 + 优化 
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        # 输出统计信息
        if i % 100 == 0:   
            print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))

print('Finished Training')

Por favor agregue una descripción de la imagen
6. Tomamos 8 fotos del conjunto de prueba.

# 得到一组图像
images, labels = next(iter(testloader))
# 展示图像
imshow(torchvision.utils.make_grid(images))
# 展示图像的标签
for j in range(8):
    print(classes[labels[j]])

inserte la descripción de la imagen aquí
7. Ingrese las imágenes en el modelo y vea los resultados de CNN reconociendo estas imágenes

outputs = net(images.to(device))
_, predicted = torch.max(outputs, 1)

# 展示预测的结果
for j in range(8):
    print(classes[predicted[j]])

Por favor agregue una descripción de la imagen
8. Al comparar con la imagen, puede ver que algunos resultados de reconocimiento son incorrectos.
Vea cómo funciona la CNN en todo el conjunto de datos

correct = 0
total = 0

for data in testloader:
    images, labels = data
    images, labels = images.to(device), labels.to(device)
    outputs = net(images)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

Por favor agregue una descripción de la imagen
Se puede ver que la tasa de precisión es del 63%.

VGG

1. La estructura de red de VGG16 se muestra en la siguiente figura:
inserte la descripción de la imagen aquí
La información de nodo de la red de 16 capas es la siguiente:

01: Convolución usando 64 filtros
02: Convolución usando 64 filtros + Agrupación máxima
03: Convolución usando 128 filtros
04: Convolución usando 128 filtros + Agrupación máxima 05: Convolución usando 256 filtros 06: Convolución usando 256 filtros
07 : Convolución usando 256 filtros + Max pooling 08: Convolución usando 512 filtros 09: Convolución usando 512 filtros 10: Convolución usando 512 filtros + Max pooling 11: Convolución usando 512 filtros 12: Convolución usando 512 filtros 13: Convolución usando 512 filtros + Max pooling 14: Totalmente conectado con 4096 nodos 15: Totalmente conectado con 4096 nodos 16: Softmax 2.首先,定义cargador de datos











import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# 使用GPU训练,可以在菜单 "代码执行工具" -> "更改运行时类型" 里进行设置
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,  download=True, transform=transform_train)
testset  = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)

trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

3. Definir la red VGG
La estructura actual es básicamente:
64 conv, maxpooling,
128 conv, maxpooling,
256 conv, 256 conv, maxpooling,
512 conv, 512 conv, maxpooling,
512 conv, 512 conv, maxpooling,
softmax

Código de implementación del modelo:

class VGG(nn.Module):
    def __init__(self):
        super(VGG, self).__init__()
        self.cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']
        self.features = self._make_layers(self.cfg)
        self.classifier = nn.Linear(512, 10)

    def forward(self, x):
        out = self.features(x)
        out = out.view(out.size(0), -1)
        out = self.classifier(out)
        return out

    def _make_layers(self, cfg):
        layers = []
        in_channels = 3
        for x in cfg:
            if x == 'M':
                layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
            else:
                layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),
                           nn.BatchNorm2d(x),
                           nn.ReLU(inplace=True)]
                in_channels = x
        layers += [nn.AvgPool2d(kernel_size=1, stride=1)]
        return nn.Sequential(*layers)

Ponga la red en la GPU:

for epoch in range(10):  # 重复多轮训练
    for i, (inputs, labels) in enumerate(trainloader):
        inputs = inputs.to(device)
        labels = labels.to(device)
        # 优化器梯度归零
        optimizer.zero_grad()
        # 正向传播 + 反向传播 + 优化 
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        # 输出统计信息
        if i % 100 == 0:   
            print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))

print('Finished Training')

Por favor agregue una descripción de la imagen

correct = 0
total = 0

for data in testloader:
    images, labels = data
    images, labels = images.to(device), labels.to(device)
    outputs = net(images)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %.2f %%' % (
    100 * correct / total))

Por favor agregue una descripción de la imagen

conclusión del problema

  1. ¿Cuál es la diferencia entre los diferentes valores de reproducción aleatoria en el cargador de datos?
shuffle是bool类型的参数,作用是设置是否将数据集打乱。shuffle=False,表示不打乱数据的顺序,然后以batch为单位从头到尾按顺序取用数据。shuffle=True,表示每一次在epoch中都打乱所有数据的顺序,然后以batch为单位从头到尾按顺序取用数据,这样的结果就是不同epoch中的数据都是乱序的。
  1. En transform se toman diferentes valores, cual es la diferencia?
当图像数据输入时,需要对图像数据进行预处理。transform.ToTensor()是将输入的数据shape H,W,C---->C,H,W.将所有的数除以255,将数据归一化到【01】
transform.Normalize()通过公式x = (x-mean) / std,即同一纬度的数据减去这一维度的平均值,再除以标准差,将数据进行标准化处理。
  1. ¿La diferencia entre época y lote?
Epoch和Batch分别表示模型训练的层次。
Batch(批量)是指为了加速训练而将大规模数据划分成小批次数据的过程。每个Batch中包含了多个样本,模型会对这些样本进行前向传播和反向传播。计算出参数的梯度并进行更新。
Epoch(批次)是指将整个数据集迭代一遍的过程。在一个Epoch中,模型会对整个数据集进行一次前向传播和反向传播,更新所有的参数。
Batch大小是梯度下降的超参数,它控制在更新模型的内部参数之前要处理的训练样本的数量。
Epoch数是控制通过训练数据集的完整通过数的梯度下降的超参数。
  1. ¿Cuál es la diferencia entre convolución 1x1 y FC? ¿Cuál es el papel principal?
1*1的卷积可以用于降维(减少通道数),升维(增加通道数),代替fc成为一个分类器,conv可以权值共享,参数量较同等功能的fc层相比少,使用了位置信息。fc层对于训练样本要求统一尺寸,但1*1的卷积不会受该规定的限制。
  1. ¿Por qué el aprendizaje residual puede mejorar la precisión?
residual learning framework将传统网络中的层learning unreferenced function修改为参照了该层inputs的learning residual function。容易优化,显著增加了深度,可以提高准确率。比VGG深了8倍,而且复杂度更低。
  1. En el segundo ejercicio de código, ¿cuál es la diferencia entre la red y LeNet propuesta por Lecun en 1989?
LeNet是一种经典的卷积网络神经,是现代卷积网络的起源之一,它是conv1-pool1-conv2-pool2,然后才接上全连接层的结构,由一个输入层,两个卷积层,两个池化层,三个全连接层构成。Lenet使用的激活函数是sigmoid函数,平均池化层。而练习二中的网络使用的激活函数是relu函数,最大池化层。
  1. En el segundo ejercicio de código, el tamaño del mapa de características se hará más pequeño después de la convolución.¿Cómo aplicar el aprendizaje residual?
实现时使用1*1的卷积,设置步长为2
  1. ¿Hay alguna forma de mejorar aún más la precisión?
1.增加更多的数据,并处理好缺失值和异常值。
2.选取有用的特征。
3.选择合适的算法,可以多种算法进行对比。
4.进行交叉验证。

Supongo que te gusta

Origin blog.csdn.net/weixin_45867259/article/details/131794288
Recomendado
Clasificación