torchvision手写数据集训练过程(完整训练过程)

在torchvision中下载MNIST数据集

import torchvision
from torchvision.transforms import ToTensor
import torch

常见的图片格式: (高, 宽, 通道)
然后这里我们设置ToTensor()的作用就是:

ToTensor()  作用:
    1. 将输入转为tensor
    2. 规范图片格式为 (channel, height, width)
    3. 将像素取值范围规范到(0,1)
train_ds = torchvision.datasets.MNIST('data',
                                      train=True,
                                      transform=ToTensor(),
                                      download=True)
test_ds = torchvision.datasets.MNIST('data',
                                      train=False,
                                      transform=ToTensor(),
                                      download=True)

查看数据集

imgs, labels = next(iter(train_dl))
imgs.shape
# torch.Size([64, 1, 28, 28])
import matplotlib.pyplot as plt
import numpy as np


plt.figure(figsize=(10, 1))
for i, img in enumerate(imgs[:10]):
    npimg = img.numpy()
    npimg = np.squeeze(npimg)
    plt.subplot(1, 10, i+1)
    plt.imshow(npimg)
    plt.axis('off')

image

labels[:10]
# tensor([0, 5, 2, 3, 7, 5, 3, 8, 0, 9])

定义模型

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear_1 = nn.Linear(28*28, 120)
        self.linear_2 = nn.Linear(120, 84)
        self.linear_3 = nn.Linear(84, 10)
    def forward(self, input):
        x = input.view(-1, 1*28*28)
        x = torch.relu(self.linear_1(x))
        x = torch.relu(self.linear_2(x))
        logits = self.linear_3(x)
        return logits    # 未激活的输出,叫做logits

主要我们下面要用CrossEntropyLoss()作为损失函数,所以上面我们不能用softmax()进行激活。这个CrossEntropyLoss()就是帮助我们计算交叉熵损失的。而他的输入并不希望我们输入这种[0.9,0.04,0.06]这种激活后的输出。
例如:loss_fn=torch.nn.CrossEntropyLoss(),它的输入:loss_fn(target,input),他要求的输入target:是0,1,2这样的类别索引,而不是独热编码,input:是未激活(softmax)的input.

损失函数和优化器

# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()

将模型转化到GPU中

device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Model().to(device)   # 初始化模型
opt = torch.optim.SGD(model.parameters(), lr=0.001)

训练过程

训练函数

# 训练函数
def train(dl, model, loss_fn, optimizer):
    size = len(dl.dataset)    
    num_batches = len(dl)
        
    train_loss, correct = 0, 0
    model.train()
    for x, y in dl:  # 一个批次的数据
        x, y = x.to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item() # loss.item()是一个批次的损失
    correct /= size #全部的正确率,所以除的不一样
    train_loss /= num_batches #train_loss是所有批次的损失
    return correct, train_loss

测试函数

# 测试函数
def test(test_dl, model, loss_fn):
    size = len(test_dl.dataset)    
    num_batches = len(test_dl)
    test_loss, correct = 0, 0
    model.eval()
    with torch.no_grad():
        for x, y in test_dl:
            x, y = x.to(device), y.to(device)
            pred = model(x)
            loss = loss_fn(pred, y)
            test_loss += loss.item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        correct /= size
        test_loss /= num_batches
        return correct, test_loss

训练

