第一篇 从PyTorch到FastAI

2024-02-27 00:32
文章标签 pytorch 第一篇 fastai

本文主要是介绍第一篇 从PyTorch到FastAI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、使用PyTorchResNet18网络,在MNIST数据集上实现手写数字的分类

MNIST数据集下载地址。数据读取代码如下:

import pickle, gzip
import numpy as npdef load_data(data_pkl):with gzip.open(data_pkl, "rb") as fp:training_data, valid_data, test_data = pickle.load(fp, encoding="latin-1")return training_data, valid_data, test_datatraining_data, valid_data, test_data = load_data(data_pkl)
x_train, y_train = training_data
x_valid, y_valid = valid_data
x_test, y_test = test_data

所得到的数据为numpy的数组格式。其中每张图像为28x28大小的单通道数据,被扯成了一维向量。训练集、验证集、测试集各有500001000010000条数据。

图 1. MNIST数据示例
1. 定义数据集(Dataset)及数据加载器(Dataloader)

对于MNIST数据,PyTorch库中有两种方式比较适合将之整理为网络所需形式,一种是直接继承Dataset对象,并实现__len__()(返回数据集大小)和__getitem__()(实现数据集索引功能)函数;另一种是将数据整理为TensorDataset的形式。

(1) Dataset
from torch.utils.data import Dataset
import torch
# ImageNet的图像统计参数(RGB三通道的均值和方差)
stats = [np.array([0.485, 0.456, 0.406]).reshape(3,1,1), np.array([0.229, 0.224, 0.225]).reshape(3,1,1)]class MnistDataset(Dataset):def __init__(self, x, y):super().__init__()x_temp = x.reshape(-1, 28, 28)self.x = (np.stack((x_temp,)*3, 1)-stats[0])/stats[1]self.x = self.x.astype("float32")self.y = ydef __len__(self):return len(self.y)def __getitem__(self, index):return self.x[index, :], self.y[index]train_ds = MnistDataset(x_train, y_train)
valid_ds = MnistDataset(x_valid, y_valid)
test_ds = MnistDataset(x_test, y_test)

对于图像数据而言,__getitem__()返回的x需要为C x H x W的形式。

(2) TensorDataset
from torch.utils.data import TensorDatasetdef get_tensor_ds(ds):temp = np.stack((ds,)*3, 1)temp = temp.reshape(-1,3,28,28)temp = (temp - stats[0])/stats[1]return torch.from_numpy( temp )train_ds = TensorDataset(get_tensor_ds(x_train), torch.from_numpy(y_train))
valid_ds = TensorDataset(get_tensor_ds(x_valid), torch.from_numpy(y_valid))
test_ds = TensorDataset(get_tensor_ds(x_test), torch.from_numpy(y_test))

对图像数据而言,TensorDataset所需的图像数据为NxCxHxW的形式。

数据迭代器

from torch.utils.data import DataLoadertrain_dl = DataLoader(train_ds, batch_size=64, shuffle=True)
valid_dl = DataLoader(valid_ds, batch_size=64, shuffle=False)
test_dl = DataLoader(valid_ds, batch_size=32)
2. 使用预训练的ResNet18网络
from torch import nn
from torchvision import modelsnet = models.resnet18(pretrained=True)def set_parameter_requires_grad(model, feature_extrating):if feature_extrating:for param in model.parameters():param.requires_grad = False# 冻结预训练模型的参数
set_parameter_requires_grad(net, True)# ResNet会降采样32倍,对于28x28的网络,经过卷积层后的特征图就变成1x1大小的,因此不需要使用池化层进行进一步的下采样了。
class Identy(nn.Module):def forward(self, input):return input
net.avgpool = Identy()# 输出类别为10类
prev_fc = net.fc
net.fc = nn.Linear(in_features=prev_fc.in_features, out_features=10)
3. 损失函数和优化器

对于多分类问题,选择交叉熵损失函数

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
4. 训练流程控制

