[Introducción al aprendizaje profundo de OUC] Registro de aprendizaje de la semana 2: Conceptos básicos de la red neuronal convolucional

Tabla de contenido

Video aprendizaje parte 1

1 Red neuronal tradicional vs red neuronal convolucional

2 Estructura básica

3 Estructura típica de una red neuronal convolucional

Ejercicio de código parte 2

1 clasificación de conjuntos de datos MNIST

2 Clasificación de conjuntos de datos CIFAR10

3 Clasificar CIFAR10 usando VGG16

Pensamiento de problemas de la parte 3

1 ¿Cuál es la diferencia entre los diferentes valores de reproducción aleatoria en el cargador de datos?

2 En la transformada se toman diferentes valores cual es la diferencia?

3 ¿Cuál es la diferencia entre época y lote?

¿Cuál es la diferencia entre la convolución 4 1x1 y FC? ¿Cuál es el papel principal?

5 ¿Por qué el aprendizaje residual puede mejorar la precisión?

6 En el segundo ejercicio de código, ¿cuál es la diferencia entre la red y LeNet propuesta por Lecun en 1989?

7 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?

8 ¿Hay alguna forma de mejorar aún más la precisión?


Video aprendizaje parte 1

1 Red neuronal tradicional vs red neuronal convolucional

Aplicaciones básicas de las redes neuronales convolucionales: clasificación, recuperación, detección, segmentación, reconocimiento, generación de imágenes, transferencia de estilos, conducción autónoma, etc.

1.1 Trilogía de aprendizaje profundo

  1. Construir una red neuronal
  2. Seleccione la función de pérdida adecuada: pérdida de entropía cruzada (pérdida de entropía cruzada), error cuadrático medio (MSE), etc.
  3. Elija una función de optimización adecuada para actualizar los parámetros: retropropagación (BP), descenso de gradiente estocástico (SGD), etc.

1.2 Función de pérdida

La función de pérdida se utiliza para medir el grado de concordancia entre los resultados previstos y los resultados reales, y puede ayudar a la red neuronal convolucional a ajustar los parámetros/pesos W para lograr mejores resultados de entrenamiento.

1.3 Comparación entre los dos

La red neuronal convolucional del núcleo de la red neuronal tradicional adopta una estructura jerárquica, pero la red neuronal tradicional es una red completamente conectada, y casi todas las neuronas están conectadas a toda la información de píxeles de la imagen, lo que hace que la matriz de peso tenga demasiados parámetros y es fácil de sobreajustar. ; mientras que la red convolucional resuelve este problema a través de la asociación local y el intercambio de parámetros, cada una de sus neuronas solo está conectada a un área determinada en la imagen, y los parámetros del núcleo de convolución permanecen sin cambios durante el proceso de deslizamiento, que además reduce el tamaño del parámetro

2 Estructura básica

2.1 Convolución

Convolución unidimensional : se utiliza en el procesamiento de señales para calcular la acumulación retardada de señales.

Convolución : la convolución es una operación matemática en dos funciones de variables reales. En el procesamiento de imágenes, las imágenes se ingresan a la red neuronal en forma bidimensional, por lo que se requiere una convolución bidimensional.

Conceptos relacionados con la convolución

  • Forma básica: y=Wx+b, donde x es la imagen dada y W es el filtro
  • Núcleo/filtro de convolución (núcleo/filtro)
  • peso
  • Campo receptivo (campo receptivo): el tamaño del área correspondiente a una operación de convolución
  • Mapa de características (mapa de activación/mapa de características): el mapa obtenido después de la operación de convolución, el tamaño está relacionado con el tamaño del kernel de convolución, el tamaño del paso y el mapa (N+padding*2-F)/stride+1
  • Relleno (relleno): relleno 0 alrededor de la imagen, para que la operación de convolución pueda tener en cuenta el borde de la imagen
  • Tamaño de paso (zancada): la longitud del kernel de convolución deslizándose una vez
  • Profundidad (profundidad/canal)

