(保姆级)Pytorch构建神经网络的简单实例——对FashionMNIST数据集图像进行分类(源代码来源于Pytorch计算机视觉实战第三章)

项目介绍

用mlp实现图像分类(暂时不用CNN)

采用贯序模型而不是创捷nn.Model的派生类(这样做的好处是不用写__init__函数和forward函数。

数据集介绍: 

FashionMNIST(时尚MNIST)是一个经典的计算机视觉数据集,用于图像分类任务。它是由 Zalando Research 创建的,旨在替代传统的MNIST数据集,以更贴近实际场景中的图像分类问题。

FashionMNIST数据集包含了60,000个用于训练的图像样本和10,000个用于测试的图像样本,总共包括10个类别。每个样本都是灰度图像,分辨率为28x28像素。每个像素的值介于0到255之间,表示像素的灰度强度。

数据集中的图像样本代表了不同种类的时尚商品,包括衣服、鞋子、手袋等。以下是FashionMNIST数据集中的类别标签和对应的类别名称:

  1. T-shirt/top(T恤/上衣)
  2. Trouser(裤子)
  3. Pullover(套头衫)
  4. Dress(裙子)
  5. Coat(外套)
  6. Sandal(凉鞋)
  7. Shirt(衬衫)
  8. Sneaker(运动鞋)
  9. Bag(包)
  10. Ankle boot(短靴)

FashionMNIST数据集的设计灵感来自于MNIST数据集,但相对于MNIST,FashionMNIST更具挑战性,更适合用于评估和比较不同的图像分类算法和模型。

由于其简单的图像和类别标签结构,FashionMNIST数据集成为了深度学习和计算机视觉领域中常用的基准数据集之一。它可以用于训练和评估各种图像分类算法、卷积神经网络(CNN)等模型,并作为学术研究和教学的基础。

程序实现

1、导包

from torch.utils.data import Dataset, DataLoader
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
device = "cuda" if torch.cuda.is_available() else "cpu"
from torchvision import datasets
data_folder = '~/data/FMNIST' #数据的下载路径
fmnist = datasets.FashionMNIST(data_folder, download=True, train=True)
#data_folder: 这是一个字符串,表示数据集的存储位置。它指定了数据集的根文件夹路径。
#download=True: 这是一个可选的参数,用于指定是否下载FashionMNIST数据集。如果数据集尚未下载,设置为True将自动下载数据集。如果数据集已经下载,设置为False将跳过下载步骤。
#train=True: 这是一个可选的参数,用于指定是否加载FashionMNIST的训练集。当设置为True时,创建的数据集对象将包含FashionMNIST的训练集。当设置为False时,将加载测试集。

#torch.manual_seed(0)用于使用相同值初始化网络模型,方便模型复现

tr_images = fmnist.data
#数据集中的输入
tr_targets = fmnist.targets
#与数据集中的输入对应的输出

2、数据处理

#定义数据集类,派生自Dataset类,Dataset类是在机器学习和深度学习中常用的一个抽象类,用于表示数据集。
#Dataset类提供了一种通用的接口和功能,用于组织、存储和预处理数据集。它为机器学习和深度学习任务提供了一种方便和灵活的方式来处理数据。
class FMNISTDataset(Dataset):
    def __init__(self, x, y):
        x = x.float()
        x = x.view(-1,28*28)
        self.x, self.y = x, y 
    def __getitem__(self, ix):
        x, y = self.x[ix], self.y[ix] 
        return x.to(device), y.to(device)
    def __len__(self): 
        return len(self.x)

def get_data(): 
    train = FMNISTDataset(tr_images, tr_targets) 
    trn_dl = DataLoader(train, batch_size=32, shuffle=True)
    #DataLoader是用于批量加载和处理数据的类。它封装了一个Dataset对象,并提供了数据的批量加载、并行处理、顺序打乱等功能。
    #通过DataLoader,可以从Dataset中按照指定的批次大小加载数据,并且可以使用多个工作线程并行地加载和处理数据。
    return trn_dl

3、模型

from torch.optim import SGD
#这个SGD不是理论定义上的挑一个样本计算损失更新参数,而是按batch计算损失函数并更新(Pytorch并没有直接定义GD,MBGD都是通过SGD实现的)
#这里采用Sequential的方式定理网络结构,而不是继承nn.model的方式定义网络结构,这样做的优点是不用定义__init__函数,和forward方法
def get_model():
    model = nn.Sequential(
        nn.Linear(28 * 28, 1000),
        nn.ReLU(),
        nn.Linear(1000, 10)
    ).to(device)
    loss_fn = nn.CrossEntropyLoss()#分离问题采用交叉熵损失函数
    optimizer = SGD(model.parameters(), lr=1e-2)#优化器设置为SGD,指定学习率未0.01
    return model, loss_fn, optimizer#一般模型的函数都返回模型本身,损失函数,优化器,其实就对应着机器学习(深度学习也一个意思)三要素:模型、策略、算法

4、训练

def train_batch(x, y, model, opt, loss_fn):
    model.train() 
    #model.train()方法用于将模型设置为训练模式,启用梯度计算、启用 Dropout 层和 Batch Normalization 层的训练行为。这是深度学习训练的重要步骤之一,用于指定模型在训练阶段的行为,并进行参数更新和优化。
    prediction = model(x)
    #计算预测值
    batch_loss = loss_fn(prediction, y)
    #计算损失

    batch_loss.backward()
    # based on the forward pass in `model(x)` compute all the gradients of     
    # 'model.parameters()'
    optimizer.step()
    # apply new-weights = f(old-weights, old-weight-gradients) where 
    # "f" is the optimizer
    optimizer.zero_grad()
    # Flush gradients memory for next batch of calculations
    # 至于为啥要清零由pytorch计算梯度的机制决定
    return batch_loss.item()
    #batch_loss是一个tensor,item()取其值

5、测试

@torch.no_grad()
#这个修饰器用于省去梯度计算,在测试时不用计算梯度
def accuracy(x, y, model):
    model.eval() # <- let's wait till we get to dropout section
    #model.eval()用于将模型设置为评估模式,以确保一致的行为和计算结果。在进行模型评估、验证和推理时,通常会在调用model.eval()之前使用。
    # get the prediction matrix for a tensor of `x` images
    prediction = model(x)
    # compute if the location of maximum in each row coincides 
    # with ground truth
    max_values, argmaxes = prediction.max(-1)
    is_correct = argmaxes == y
    return is_correct.cpu().numpy().tolist()

6、串起来

trn_dl = get_data()
model, loss_fn, optimizer = get_model()

losses, accuracies = [], []
for epoch in range(5):
    print(epoch)
    epoch_losses, epoch_accuracies = [], []
    #for i in trn_dl:
    #  print(i)
    for ix, batch in enumerate(iter(trn_dl)):
        #trn_dl是Dataloder的一个实例,他是一个迭代器对象,其返回形式是<torch.utils.data.dataloader.DataLoader object at 0x7b4969b2afb0>
        #iter()用于创建一个迭代器对象,事实上,这里将iter()省略也完全可以运行,其返回形式是<torch.utils.data.dataloader._SingleProcessDataLoaderIter object at 0x7bf037a93c70>
        #enumerate返回的是一个枚举对象,相较于迭代器对象,它多了index,其返回形式是<enumerate object at 0x7bf037aae2c0>
        #最后的数是对象在内存中的地址
        x, y = batch
        #取出一个batch中对应的输入输出
        batch_loss = train_batch(x, y, model, optimizer, loss_fn)
        epoch_losses.append(batch_loss)
        #epoch_losses存batch_loss
    epoch_loss = np.array(epoch_losses).mean()
    for ix, batch in enumerate(iter(trn_dl)):
        x, y = batch
        is_correct = accuracy(x, y, model)
        epoch_accuracies.extend(is_correct)
    epoch_accuracy = np.mean(epoch_accuracies)
    losses.append(epoch_loss)
    #losses存epoch_loss
    accuracies.append(epoch_accuracy)
    #预测准确度存轮准确度

7、可视化

epochs = np.arange(5)+1
plt.figure(figsize=(20,5))
plt.subplot(121)
plt.title('Loss value over increasing epochs')
plt.plot(epochs, losses, label='Training Loss')
plt.legend()
plt.subplot(122)
plt.title('Accuracy value over increasing epochs')
plt.plot(epochs, accuracies, label='Training Accuracy')
plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()]) 
plt.legend()