可参考PyTorch Tutorial中的迁移学习的训练过程train_model()(链接)。

如果仅更新最后一层全连接层的参数,则在测试集上可得到约72%的准确率。若使用迁移学习方法,在进行微调参数后,可得到约99%的准确率。

二、使用Fast.AI

1. 定义数据集(DataBunch)

首先下载数据

from fastai.vision import *
mnist = untar_data(URLs.MNIST)

其中所需要的函数untar_data定义如下:

untar_data(url, fname=None, dest=None, data=True, force_download=False) -> pathlib.Path

该函数从url指示的网址下载数据,并解压文件。可通过可选参数fnamedest指定保存路径。

下载的数据的目录结构如下:

~/.fastai/data/mnist_png/training/0/ 1/ ...  9/总计60000张单通道图片test/0/ 1/ ... 9/总计10000张单通道图片

然后将之整理为Fast AI的学习器所需的DataBunch对象(其实就是封装了训练集、验证集、测试集的数据迭代器):

tfms = get_transforms(do_flip=False)data = (ImageList.from_folder(mnist/"training") # 指定训练集的文件路径.split_by_rand_pct(0.2) # 按比例分割训练集和验证集.label_from_folder() # 指定类别标签.add_test_folder(mnist/"testing") # 添加测试集.transform(tfms, size=32) # 对图像的变换,并指定图像尺寸.databunch() # 生成databunch.normalize(imagenet_stats) # 数据归一化
)

其中get_transforms()imagenet_stats都是在fastai.vision中定义的。

2. 构建ResNet18网络
learn = cnn_learner(data, models.resnet18, metrics=accuracy)

cnn_learnerDataBunch数据对象,以及网络模型进一步封装,并可自动完成模型与实际问题的适配(如在ImageNet上预训练的模型是1000类,而MNIST数据仅需定义10类),并设置优化算法、进行网络训练的过程控制、设置模型指标评估等。
上述语句中models模块来源于torchvision,其实也是在fastai.vision中引入的。cnn_learner默认使用预训练的模型。

3. 进行迁移学习

先进行一轮的学习:

learn.fit_one_cycle(3, 1e-2)

可得准确率为98.9%
然后解冻预训练的模型,以较小的学习速率再进行训练。

learn.unfreeze()
learn.lr_find()
learn.fit_one_cycle(3, max_lr=slice(1e-6, 1e-4))

可得约99.17%的准确率。

4. 一些辅助功能
  • 显示数据

    data.show_batch(rows=3, figsize=(4,4))
    

    结果如下图:

    图 2. learn.show_batch( )绘图
  • 学习速率查找

    learn.lr_find()
    learn.recorder.plot()
    

    结果如下图:

    图 3. learn.recorder.plot( )绘图
  • 最错误的样本

    interp = ClassificationInterpretation.from_learner(learn)
    interp.plot_top_losses(9, figsize=(7,7))
    

    结果如下图:

    图 4. interp.plot_top_loss( )绘图
  • 混淆矩阵

    interp.plot_confusion_matrix(figsize=(9,9), dpi=60)
    

    结果如下图:

    图 5. interp.plot_confusion_matrix( )绘图

由上,使用Fast AIAPI,将极大减少准备数据集、以及训练流程控制方面的代码。此外,Fast AI还提供了许多可用于模型性能分析的工具。本系列的后续博文将结合Fast AI的文档进行更深入的介绍。

这篇关于第一篇 从PyTorch到FastAI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750665

相关文章

PyTorch使用教程之Tensor包详解