Visualización de convolución : genere el mapa de características de una determinada capa y observe qué características ha aprendido la capa

2.2 Agrupación

Pooling : La estructura y el funcionamiento son similares a la convolución. Generalmente se ubica entre la capa convolucional y la capa convolucional, o entre la capa totalmente conectada y la capa totalmente conectada. Reduce los parámetros y los cálculos conservando las características principales. Sobreajuste para mejorar la capacidad de generalización del modelo

tipo de agrupación

  • Max pooling (agrupación máxima): más comúnmente utilizado en tareas de reconocimiento de clasificación
  • agrupación promedio

2.3 Conexión completa

Capa totalmente conectada (capa FC) : por lo general, al final de la red neuronal convolucional, todas las neuronas entre las dos capas tienen conexiones de peso y la cantidad de parámetros es grande

3 Estructura típica de una red neuronal convolucional

3.1 Alex Net

Estructura del modelo : CONV1 + MAXPOOL1 +NORM1+ CONV2 + MAXPOOL2 + NORM2 + CONV3 + CONV4 + CONV5 + MAXPOOL3 +FC6+FC7+FC8

 Características del modelo

  • Capacitación en Big Data: ImageNet
  • Función de activación no lineal: ReLU, que resuelve el problema de la desaparición de gradientes en intervalos positivos, con una velocidad de cálculo rápida y una velocidad de convergencia más rápida que sigmoide
  • Evite el sobreajuste: abandono (desactivación aleatoria) + aumento de datos (mejora de datos, como traducción, inversión y perturbación gaussiana)
  • Implementación de doble GPU

análisis capa por capa

  1. Convolución-ReLU-Pooling
  2. Convolución-ReLU-Pooling
  3. Convolución-ReLU
  4. Convolución-ReLU
  5. Convolución-ReLU-Pooling
  6. Conexión completa-ReLU-Abandono
  7. Conexión completa-ReLU-Abandono
  8. Totalmente conectado-SoftMax

3.2 ZFNet

La estructura de la red es la misma que la de AlexNet, el tamaño del campo receptivo en la capa convolucional 1 se cambia de 11*11 a 7*7, el tamaño de paso se cambia de 4 a 2; el número de filtros en las capas convolucionales 3, 4 y 5 se cambia de 384, 384, 256 se cambia a 512, 512, 1024

3.3 VGG

VGG es una red más profunda, AlexNet tiene 8 capas, VGG tiene 16-19 capas, VGG se usa comúnmente en el aprendizaje de transferencia

Estructura de red:

 Información de nodo de la red de 16 capas:

  • 01:Convolución usando 64 filtros
  • 02: Convolución usando 64 filtros + Max pooling
  • 03: Convolución usando 128 filtros
  • 04: Convolución usando 128 filtros + Max pooling
  • 05: Convolución usando 256 filtros
  • 06: Convolución usando 256 filtros
  • 07: Convolución usando 256 filtros + Max pooling
  • 08: Convolución usando filtros 512
  • 09: Convolución usando filtros 512
  • 10: Convolución usando 512 filtros + Max pooling
  • 11: Convolución usando filtros 512
  • 12: Convolución usando filtros 512
  • 13: Convolución usando 512 filtros + Max pooling
  • 14: Totalmente conectado con 4096 nodos
  • 15: Totalmente conectado con 4096 nodos
  • 16: Softmax

 

3.4 Red de Google

Estructura general de la red : contiene 22 capas con parámetros (considerando que la capa de agrupación tiene 27 capas), un total de aproximadamente 100 capas de bloques independientes, la cantidad de parámetros es aproximadamente la mitad de AlexNet y no hay una capa completamente conectada

El papel del módulo Inception : los núcleos multiconvolución aumentan la diversidad de características

