PyTorch学习笔记(四):PyTorch基础实战

简介: 通过一个基础实战案例,结合前面所涉及的PyTorch入门知识。本次任务是对10个类别的“时装”图像进行分类,使用FashionMNIST数据集(fashion-mnist/data/fashion at master · zalandoresearch/fashion-mnist · GitHub

通过一个基础实战案例,结合前面所涉及的PyTorch入门知识。本次任务是对10个类别的“时装”图像进行分类,使用FashionMNIST数据集(fashion-mnist/data/fashion at master · zalandoresearch/fashion-mnist · GitHub


FashionMNIST数据集中包含已经预先划分好的训练集和测试集,其中训练集共60,000张图像,测试集共10,000张图像。每张图像均为单通道黑白图像,大小为32*32pixel,分属10个类别。


1.导入必要的包


import os
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader


2 配置训练环境和超参数


# 配置GPU,这里有两种方式
## 方案一:使用os.environ
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
# 方案二:使用“device”,后续对要使用GPU的变量用.to(device)即可
#device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
## 配置其他超参数,如batch_size, num_workers, learning rate, 以及总的epochs
batch_size = 256
num_workers = 4   # 对于Windows用户,这里应设置为0,否则会出现多线程错误
lr = 1e-4
epochs = 20


3 数据读取和加载


这里同时展示两种方式:


下载并使用PyTorch提供的内置数据集

从网站下载以csv格式存储的数据,读入并转成预期的格式

第一种数据读入方式只适用于常见的数据集,如MNIST,CIFAR10等,PyTorch官方提供了数据下载。这种方式往往适用于快速测试方法(比如测试下某个idea在MNIST数据集上是否有效)

第二种数据读入方式需要自己构建Dataset,这对于PyTorch应用于自己的工作中十分重要

同时,还需要对数据进行必要的变换,比如说需要将图片统一为一致的大小,以便后续能够输入网络训练;需要将数据格式转为Tensor类,等等。


from torchvision import transforms
# 设置数据变换
image_size = 28
data_transform = transforms.Compose([
    transforms.ToPILImage(),   # 这一步取决于后续的数据读取方式,如果使用内置数据集则不需要
    transforms.Resize(image_size),
    transforms.ToTensor()
])
## 读取方式一:使用torchvision自带数据集,下载可能需要一段时间
from torchvision import datasets
train_data = datasets.FashionMNIST(root='./', train=True, download=True, transform=data_transform)
test_data = datasets.FashionMNIST(root='./', train=False, download=True, transform=data_transform)
## 读取方式二:读入csv格式的数据,自行构建Dataset类,即自定义数据集
# csv数据下载链接:https://www.kaggle.com/zalando-research/fashionmnist
class FMDataset(Dataset):
    def __init__(self, df, transform=None):
        self.df = df
        self.transform = transform
        self.images = df.iloc[:,1:].values.astype(np.uint8)
        self.labels = df.iloc[:, 0].values
    def __len__(self):
        return len(self.images)
    def __getitem__(self, idx):
        image = self.images[idx].reshape(28,28,1)
        label = int(self.labels[idx])
        if self.transform is not None:
            image = self.transform(image)
        else:
            image = torch.tensor(image/255., dtype=torch.float)
        label = torch.tensor(label, dtype=torch.long)
        return image, label
train_df = pd.read_csv("./FashionMNIST/fashion-mnist_train.csv")
test_df = pd.read_csv("./FashionMNIST/fashion-mnist_test.csv")
train_data = FMDataset(train_df, data_transform)
test_data = FMDataset(test_df, data_transform)

 4.模型设计


# 使用CNN
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 32, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2),
            nn.Dropout(0.3),
            nn.Conv2d(32, 64, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2),
            nn.Dropout(0.3)
        )
        self.fc = nn.Sequential(
            nn.Linear(64*4*4, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )
    def forward(self, x):
        x = self.conv(x)
        x = x.view(-1, 64*4*4)
        x = self.fc(x)
        # x = nn.functional.normalize(x)
        return x
model = Net()
model = model.cuda()


5 设置损失函数和优化器


使用torch.nn模块自带的CrossEntropy损失。

PyTorch会自动把整数型的label转为one-hot型,用于计算CE loss

这里需要确保label是从0开始的,同时模型不加softmax层(使用logits计算),这也说明了PyTorch训练中各个部分不是独立的,需要通盘考虑。


# 使用交叉熵损失函数
criterion = nn.CrossEntropyLoss()
# 使用Adam优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)


6.训练与测试


各自封装成函数,方便后续调用

关注两者的主要区别:


模型状态设置

是否需要初始化优化器

是否需要将loss传回到网络

是否需要每步更新optimizer

此外,对于测试或验证过程,可以计算分类准确率。


训练:


def train(epoch):
    # 设置训练状态
    model.train()
    train_loss = 0
    # 循环读取DataLoader中的全部数据
    for data, label in train_loader:
        # 将数据放到GPU用于后续计算
        data, label = data.cuda(), label.cuda()
        # 将优化器的梯度清0
        optimizer.zero_grad()
        # 将数据输入给模型
        output = model(data)
        # 设置损失函数
        loss = criterion(output, label)
        # 将loss反向传播给网络
        loss.backward()
        # 使用优化器更新模型参数
        optimizer.step()
        # 累加训练损失
        train_loss += loss.item() * data.size(0)
    train_loss = train_loss/len(train_loader.dataset)
    print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch, train_loss))