#plt.show()#pycharm中加上,jupyter、colab不用加

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是使用PyTorchFashion MNIST数据集进行分类的示例代码: 首先,我们需要导入必要的库和模块: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as datasets import torchvision.transforms as transforms from torch.utils.data import DataLoader ``` 然后,我们需要下载并加载数据集Fashion MNIST数据集可以通过以下方式下载: ```python train_data = datasets.FashionMNIST( root="data", train=True, download=True, transform=transforms.ToTensor() ) test_data = datasets.FashionMNIST( root="data", train=False, download=True, transform=transforms.ToTensor() ) ``` 接下来,我们需要定义一个神经网络模型。在这个例子,我们使用了一个简单的卷积神经网络: ```python class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.layer1 = nn.Sequential( nn.Conv2d(1, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) self.layer2 = nn.Sequential( nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) self.fc = nn.Sequential( nn.Linear(7 * 7 * 64, 128), nn.ReLU(), nn.Linear(128, 10) ) def forward(self, x): out = self.layer1(x) out = self.layer2(out) out = out.reshape(out.size(0), -1) out = self.fc(out) return out ``` 然后,我们需要定义损失函数和优化器: ```python model = CNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) ``` 最后,我们可以开始训练模型并评估其性能: ```python train_loader = DataLoader(train_data, batch_size=100, shuffle=True) test_loader = DataLoader(test_data, batch_size=100, shuffle=False) for epoch in range(10): for i, (images, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() if (i + 1) % 100 == 0: print(f"Epoch [{epoch + 1}/{10}], Step [{i + 1}/{len(train_loader)}], Loss: {loss.item():.4f}") with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() accuracy = 100 * correct / total print(f"Test Accuracy: {accuracy:.2f}%") ``` 这就是使用PyTorchFashion MNIST数据集进行分类的示例代码。希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值