Inception V2 : inserte la convolución 1*1 para la reducción de la dimensionalidad, lo que resuelve el problema de que la cantidad de parámetros de profundidad aumenta demasiado rápido

Inception V3 : reemplace el kernel de convolución grande con un kernel de convolución pequeño y reduzca aún más la cantidad de parámetros; al mismo tiempo, aumentar la función de activación no lineal hace que la red genere más características independientes, mejora la capacidad de representación y entrena más rápido

 Parte del tallo (red del tallo) : convolución-agrupación-convolución-convolución-agrupación

3.5 ResNet

Red de aprendizaje residual (red de aprendizaje residual profundo) , no hay otra capa completamente conectada excepto la capa de salida, la estructura es flexible y puede entrenar redes muy profundas

 La idea de los residuos : eliminar la misma parte principal y resaltar pequeños cambios

Ejercicio de código parte 2

1 clasificación de conjuntos de datos MNIST

Enlace de código: (colab) clasificación de conjuntos de datos MNIST

Las redes neuronales convolucionales profundas tienen las siguientes propiedades:

  • Muchas capas: composicionalidad
  • 卷积: localidad + estacionariedad de imágenes
  • 池化: Invariancia de la clase de objeto a las traducciones

1.1 Cargando datos MNIST

PyTorch contiene conjuntos de datos comunes como MNIST y CIFAR10. Llame a torchvision.datasets para descargar estos datos de remoto a local. Tome el uso de MNIST como ejemplo:

torchvision.datasets.MNIST(raíz, entrenar=Verdadero, transformar=Ninguno, target_transform=Ninguno, descargar=Falso)

  • raíz: el directorio raíz después de que el conjunto de datos se descargue localmente, incluidos los archivos training.pt y test.pt
  • entrenar: si se establece en Verdadero, crea un conjunto de datos desde entrenamiento.pt; de lo contrario, desde prueba.pt
  • descargar: si se establece en Verdadero, descargue datos de Internet y colóquelos en la carpeta raíz
  • transform: una función o transformación que ingresa una imagen PIL y devuelve los datos transformados
  • target_transform: una función o transformación, destino de entrada, transformación

DataLoader es una clase relativamente importante y las operaciones comunes proporcionadas son:

  • batch_size: el tamaño de cada lote
  • barajar: si realizar operaciones que barajan aleatoriamente el orden
  • num_workers: usa varios subprocesos al cargar datos
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
import matplotlib.pyplot as plt
import numpy

# 计算模型中有多少参数
def get_n_params(model):
    np=0
    for p in list(model.parameters()):
        np += p.nelement()
    return np

# 使用GPU训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
# out: cude:0

input_size = 28*28  # MNIST上的图像尺寸
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)

# 显示数据集中的部分图像
plt.figure(figsize=(8,5))
for i in range(20):
    plt.subplot(4,5,i+1)
    image,_ = train_loader.dataset.__getitem__(i)
    plt.imshow(image.squeeze().numpy(), 'gray')
    plt.axis('off');

1.2 Crear una red

Al definir una red, debe heredar nn.Module e implementar su método de avance. Coloque la capa con parámetros de aprendizaje en la red en el inicio del constructor. Siempre que la función de avance esté definida en la subclase de nn.Module, la función de retroceso la función será 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)
    )
  # forward函数用于指定网络的运行过程
  def forward(self,x):
    # view一般出现在model类的forward函数中,用于改变输入或输出的形状
    # 代码指定二维数据的列数为input_size=784,行数-1表示由电脑自己计算对应的数字
    # batch_size是64,所以x的行数是64
    x = x.view(-1,self.input_size) # 多维的数据展成二维
    # print(x.cpu().numpy().shape)  # 输出(64,784)
    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

1.3 Formación en una pequeña red totalmente conectada

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()
    # 值最大的那个即对应着分类结果,然后把分类结果保存在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))
# 全连接层网络训练

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(model_fnn)
test(model_fnn)

