Notas prácticas de aprendizaje profundo (5): implementación de regresión softmax

Descubrimos que era más fácil implementar la regresión lineal a través de las API de alto nivel de los marcos de trabajo de aprendizaje profundo. De manera similar, los modelos de regresión softmax se pueden implementar de manera más conveniente a través de la API de alto nivel de los marcos de trabajo de aprendizaje profundo.

1.1 Conjunto de datos de clasificación de imágenes

El conjunto de datos MNIST es uno de los conjuntos de datos más utilizados en la clasificación de imágenes, pero es demasiado simplista como conjunto de datos de referencia. Usaremos un conjunto de datos Fashion-MNIST similar pero más complejo

%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

d2l.use_svg_display()

1.1.1 Leer el conjunto de datos

Podemos descargar y leer el conjunto de datos Fashion-MNIST en la memoria a través de funciones integradas en el marco.

# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0到1之间
trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(
    root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(
    root="../data", train=False, transform=trans, download=True)

Fashion-MNIST consta de 10 categorías de imágenes, cada una de 训练数据集(train dataset)las cuales consta de 6000 imágenes 测试数据集(test dataset)en y 1000 imágenes en formato . Por lo tanto, los conjuntos de entrenamiento y prueba contienen 60 000 y 10 000 imágenes, respectivamente. El conjunto de datos de prueba no se utilizará para el entrenamiento, solo para evaluar el rendimiento del modelo.

len(mnist_train), len(mnist_test)
(60000, 10000)

La altura y el ancho de cada imagen de entrada son 28像素. El conjunto de datos consta de imágenes en escala de grises con un número de canal de 1. Para abreviar, denote la forma de una imagen con una altura de h píxeles y un ancho de w píxeles como h×w o (h, w).

mnist_train[0][0].shape
torch.Size([1, 28, 28])

Las 10 categorías incluidas en Fashion-MNIST son t-shirt (camiseta), pantalón (pantalones), jersey (jersey), vestido (vestido), abrigo (abrigo), sandalia (sandalias), camisa (camiseta), zapatilla de deporte ( zapatillas de deporte), bolso (bolso) y botín (botas cortas). Las siguientes funciones se utilizan para convertir entre índices de etiquetas numéricas y sus nombres textuales.

def get_fashion_mnist_labels(labels):  
    """返回Fashion-MNIST数据集的文本标签"""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

Cree una función para visualizar estas muestras.

def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """绘制图像列表"""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        if torch.is_tensor(img):
            # 图片张量
            ax.imshow(img.numpy())
        else:
            # PIL图片
            ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    return axes

A continuación se muestran las imágenes de las primeras muestras en el conjunto de datos de entrenamiento y sus etiquetas correspondientes.

X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));

inserte la descripción de la imagen aquí

1.1.2 Lectura de lotes pequeños

Para facilitarnos la lectura de los conjuntos de entrenamiento y prueba, en lugar de crear desde cero, usamos los iteradores de datos incorporados. En resumen, en cada iteración, el cargador de datos lee un pequeño lote de datos de tamaño de lote cada vez. Con los iteradores de datos integrados, podemos mezclar todas las muestras al azar para leer minilotes sin sesgos.

batch_size = 256

def get_dataloader_workers():  
    """使用4个进程来读取数据"""
    return 4

train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
                             num_workers=get_dataloader_workers())

1.1.3 Integrar todos los componentes

Ahora definimos load_data_fashion_mnist函数,Se utiliza para obtener y leer el conjunto de datos Fashion-MNIST.Esta función devuelve iteradores de datos para conjuntos de entrenamiento y validación. Además, esta función acepta un cambio de tamaño de parámetro opcional, que se utiliza para cambiar el tamaño de la imagen a otra forma.

def load_data_fashion_mnist(batch_size, resize=None):  
    """下载Fashion-MNIST数据集,然后将其加载到内存中"""
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="../data", train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="../data", train=False, transform=trans, download=True)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=get_dataloader_workers()),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=get_dataloader_workers()))

A continuación, probamos las capacidades de cambio de tamaño de imagen de la función load_data_fashion_mnist especificando el parámetro de cambio de tamaño.

train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break
torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64

1.2 Inicializar los parámetros del modelo

import torch
from torch import nn
from d2l import torch as d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

La capa de salida de la regresión softmax es uno 全连接层. Por lo tanto, para implementar nuestro modelo, simplemente agregamos una capa completamente conectada con 10 salidas a Sequential. Nuevamente, Sequential no es necesario aquí, pero es la base para implementar modelos profundos. Todavía inicializamos aleatoriamente los pesos con media 0 y desviación estándar 0.01.

# PyTorch不会隐式地调整输入的形状。因此,
# 我们在线性层前定义了展平层(flatten),来调整网络输入的形状
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);

1.3 Función de pérdida

loss = nn.CrossEntropyLoss()

1.4 Algoritmo de optimización

Aquí, usamos el descenso de gradiente estocástico de mini lotes con una tasa de aprendizaje de 0.1 como algoritmo de optimización. Esto es lo mismo que hicimos en el ejemplo de regresión lineal, que ilustra la generalidad del optimizador.

trainer = torch.optim.SGD(net.parameters(), lr=0.1)

1.5 Entrenamiento

num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

inserte la descripción de la imagen aquí

Como antes, el algoritmo converge con una precisión razonablemente alta y, esta vez, el código es mucho más reducido que antes.

Supongo que te gusta

Origin blog.csdn.net/qq_52118067/article/details/122863204
Recomendado
Clasificación