验证:


def val(epoch): 
    # 设置验证状态
    model.eval()
    val_loss = 0
    gt_labels = []
    pred_labels = []
    # 不设置梯度
    with torch.no_grad():
        for data, label in test_loader:
            data, label = data.cuda(), label.cuda()
            output = model(data)
            preds = torch.argmax(output, 1)
            gt_labels.append(label.cpu().data.numpy())
            pred_labels.append(preds.cpu().data.numpy())
            loss = criterion(output, label)
            val_loss += loss.item()*data.size(0)
    # 计算验证集的平均损失
    val_loss = val_loss/len(test_loader.dataset)
    gt_labels, pred_labels = np.concatenate(gt_labels), np.concatenate(pred_labels)
    # 计算准确率
    acc = np.sum(gt_labels==pred_labels)/len(pred_labels)
    print('Epoch: {} \tValidation Loss: {:.6f}, Accuracy: {:6f}'.format(epoch, val_loss, acc))
for epoch in range(1, epochs+1):
    train(epoch)
    val(epoch)
Epoch: 1     Training Loss: 0.664049
Epoch: 1     Validation Loss: 0.421500, Accuracy: 0.852400
Epoch: 2     Training Loss: 0.417311
Epoch: 2     Validation Loss: 0.349790, Accuracy: 0.871200
Epoch: 3     Training Loss: 0.355448
Epoch: 3     Validation Loss: 0.318987, Accuracy: 0.879500
Epoch: 4     Training Loss: 0.323644
Epoch: 4     Validation Loss: 0.290521, Accuracy: 0.893800
Epoch: 5     Training Loss: 0.301900
Epoch: 5     Validation Loss: 0.266420, Accuracy: 0.901300
Epoch: 6     Training Loss: 0.286696
Epoch: 6     Validation Loss: 0.246448, Accuracy: 0.909700
Epoch: 7     Training Loss: 0.271441
Epoch: 7     Validation Loss: 0.241845, Accuracy: 0.911200
Epoch: 8     Training Loss: 0.260185
Epoch: 8     Validation Loss: 0.243311, Accuracy: 0.910800
Epoch: 9     Training Loss: 0.247986
Epoch: 9     Validation Loss: 0.225896, Accuracy: 0.916200
Epoch: 10     Training Loss: 0.240718
Epoch: 10     Validation Loss: 0.227848, Accuracy: 0.914700
Epoch: 11     Training Loss: 0.232358
Epoch: 11     Validation Loss: 0.220180, Accuracy: 0.917500
Epoch: 12     Training Loss: 0.223933
Epoch: 12     Validation Loss: 0.215308, Accuracy: 0.919400
Epoch: 13     Training Loss: 0.218354
Epoch: 13     Validation Loss: 0.211890, Accuracy: 0.919300
Epoch: 14     Training Loss: 0.210027
Epoch: 14     Validation Loss: 0.209707, Accuracy: 0.922700
Epoch: 15     Training Loss: 0.203024
Epoch: 15     Validation Loss: 0.208233, Accuracy: 0.925600
Epoch: 16     Training Loss: 0.196965
Epoch: 16     Validation Loss: 0.208209, Accuracy: 0.921900
Epoch: 17     Training Loss: 0.193155
Epoch: 17     Validation Loss: 0.200000, Accuracy: 0.926100
Epoch: 18     Training Loss: 0.184376
Epoch: 18     Validation Loss: 0.197259, Accuracy: 0.926200
Epoch: 19     Training Loss: 0.184272
Epoch: 19     Validation Loss: 0.200259, Accuracy: 0.926000
Epoch: 20     Training Loss: 0.172641
Epoch: 20     Validation Loss: 0.200177, Accuracy: 0.927100