def fit(epochs,train_dl,test_dl,model,loss_fn,opt):
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []

    for epoch in range(epochs):
        epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
        train_acc.append(epoch_acc)
        train_loss.append(epoch_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ("epoch:{:2d}, train_Loss:{:.5f},   train_acc:{:.5f},   test_Loss:{:.5f},   test_acc:{:.5f}")

        print(template.format(epoch, epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc))
    print('Done')
    return train_loss,train_acc,test_loss,test_acc

fit函数

def fit(epochs,train_dl,test_dl,model,loss_fn,opt):
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []

    for epoch in range(epochs):
        epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
        train_acc.append(epoch_acc)
        train_loss.append(epoch_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ("epoch:{:2d}, train_Loss:{:.5f},   train_acc:{:.5f},   test_Loss:{:.5f},   test_acc:{:.5f}")

        print(template.format(epoch, epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc))
    print('Done')
    return train_loss,train_acc,test_loss,test_acc
(train_loss,
train_acc,
test_loss,
test_acc)=fit(10,train_dl,test_dl,model,loss_fn,opt)

结果

epoch: 0, train_Loss:0.81310,   train_acc:0.80535,   test_Loss:0.74215,   test_acc:0.81870
epoch: 1, train_Loss:0.72248,   train_acc:0.81923,   test_Loss:0.66442,   test_acc:0.83260
epoch: 2, train_Loss:0.65554,   train_acc:0.83070,   test_Loss:0.60734,   test_acc:0.84400
epoch: 3, train_Loss:0.60485,   train_acc:0.84162,   test_Loss:0.56217,   test_acc:0.85440
epoch: 4, train_Loss:0.56517,   train_acc:0.85003,   test_Loss:0.52724,   test_acc:0.86180
epoch: 5, train_Loss:0.53357,   train_acc:0.85745,   test_Loss:0.49885,   test_acc:0.86770
epoch: 6, train_Loss:0.50748,   train_acc:0.86377,   test_Loss:0.47488,   test_acc:0.87430
epoch: 7, train_Loss:0.48581,   train_acc:0.86872,   test_Loss:0.45535,   test_acc:0.87790
epoch: 8, train_Loss:0.46758,   train_acc:0.87297,   test_Loss:0.43883,   test_acc:0.88140
epoch: 9, train_Loss:0.45202,   train_acc:0.87667,   test_Loss:0.42449,   test_acc:0.88580
Done

用CNN进行训练

class Model(nn.Module):
    def __init__(self):# (b,1,28,28)
        super().__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3,padding=1)
        self.max1=nn.MaxPool2d(3, padding=1, stride=2)
        self.bn1=nn.BatchNorm2d(16)
        
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3,padding=1)
        self.max2=nn.MaxPool2d(3, padding=1, stride=2)
        self.bn2=nn.BatchNorm2d(32)
        
        self.linear_1 = nn.Linear(32*7*7, 120)
        
        self.linear_2= nn.Linear(120,10)
        
    def forward(self, input):
        x=torch.relu(self.conv1(input))
        x=self.max1(x)
      #  x=self.bn1(x)
        
        x=torch.relu(self.conv2(x))
        x=self.max2(x)
     #   x=self.bn2(x)
        
        x = x.view(-1, 32*7*7)
        x = torch.relu(self.linear_1(x))
        logits = self.linear_2(x)
        return logits    # 未激活的输出,叫做logits
# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Model().to(device)   # 初始化模型
print(model)
opt = torch.optim.SGD(model.parameters(), lr=0.001)
# 训练函数
def train(dl, model, loss_fn, optimizer):
    size = len(dl.dataset)    
    num_batches = len(dl)
        
    train_loss, correct = 0, 0
    model.train()
    for x, y in dl:  # 一个批次的数据
        x, y = x.to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item() # loss.item()是一个批次的损失
    correct /= size #全部的正确率,所以除的不一样
    train_loss /= num_batches #train_loss是所有批次的损失
    return correct, train_loss
# 测试函数
def test(test_dl, model, loss_fn):
    size = len(test_dl.dataset)    
    num_batches = len(test_dl)
    test_loss, correct = 0, 0
    model.eval()
    with torch.no_grad():
        for x, y in test_dl:
            x, y = x.to(device), y.to(device)
            pred = model(x)
            loss = loss_fn(pred, y)
            test_loss += loss.item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        correct /= size
        test_loss /= num_batches
        return correct, test_loss
