PyTorch生态系统简介
50 Tools to Make Working with PyTorch Easier
-
图像:torchvision
-
视频:TorchVideo
-
文本:torchtext
可提供:
数据集
图像变换
预定义模型结构
预训练模型权重
工具箱
数据处理工具
数据集
词表工具
测评指标
……
torchvision | 功能 |
---|---|
torchvision.datasets | 几个常用视觉数据集,可以下载和加载 |
torchvision.models | 流行的模型,例如 AlexNet, VGG, ResNet 和 Densenet 以及 与训练好的参数 |
torchvision.tramsforms | 常用的图像操作,例如:随机切割,旋转,数据类型转换,图像到tensor ,numpy 数组到tensor , tensor 到 图像等。 |
torchvision.io | |
torchvision.ops | |
torchvision.utils | 用于把形似 (3 x H x W) 的张量保存到硬盘中,给一个mini-batch的图像可以产生一个图像格网。 |
1.1、torchvision.datasets
数据集 | 说明 | 数据集 | 说明 |
---|---|---|---|
Caltech | 加州理工学院的行人数据集 | KMNIST | 古日文手写识别数据集 |
CelebA | CeleA是香港中文大学的开放数据(人脸数据集),包含10177个名人身份的202599张图片,并且都做好了特征标记 | PhotoTour | 旅游景点图片数据集。 |
CIFAR | 经典的10分类(CIFAR-10)/100分类(CIFAR-100)图像数据集 | Places365 | 场景识别数据集 |
Cityscapes | 自动驾驶数据集,包括了国外多个城市街道场景图片 | QMNIST | MNIST的重构数据集。 |
EMNIST | Extended MNIST (EMNIST),是MNIST数据集的扩展,包含手写数字、字母等 | SBD | VOC数据集的扩展。 |
FakeData | SEMEION | 手写数字识别数据集。 | |
Fashion-MNIST | 类似于MNIST数据集,是服装的分类(T恤、衣服、裤子、鞋子等) | STL10 | 用于开发无监督特征学习、深度学习和自学学习算法的图像识别数据集,类似于CIFAR-10,但每个类标记训练示例较少。 |
Flickr | 图文匹配数据集 | SVHN | 街景门牌号码图片数据集。 |
ImageNet | 经典的图像识别数据集 | UCF101 | 截至2012年最大的动作识别类数据集(视频数据),包含101个类别和13320个视频。 |
Kinetics-400 | 人体动作识别数据集,包括至少400种人体动作类别,每个类别有至少400段视频 | UCF101 | Visual Object Class,目标检测、图像分割等视觉任务数据集。 |
KITTI | 自动驾驶场景下的计算机视觉算法评测数据集 | WIDERFace | 人脸检测的一个benchmark数据集 |
1.2、torchvision.transforms
对图片归一化,大小缩放,对现有图片数据进行各种变换,如缩小或放大、水平或垂直翻转等
from torchvision import transforms
data_transform = transforms.Compose([
transforms.ToPILImage(), # 这一步取决于后续的数据读取方式,如果使用内置数据集则不需要
transforms.Resize(image_size),
transforms.ToTensor()
])
1.3、torchvision.models
为了提高训练效率,减少不必要的重复劳动,PyTorch官方也提供了一些预训练好的模型供我们使用,可以点击这里进行查看现在有哪些预训练模型。现有的预训练模型主要包括:
-
分类模型(Classification)
AlexNet | VGG | ResNet | SqueezeNet |
---|---|---|---|
DenseNet | Inception v3 | GoogLeNet | ShuffleNet v2 |
MobileNetV2 | MobileNetV3 | ResNext | Wide ResNet |
MNASNet | EfficientNet | RegNet |
-
语义分割模型(Semantic Segmentation )
语义分割的预训练模型是在COCO train2017的子集上训练
FCN ResNet50 | FCN ResNet101 | DeepLabV3 ResNet50 | DeepLabV3 ResNet101 |
---|---|---|---|
LR-ASPP MobileNetV3-Large | DeepLabV3 MobileNetV3-Large |
-
物体检测(Object Detection),实例分割(Instance Segmentation)和人体关键点检测(Keypoint Detection)
Faster R-CNN | Mask R-CNN | RetinaNet | SSDlite |
---|---|---|---|
SSD |
-
视频分类(Video classification)
视频分类模型是在 Kinetics-400上进行预训练
ResNet 3D 18 | ResNet MC 18 | ResNet (2+1) D |
---|---|---|
二、PyTorchVideo
PyTorchVideo
深度学习库
专注于视频理解工作的深度学习库
提供了加速视频理解研究所需的可重用、模块化和高效的组件
支持不同的深度学习视频组件,如视频模型、视频数据集和视频特定转换
亮点:
提供了加速视频理解研究所需的模块化和高效的API、支持不同的深度学习视频组件,如视频模型、视频数据集和视频特定转换、也提供了model zoo,使得人们可以使用各种先进的预训练视频模型及其评判基准
基于 PyTorch: 使用 PyTorch 构建。使所有 PyTorch 生态系统组件的使用变得容易。
Model Zoo: PyTorchVideo提供了包含I3D、R(2+1)D、SlowFast、X3D、MViT等SOTA模型的高质量model zoo(目前还在快速扩充中,未来会有更多SOTA model),并且PyTorchVideo的model zoo调用与PyTorch Hub做了整合,大大简化模型调用。
数据预处理和常见数据: PyTorchVideo支持Kinetics-400, Something-Something V2, Charades, Ava (v2.2), Epic Kitchen, HMDB51, UCF101, Domsev等主流数据集和相应的数据预处理,同时还支持randaug, augmix等数据增强trick。
模块化设计: PyTorchVideo的设计类似于torchvision,也是提供许多模块方便用户调用修改,在PyTorchVideo中具体来说包括data, transforms, layer, model, accelerator等模块,方便用户进行调用和读取。
支持多模态: PyTorchVideo现在对多模态的支持包括了visual和audio,未来会支持更多模态,为多模态模型的发展提供支持。
移动端部署优化: PyTorchVideo支持针对移动端模型的部署优化(使用前述的PyTorchVideo/accelerator模块),模型经过PyTorchVideo优化了最高达7倍的提速,并实现了第一个能实时跑在手机端的X3D模型(实验中可以实时跑在2018年的三星Galaxy S8上,具体请见Android Demo APP)。
2.1、PyTorchVideo的安装
pip install pytorchvideo
2.2、PyTorchVideo model zoo
-
TorchHub,这些模型都已经在TorchHub存在。我们可以根据实际情况来选择需不需要使用预训练模型。除此之外,官方也给出了TorchHub使用的 tutorial 。
-
PySlowFast,使用 PySlowFast workflow 去训练或测试PyTorchVideo models/datasets.
-
PyTorch Lightning建立一个工作流进行处理,点击查看官方 tutorial。
-
如果想查看更多的使用教程,可以点击 这里 进行尝试
三、torchtext
PyTorch官方用于自然语言处理(NLP)的工具包,自然语言处理也是深度学习的一大应用场景,近年来随着大规模预训练模型的应用,深度学习在人机对话、机器翻译等领域的取得了非常好的效果,也使得NLP相关的深度学习模型获得了越来越多的关注
3.1、torchtext的主要组成部分
torchtext可以方便的对文本进行预处理,例如截断补长、构建词表等。torchtext主要包含了以下的主要组成部分:
-
数据处理工具 torchtext.data.functional、torchtext.data.utils
-
数据集 torchtext.data.datasets
-
词表工具 torchtext.vocab
-
评测指标 torchtext.metrics
3.2、torchtext的安装
pip install torchtext
3.3、构建数据集
-
Field及其使用
Field是torchtext中定义数据类型以及转换为张量的指令
torchtext
认为一个样本是由多个字段(文本字段,标签字段)组成,不同的字段可能会有不同的处理方式,所以才会有 Field
抽象。定义Field对象是为了明确如何处理不同类型的数据,但具体的处理则是在Dataset中完成的
tokenize = lambda x: x.split()
TEXT = data.Field(sequential=True, tokenize=tokenize, lower=True, fix_length=200)
LABEL = data.Field(sequential=False, use_vocab=False)
sequential设置数据是否是顺序表示的;
tokenize用于设置将字符串标记为顺序实例的函数
lower设置是否将字符串全部转为小写;
fix_length设置此字段所有实例都将填充到一个固定的长度,方便后续处理;
use_vocab设置是否引入Vocab object,如果为False,则需要保证之后输入field中的data都是numerical的
进一步构建dataset:
from torchtext import data
def get_dataset(csv_data, text_field, label_field, test=False):
fields = [("id", None), # we won't be needing the id, so we pass in None as the field
("comment_text", text_field), ("toxic", label_field)]
examples = []
if test:
# 如果为测试集,则不加载label
for text in tqdm(csv_data['comment_text']):
examples.append(data.Example.fromlist([None, text, None], fields))
else:
for text, label in tqdm(zip(csv_data['comment_text'], csv_data['toxic'])):
examples.append(data.Example.fromlist([None, text, label], fields))
return examples, fields
这里使用数据csv_data中有"comment_text"和"toxic"两列,分别对应text和label
train_data = pd.read_csv('train_toxic_comments.csv')
valid_data = pd.read_csv('valid_toxic_comments.csv')
test_data = pd.read_csv("test_toxic_comments.csv")
TEXT = data.Field(sequential=True, tokenize=tokenize, lower=True)
LABEL = data.Field(sequential=False, use_vocab=False)
# 得到构建Dataset所需的examples和fields
train_examples, train_fields = get_dataset(train_data, TEXT, LABEL)
valid_examples, valid_fields = get_dataset(valid_data, TEXT, LABEL)
test_examples, test_fields = get_dataset(test_data, TEXT, None, test=True)
# 构建Dataset数据集
train = data.Dataset(train_examples, train_fields)
valid = data.Dataset(valid_examples, valid_fields)
test = data.Dataset(test_examples, test_fields)
可以看到,定义Field对象完成后,通过get_dataset函数可以读入数据的文本和标签,将二者(examples)连同field一起送到torchtext.data.Dataset类中,即可完成数据集的构建
# 检查keys是否正确
print(train[0].__dict__.keys())
print(test[0].__dict__.keys())
# 抽查内容是否正确
print(train[0].comment_text)
-
词汇表(vocab)
将句子中的词语转为向量表示
在torchtext中可以使用Field自带的build_vocab函数完成词汇表构建。TEXT.build_vocab(train)
-
数据迭代器
其实就是torchtext中的DataLoader:
from torchtext.data import Iterator, BucketIterator
# 若只针对训练集构造迭代器
# train_iter = data.BucketIterator(dataset=train, batch_size=8, shuffle=True, sort_within_batch=False, repeat=False)
# 同时对训练集和验证集进行迭代器的构建
train_iter, val_iter = BucketIterator.splits(
(train, valid), # 构建数据集所需的数据集
batch_sizes=(8, 8),
device=-1, # 如果使用gpu,此处将-1更换为GPU的编号
sort_key=lambda x: len(x.comment_text), # the BucketIterator needs to be told what function it should use to group the data.
sort_within_batch=False
)
test_iter = Iterator(test, batch_size=8, device=-1, sort=False, sort_within_batch=False)
torchtext支持只对一个dataset和同时对多个dataset构建数据迭代器。
-
使用自带数据集
与torchvision类似,torchtext也提供若干常用的数据集方便快速进行算法测试。可以查看官方文档寻找想要使用的数据集。
3.4、评测指标(metric)
NLP中部分任务的评测不是通过准确率等指标完成的
torchtext中可以直接调用torchtext.data.metrics.bleu_score来快速实现BLEU
from torchtext.data.metrics import bleu_score
candidate_corpus = [['My', 'full', 'pytorch', 'test'], ['Another', 'Sentence']]
references_corpus = [[['My', 'full', 'pytorch', 'test'], ['Completely', 'Different']], [['No', 'Match']]]
bleu_score(candidate_corpus, references_corpus)
0.8408964276313782
四、transforms实战
from PIL import Image
from torchvision import transforms
import matplotlib.pyplot as plt
# 加载原始图片
img = Image.open("./xiaomai.jpg")
print(img.size)
plt.imshow(img)
plt.show()
(461, 319)
transforms.CenterCrop(size)
沿中心切割
# 对给定图片进行沿中心切割
# 对图片沿中心放大切割,超出图片大小的部分填0
img_centercrop1 = transforms.CenterCrop((500,500))(img)
print(img_centercrop1.size)
# 对图片沿中心缩小切割,超出期望大小的部分剔除
img_centercrop2 = transforms.CenterCrop((224,224))(img)
print(img_centercrop2.size)
plt.subplot(1,3,1),plt.imshow(img),plt.title("Original")
plt.subplot(1,3,2),plt.imshow(img_centercrop1),plt.title("500 * 500")
plt.subplot(1,3,3),plt.imshow(img_centercrop2),plt.title("224 * 224")
plt.show()
(461, 319)
(500, 500)
(224, 224)
transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)
# 对图片的亮度,对比度,饱和度,色调进行改变
img_CJ = transforms.ColorJitter(brightness=1,contrast=0.5,saturation=0.5,hue=0.5)(img)
print(img_CJ.size)
plt.imshow(img_CJ)
(461, 319)
transforms.Grayscale(num_output_channels)
# 等比缩放
img_resize = transforms.Resize(224)(img)
print(img_resize.size)
plt.imshow(img_resize)
(323, 224)
transforms.RandomCrop
随机切割
# 随机裁剪成指定大小
# 设立随机种子
import torch
torch.manual_seed(31)
# 随机裁剪
img_randowm_crop1 = transforms.RandomCrop(224)(img)
img_randowm_crop2 = transforms.RandomCrop(224)(img)
print(img_randowm_crop1.size)
plt.subplot(1,2,1),plt.imshow(img_randowm_crop1)
plt.subplot(1,2,2),plt.imshow(img_randowm_crop2)
plt.show()
transforms.RandomHorizontalFlip
# 随机左右旋转
# 设立随机种子,可能不旋转
import torch
torch.manual_seed(31)
img_random_H = transforms.RandomHorizontalFlip()(img)
print(img_random_H.size)
plt.imshow(img_random_H)
plt.show()
(461, 319)
transforms.RandomVerticalFlip
# 随机垂直方向旋转
img_random_V = transforms.RandomVerticalFlip()(img)
print(img_random_V.size)
plt.imshow(img_random_V)
transforms.RandomResizedCrop
# 随机裁剪成指定大小
img_random_resizecrop = transforms.RandomResizedCrop(224,scale=(0.5,0.5))(img)
print(img_random_resizecrop.size)
plt.imshow(img_random_resizecrop)
对图片进行组合变化 tranforms.Compose()
# 对一张图片的操作可能是多种的,我们使用transforms.Compose()将他们组装起来
transformer = transforms.Compose([
transforms.Resize(256),
transforms.transforms.RandomResizedCrop((224), scale = (0.5,1.0)),
transforms.RandomVerticalFlip(),
])
img_transform = transformer(img)
plt.imshow(img_transform)