7.模型保存


训练完成后,可以使用torch.save保存模型参数或者整个模型,也可以在训练过程中保存模型


save_path = "./FahionModel.pkl"
torch.save(model, save_path)
目录
相关文章
|
5月前
|
机器学习/深度学习 自然语言处理 PyTorch
【PyTorch实战演练】基于AlexNet的预训练模型介绍
【PyTorch实战演练】基于AlexNet的预训练模型介绍
232 0
|
5月前
|
机器学习/深度学习 算法 PyTorch
【PyTorch实战演练】自调整学习率实例应用(附代码)
【PyTorch实战演练】自调整学习率实例应用(附代码)
213 0
|
5月前
|
机器学习/深度学习 算法 PyTorch
【PyTorch实战演练】Fast R-CNN中的RoI(Region of Interest)池化详解
【PyTorch实战演练】Fast R-CNN中的RoI(Region of Interest)池化详解
150 1
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【PyTorch实战演练】AlexNet网络模型构建并使用Cifar10数据集进行批量训练(附代码)
【PyTorch实战演练】AlexNet网络模型构建并使用Cifar10数据集进行批量训练(附代码)
375 0
|
4月前
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
|
16天前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
在数据驱动时代,Python凭借简洁的语法和强大的库支持,成为数据分析与机器学习的首选语言。Pandas和NumPy是Python数据分析的基础,前者提供高效的数据处理工具,后者则支持科学计算。TensorFlow与PyTorch作为深度学习领域的两大框架,助力数据科学家构建复杂神经网络,挖掘数据深层价值。通过Python打下的坚实基础,结合TensorFlow和PyTorch的强大功能,我们能在数据科学领域探索无限可能,解决复杂问题并推动科研进步。
38 0
|
2月前
|
机器学习/深度学习 PyTorch TensorFlow
【PyTorch】PyTorch深度学习框架实战(一):实现你的第一个DNN网络
【PyTorch】PyTorch深度学习框架实战(一):实现你的第一个DNN网络
84 1
|
3月前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
【7月更文挑战第31天】在数据驱动时代,Python凭借其简洁性与强大的库支持,成为数据分析与机器学习的首选语言。**数据分析基础**从Pandas和NumPy开始,Pandas简化了数据处理和清洗,NumPy支持高效的数学运算。例如,加载并清洗CSV数据、计算总销售额等。
51 2
|
3月前
|
机器学习/深度学习 人工智能 数据挖掘
从0到1构建AI帝国:PyTorch深度学习框架下的数据分析与实战秘籍
【7月更文挑战第30天】PyTorch以其灵活性和易用性成为深度学习的首选框架。
58 2
|
3月前
|
机器学习/深度学习 数据挖掘 PyTorch
🚀PyTorch实战宝典:从数据分析小白到深度学习高手的飞跃之旅
【7月更文挑战第29天】在数据驱动的世界里, **PyTorch** 作为深度学习框架新星, 凭借其直观易用性和高效计算性能, 助力数据分析新手成为深度学习专家。首先, 掌握Pandas、Matplotlib等工具进行数据处理和可视化至关重要。接着, 安装配置PyTorch环境, 学习张量、自动求导等概念。通过构建简单线性回归模型, 如定义 `nn.Module` 类、设置损失函数和优化器, 进行训练和测试, 逐步过渡到复杂模型如CNN和RNN的应用。不断实践, 你将能熟练运用PyTorch解决实际问题。
43 1

热门文章

最新文章

下一篇
无影云桌面