torchvision

torchvision包 包含了目前流行的数据集,模型结构和常用的图片转换工具。

1. torchvision.datasets

torchvision.datasets中包含了以下数据集

  • MNIST
  • COCO(用于图像标注和目标检测)(Captioning and Detection)
  • LSUN Classification
  • ImageFolder
  • Imagenet-12
  • CIFAR10 and CIFAR100
  • STL10
__all__ = ('LSUN', 'LSUNClass',
           'ImageFolder', 'DatasetFolder', 'FakeData',
           'CocoCaptions', 'CocoDetection',
           'CIFAR10', 'CIFAR100', 'EMNIST', 'FashionMNIST', 'QMNIST',
           'MNIST', 'KMNIST', 'STL10', 'SVHN', 'PhotoTour', 'SEMEION',
           'Omniglot', 'SBU', 'Flickr8k', 'Flickr30k',
           'VOCSegmentation', 'VOCDetection', 'Cityscapes', 'ImageNet',
           'Caltech101', 'Caltech256', 'CelebA', 'SBDataset', 'VisionDataset',
           'USPS', 'Kinetics400', 'HMDB51', 'UCF101')

例如,我们可以通过datasets.CIFAR10获得一个CIFAR10的数据集类对象。例如:

dset.MNIST(root, train=True, transform=None, target_transform=None, download=False)

除此之外,datasets下的Datasets类都是torch.utils.data.Dataset的子类,所以,这些类我们都可以直接拿来用,它返回的是torch.utils.data.Dataset的子类对象。最常用的类是datasets.ImageFolder(DatasetFolder),其中DatasetFolder类间接继承了torch.utils.data.Dataset

class ImageFolder(DatasetFolder):

    def __init__(self, root, transform=None, target_transform=None,
                 loader=default_loader, is_valid_file=None):
        super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,
                                          transform=transform,
                                          target_transform=target_transform,
                                          is_valid_file=is_valid_file)
        self.imgs = self.samples

参数说明

  • root:数据集所在的文件夹
  • transform:一个函数,原始图片作为输入,返回一个转换后的图片。用torchvision.transforms产生。
  • target_transform:一个函数,输入为target,输出对其的转换。例子,输入的是图片标注的string,输出为word的索引。

2. torchvision.models

torchvision.models模块的 子模块中包含以下模型结构。

from .alexnet import *
from .resnet import *
from .vgg import *
from .squeezenet import *
from .inception import *
from .densenet import *
from .googlenet import *
from .mobilenet import *
from .mnasnet import *
from .shufflenetv2 import *

你可以使用随机初始化的权重来创建这些模型。

import torchvision.models as models
resnet18 = models.resnet18()
alexnet = models.alexnet()
squeezenet = models.squeezenet1_0()
densenet = models.densenet_161()

也可以使用预训练的模型,只要设置pretrained=True即可。

import torchvision.models as models
#pretrained=True就可以使用预训练的模型
resnet18 = models.resnet18(pretrained=True)
alexnet = models.alexnet(pretrained=True)

3. torchvision.transforms

这是一个图像转换工具。

3.1 对PIL.Image进行变换

class torchvision.transforms.Compose(transforms)

将多个transform组合起来使用。

transforms: 由transform构成的列表. 例子:

transforms.Compose([
     transforms.CenterCrop(10),
     transforms.ToTensor(),
 ])

### class torchvision.transforms.Scale(size, interpolation=2)

将输入的`PIL.Image`重新改变大小成给定的`size`,`size`是最小边的边长。举个例子,如果原图的`height>width`,那么改变大小后的图片大小是`(size*height/width, size)`。
**用例:**

from torchvision import transforms
from PIL import Image
crop = transforms.Scale(12)
img = Image.open('test.jpg')

print(type(img))
print(img.size)

croped_img=crop(img)
print(type(croped_img))
print(croped_img.size)

结果

<class 'PIL.PngImagePlugin.PngImageFile'>
(10, 10)
<class 'PIL.Image.Image'>
(12, 12)

class torchvision.transforms.CenterCrop(size)

将给定的PIL.Image进行中心切割,得到给定的sizesize可以是tuple(target_height, target_width)size也可以是一个Integer,在这种情况下,切出来的图片的形状是正方形。

class torchvision.transforms.RandomCrop(size, padding=0)

切割中心点的位置随机选取。size可以是tuple也可以是Integer

class torchvision.transforms.RandomHorizontalFlip

随机水平翻转给定的PIL.Image,概率为0.5。即:一半的概率翻转,一半的概率不翻转。