《PyTorch使用教程之Tensor包详解》这篇文章介绍了PyTorch中的张量(Tensor)数据结构,包括张量的数据类型、初始化、常用操作、属性等,张量是PyTorch框架中的核心数据结构,支持... 目录1、张量Tensor2、数据类型3、初始化(构造张量)4、常用操作5、常用属性5.1 存储(st

[Linux Kernel Block Layer第一篇] block layer架构设计

目录 1. single queue架构 2. multi-queue架构(blk-mq)  3. 问题 随着SSD快速存储设备的发展,内核社区越发发现,存储的性能瓶颈从硬件存储设备转移到了内核block layer,主要因为当时的内核block layer是single hw queue的架构,导致cpu锁竞争问题严重,本文先提纲挈领的介绍内核block layer的架构演进,然

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 (debug笔记)

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 ##一、 缘由及解决方法 把这个pytorch-ddpg|github搬到jupyter notebook上运行时,出现错误Nn criterions don’t compute the gradient w.r.t. targets error。注:我用

【超级干货】2天速成PyTorch深度学习入门教程,缓解研究生焦虑

3、cnn基础 卷积神经网络 输入层 —输入图片矩阵 输入层一般是 RGB 图像或单通道的灰度图像,图片像素值在[0,255],可以用矩阵表示图片 卷积层 —特征提取 人通过特征进行图像识别,根据左图直的笔画判断X,右图曲的笔画判断圆 卷积操作 激活层 —加强特征 池化层 —压缩数据 全连接层 —进行分类 输出层 —输出分类概率 4、基于LeNet

pytorch torch.nn.functional.one_hot函数介绍

torch.nn.functional.one_hot 是 PyTorch 中用于生成独热编码(one-hot encoding)张量的函数。独热编码是一种常用的编码方式,特别适用于分类任务或对离散的类别标签进行处理。该函数将整数张量的每个元素转换为一个独热向量。 函数签名 torch.nn.functional.one_hot(tensor, num_classes=-1) 参数 t

pytorch计算网络参数量和Flops

from torchsummary import summarysummary(net, input_size=(3, 256, 256), batch_size=-1) 输出的参数是除以一百万(/1000000)M, from fvcore.nn import FlopCountAnalysisinputs = torch.randn(1, 3, 256, 256).cuda()fl

Python(TensorFlow和PyTorch)两种显微镜成像重建算法模型(显微镜学)

🎯要点 🎯受激发射损耗显微镜算法模型:🖊恢复嘈杂二维和三维图像 | 🖊模型架构:恢复上下文信息和超分辨率图像 | 🖊使用嘈杂和高信噪比的图像训练模型 | 🖊准备半合成训练集 | 🖊优化沙邦尼尔损失和边缘损失 | 🖊使用峰值信噪比、归一化均方误差和多尺度结构相似性指数量化结果 | 🎯训练荧光显微镜模型和对抗网络图形转换模型 🍪语言内容分比 🍇Python图像归一化

android的工程和代码的命名规范(第一篇文章,勿喷)

1。首先我们从编译代码的工具说起吧:工程中的注释一般都是中文写的(毕竟大家都是中国人,还是习惯于中文)这样就设计到乱码的问题了;对于这类问题,我们一般最好的处理方法就是将工程设置成 UTF-8 的格式;下面就说说怎么将工作空间或者是工程设置成UTF-8 的格式吧(当然我这里面说的是eclips

Pytorch环境搭建时的各种问题

1 问题 1.一直soving environment,跳不出去。网络解决方案有:配置清华源,更新conda等,没起作用。2.下载完后,有3个要done的东西,最后那个exe开头的(可能吧),总是报错。网络解决方案有:用管理员权限打开prompt等,没起作用。3.有时候配置完源,安装包的时候显示什么https之类的东西,去c盘的用户那个文件夹里找到".condarc"文件把里面的网址都改成htt

【PyTorch】使用容器(Containers)进行网络层管理(Module)

文章目录 前言一、Sequential二、ModuleList三、ModuleDict四、ParameterList & ParameterDict总结 前言 当深度学习模型逐渐变得复杂,在编写代码时便会遇到诸多麻烦,此时便需要Containers的帮助。Containers的作用是将一部分网络层模块化,从而更方便地管理和调用。本文介绍PyTorch库常用的nn.Sequen