1.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)

Se puede ver que cuando la cantidad de parámetros es similar, el efecto de CNN es mejor que el de una red simple completamente conectada, porque CNN puede extraer mejor información a través de la agrupación de kernel de convolución.

1.5 Mezclar el orden de los píxeles y entrenar y probar de nuevo en las dos redes

Tanto las operaciones de convolución como de agrupación se realizan localmente en la imagen, y se puede extraer la relación posicional de los píxeles. En este momento, intente codificar el orden de los píxeles en la imagen.

# 打乱像素顺序的演示

perm = torch.randperm(784)  # 给定参数n,返回一个从0到n-1的随机整数排列
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')

El efecto después de barajar el orden de los píxeles:

Función para mezclar píxeles:

# 对每个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

Entrene y pruebe 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)

Entrene y pruebe en una red neuronal convolucional:

# 打乱像素顺序训练卷积神经网络

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)

Se puede ver que después de que se interrumpe el orden de los píxeles, el rendimiento de la red neuronal convolucional disminuye, y la relación local entre píxeles es una información de entrenamiento muy importante para la red neuronal convolucional.

2 Clasificación de conjuntos de datos CIFAR10

Enlace de código: (colab) Clasificación de conjuntos de datos CIFAR10

El conjunto de datos CIFAR10 contiene 10 categorías y el tamaño de la imagen es 3*32*32. Se puede cargar con torchsivion. El rango de salida del conjunto de datos de torchvision es [0,1] PILImage. Antes de usarlo, debe normalizarse y convertido a [-1,1] tensor

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 = 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')

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()
# 展示图像
imshow(torchvision.utils.make_grid(images))
# 展示第一行图像的标签
for j in range(8):
  print(classes[labels[j]])

2.1 Definir la red, la función de 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)

2.2 Red de formación

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%200==0:   
            print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch+1,i+1,loss.item()))

print('Finished Training')

 Resultado del entrenamiento:

2.3 Observando el efecto de reconocimiento

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

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

print("预测结果:")

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

 

 Se encontró un pequeño número de errores de reconocimiento.

2.4 Precisión estadística general

 La tasa de precisión es baja y debe mejorarse

3 Clasificar CIFAR10 usando VGG16

Enlace de código: (colab)VGG_CIFAR10

3.1 Definir cargador de datos

En comparación con el ejercicio de código 2, los parámetros de la operación de normalización aquí tienen algunos cambios.

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.2 Definición de red VGG

Aquí se define una red VGG simple con la siguiente estructura:

  • 64 conv, agrupación máxima

  • 128 conversiones, agrupación máxima

  • 256 conversiones, 256 conversiones, agrupación máxima

  • 512 conversiones, 512 conversiones, agrupación máxima

  • 512 conversiones, 512 conversiones, agrupación máxima

  • softmax

# 简化版的VGG

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(2048,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)


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

3.3 Capacitación en 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')

La pérdida del proceso formativo:

3.4 Exactitud de verificación de prueba

 En comparación con la tasa de precisión obtenida al usar el entrenamiento CNN en el ejercicio de código 2, la tasa de precisión obtenida al usar VGG ha aumentado en puntos 20. VGG es más profundo que CNN en el ejercicio de código 2 y hay más posibilidades de transformación no lineal, que es más propicio para que VGG encuentre resultados más precisos Ajuste de transformaciones no lineales para resolver problemas de clasificación de datos

Pensamiento de problemas de la parte 3

1 ¿Cuál es la diferencia entre los diferentes valores de reproducción aleatoria en el cargador de datos?

Shuffle es un parámetro de tipo bool. Cuando shuffle es True, los datos se codificarán al cargar los datos del conjunto de datos. Cuando shuffle es False, no se codificarán. Al codificar el orden, la secuencia de datos en cada ronda de entrenamiento será diferente. , eliminando El efecto de la disposición de datos sobre el efecto de entrenamiento