def fit(epochs,train_dl,test_dl,model,loss_fn,opt):
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []

    for epoch in range(epochs):
        epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
        train_acc.append(epoch_acc)
        train_loss.append(epoch_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ("epoch:{:2d}, train_Loss:{:.5f},   train_acc:{:.5f},   test_Loss:{:.5f},   test_acc:{:.5f}")

        print(template.format(epoch, epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc))
    print('Done')
    return train_loss,train_acc,test_loss,test_acc
(train_loss,
train_acc,
test_loss,
test_acc)=fit(10,train_dl,test_dl,model,loss_fn,opt)

CIFAR10的训练

import torchvision
from torchvision.transforms import ToTensor
import torch
import numpy as np
from torch import nn
train_ds = torchvision.datasets.CIFAR10('data',
                                      train=True,
                                      transform=ToTensor(),
                                      download=True)
test_ds = torchvision.datasets.CIFAR10('data',
                                      train=False,
                                      transform=ToTensor(),
                                      download=True)
train_dl = torch.utils.data.DataLoader(train_ds, 
                                       batch_size=64,
                                       shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds, 
                                       batch_size=64)
imgs, labels = next(iter(test_dl))
imgs.shape
# torch.Size([64, 3, 32, 32])
class Model(nn.Module):
    def __init__(self):# (b,3,32,32)
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3,padding=1)
        self.max1=nn.MaxPool2d(3, padding=1, stride=2)
        self.bn1=nn.BatchNorm2d(16)
        
        # (b,16,16,16)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3,padding=1)
        self.max2=nn.MaxPool2d(3, padding=1, stride=2)
        self.bn2=nn.BatchNorm2d(32)
        # (b,32,8,8)
        
        self.linear_1 = nn.Linear(32*8*8, 1024)
        self.drop_1 = nn.Dropout(0.2)
        self.linear_2 = nn.Linear(1024, 120)
        self.drop_2 = nn.Dropout(0.2)
        self.linear_3 = nn.Linear(120,10)
        
    def forward(self, input):
        x=torch.relu(self.conv1(input))
        x=self.max1(x)
        x=self.bn1(x)
        
        x=torch.relu(self.conv2(x))
        x=self.max2(x)
        x=self.bn2(x)
        
        x = x.view(-1, 32*8*8)
        x = torch.relu(self.linear_1(x))
        x = self.drop_1(x)
        x = torch.relu(self.linear_2(x))
        x = self.drop_2(x)
        logits = self.linear_3(x)
        return logits    # 未激活的输出,叫做logits
# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Model().to(device)   # 初始化模型
opt = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练函数
def train(dl, model, loss_fn, optimizer):
    size = len(dl.dataset)    
    num_batches = len(dl)
        
    train_loss, correct = 0, 0
    model.train()
    for x, y in dl:  # 一个批次的数据
        x, y = x.to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item() # loss.item()是一个批次的损失
    correct /= size #全部的正确率,所以除的不一样
    train_loss /= num_batches #train_loss是所有批次的损失
    return correct, train_loss
# 测试函数
def test(test_dl, model, loss_fn):
    size = len(test_dl.dataset)    
    num_batches = len(test_dl)
    test_loss, correct = 0, 0
    model.eval()
    with torch.no_grad():
        for x, y in test_dl:
            x, y = x.to(device), y.to(device)
            pred = model(x)
            loss = loss_fn(pred, y)
            test_loss += loss.item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        correct /= size
        test_loss /= num_batches
        return correct, test_loss
def fit(epochs,train_dl,test_dl,model,loss_fn,opt):
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []

    for epoch in range(epochs):
        epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
        train_acc.append(epoch_acc)
        train_loss.append(epoch_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ("epoch:{:2d}, train_Loss:{:.5f},   train_acc:{:.5f},   test_Loss:{:.5f},   test_acc:{:.5f}")

        print(template.format(epoch, epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc))
    print('Done')
    return train_loss,train_acc,test_loss,test_acc
(train_loss,
train_acc,
test_loss,
test_acc)=fit(20,train_dl,test_dl,model,loss_fn,opt)
imgs, labels = next(iter(test_dl))

imgs.shape

imgs=imgs.to(device)

pred=model(img)

pred.argmax(1)

labels
posted @ 2023-10-18 20:41  lipu123  阅读(50)  评论(0)    收藏  举报