class torchvision.transforms.RandomSizedCrop(size, interpolation=2)

先将给定的PIL.Image随机切,然后再resize成给定的size大小。

class torchvision.transforms.Pad(padding, fill=0)

将给定的PIL.Image的所有边用给定的pad value填充。

  • padding:要填充多少像素
  • fill:用什么值填充
from torchvision import transforms
from PIL import Image
padding_img = transforms.Pad(padding=10, fill=0)
img = Image.open('test.jpg')

print(type(img))
print(img.size)

padded_img=padding(img)
print(type(padded_img))
print(padded_img.size)

结果:

<class 'PIL.PngImagePlugin.PngImageFile'>
(10, 10)
<class 'PIL.Image.Image'>
(30, 30) #由于上下左右都要填充10个像素,所以填充后的size是(30,30)

3.2 对Tensor进行变换

class torchvision.transforms.Normalize(mean, std)

给定均值:(R,G,B) 方差:(R,G,B),将会把Tensor正则化。即:Normalized_image=(image-mean)/std

3.3 Conversion Transforms

class torchvision.transforms.ToTensor

把一个取值范围是[0,255]PIL.Image或者shape(H,W,C)numpy.ndarray,转换成形状为[C,H,W],取值范围是[0,1.0]torch.FloadTensor

class torchvision.transforms.ToPILImage

shape(C,H,W)Tensorshape(H,W,C)numpy.ndarray转换成PIL.Image,值不变。

3.4 通用变换

class torchvision.transforms.Lambda(lambd)

使用lambd作为转换器。

4. torchvision.utils

torchvision.utils.make_grid(tensor, nrow=8, padding=2, normalize=False, range=None, scale_each=False)

不知道怎么用。用来做雪碧图?雪碧图是啥?

torchvision.utils.save_image(tensor, filename, nrow=8, padding=2, normalize=False, range=None, scale_each=False)

将给定的Tensor保存成image文件。如果给定的是mini-batch tensor,那就用make-grid做成雪碧图,再保存。

5. 代码讲解

下面给出王晋东博士迁移学习简明手册上的深度网络的 finetune 代码范例。

# -*- coding: utf-8 -*-

from torchvision import datasets, transforms
import torch
import os


def load_data(root_path, dir, batch_size, phase):
    transform_dict = {
        'src': transforms.Compose(
        [transforms.RandomResizedCrop(224),#先随机采集,然后对裁剪得到的图像缩放为同一大小
         transforms.RandomHorizontalFlip(),#以给定的概率随机水平旋转给定的PIL的图像,默认为0.5
         transforms.ToTensor(),
         transforms.Normalize(mean=[0.485, 0.456, 0.406],#ImageNet的均值和标准差。它们是根据数百万张图像计算得出的。使用它进行归一化是为了使用Imagenet预设模型进行迁移学习
                              std=[0.229, 0.224, 0.225]),
         ]),
        'tar': transforms.Compose(
        [transforms.Resize(224),
         transforms.ToTensor(),
         transforms.Normalize(mean=[0.485, 0.456, 0.406],
                              std=[0.229, 0.224, 0.225]),
         ])}
    data = datasets.ImageFolder(root=os.path.join(root_path, dir), transform=transform_dict[phase])
    #数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集。
    #在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化。
    data_loader = torch.utils.data.DataLoader(data, batch_size=batch_size, shuffle=True, drop_last=False, num_workers=4)
    return data_loader

def load_train(root_path, dir, batch_size, phase):
    transform_dict = {
        'src': transforms.Compose(
            [transforms.RandomResizedCrop(224),
             transforms.RandomHorizontalFlip(),
             transforms.ToTensor(),
             transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                  std=[0.229, 0.224, 0.225]),
             ]),
        'tar': transforms.Compose(
            [transforms.Resize(224),
             transforms.ToTensor(),
             transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                  std=[0.229, 0.224, 0.225]),
             ])}
    data = datasets.ImageFolder(root=os.path.join(root_path, dir), transform=transform_dict[phase])
    train_size = int(0.8 * len(data))
    test_size = len(data) - train_size
    data_train, data_val = torch.utils.data.random_split(data, [train_size, test_size])
    train_loader = torch.utils.data.DataLoader(data_train, batch_size=batch_size, shuffle=True, drop_last=False, num_workers=4)
    val_loader = torch.utils.data.DataLoader(data_val, batch_size=batch_size, shuffle=True, drop_last=False, num_workers=4)
    return train_loader, val_loader

你可能感兴趣的:(#,Pytorch常用库,pytorch,torchvision)