2 En la transformada se toman diferentes valores cual es la diferencia?

La transformación aquí define algunas operaciones de preprocesamiento de datos de uso común, incluida la normalización de datos, el recorte aleatorio, el volteo, etc., que se pueden usar para mejorar los datos, hacer un uso completo de las muestras de datos y mejorar la capacidad de generalización del modelo de entrenamiento.

El transforms.normalize() utilizado en el ejercicio de código se utiliza para normalizar la imagen canal por canal, de modo que los datos obedezcan la distribución con una media de 0 y una desviación estándar de 1, lo que acelera la convergencia del modelo. la fórmula básica de realización es x=(x-mean)/std, donde mean es la media de los datos en sí, y std es la desviación estándar de los datos en sí, estos dos valores deben calcularse con anticipación

Antes de normalizar, los datos están en [0,1], al normalizar, si es normalizar ((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), es para normalizar los datos, si es normalizar ( media, estándar), es procesar los datos como una distribución con una media de 0 y una desviación estándar de 1

3 ¿Cuál es la diferencia entre época y lote?

Época es la cantidad de rondas del conjunto de datos de entrenamiento. Una época equivale a ejecutar todos los conjuntos de datos una vez; bantch es la cantidad de muestras para el entrenamiento por lotes en una época.

¿Cuál es la diferencia entre la convolución 4 1x1 y FC? ¿Cuál es el papel principal?

La convolución 1*1 es un caso especial de convolución bidimensional, que puede desempeñar un papel en la reducción de la dimensionalidad. Cuando se trata de entradas multidimensionales, puede ajustar el número de canales, reducir parámetros, ayudar a capturar patrones en profundidad y aumentar No lineal, en lugar de FC como clasificador. En comparación con FC, la convolución 1*1 puede lograr compartir el peso, y la cantidad de parámetros es menor que la de la capa fc con la misma función.Utiliza información de posición, y la capa fc requiere un tamaño uniforme para las muestras de entrenamiento, pero la convolución 1*1 no sujeta a esta disposición

5 ¿Por qué el aprendizaje residual puede mejorar la precisión?

En el proceso de entrenamiento de la red, cuanto mayor es la profundidad, más complejos son los parámetros, más compleja es la red. Sin embargo, la tarea de clasificación es un proceso desconocido y es difícil para la red neuronal profunda lograr el mapeo de identidad, que hace que sea difícil para la red aprender mejores parámetros, después de introducir el aprendizaje residual, la red puede realizar el mapeo de identidad.Durante el proceso de entrenamiento, se pueden omitir varias capas de acuerdo con el efecto real, que es más flexible, por lo que la tasa de precisión puede Ser mejorado.

6 En el segundo ejercicio de código, ¿cuál es la diferencia entre la red y LeNet propuesta por Lecun en 1989?

La estructura de LeNet es más o menos la siguiente:

En el ejercicio de código 2, se usan las funciones de agrupación máxima y activación de ReLU, mientras que LeNet usa la agrupación promedio y la función de activación es sigmoide.

7 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?

Puede consultar el diseño BottleNeck de la red ResNet con más de 50 capas y usar la convolución 1*1 para ajustar la dimensión y el tamaño del mapa de características

8 ¿Hay alguna forma de mejorar aún más la precisión?

  1. Agregar operación de abandono
  2. Pruebe diferentes estructuras de red y ajuste el número de capas adecuadamente
  3. Pruebe diferentes funciones de activación
  4. Usar regularización L1/L2
  5. Usar pre-entrenamiento, usar los parámetros obtenidos del pre-entrenamiento para entrenamiento formal
  6. Pruebe diferentes optimizadores y funciones de pérdida, intente ajustar los hiperparámetros

Supongo que te gusta

Origin blog.csdn.net/qq_55708326/article/details/125831268
Recomendado
Clasificación