(一)计算机视觉工具包的介绍
为了方便开发者应用,PyTorch专门开发了一个视觉工具包torchvision,主要包含以下三个部分:
1.models
models提供了深度学习中各种经典的神经网络及预训练模型,包括AlexNet、VGG系列、ResNet系列、Inception系列等。例如下面的代码实现了加载预训练模型ResNet34(如果不存在就会自动下载),预训练模型保存在/.torch/models/下。对加载的预训练模型,读者可以根据自己的喜欢更改。
from torchvision import models
from torch import nn
# 加载预训练模型
resnet34 = models.resnet34(pretrained=True, num_classes=1000)
# 修改最后的全连接层改为100分类问题,(默认ImageNet上的1000分类)
resnet34.fc = nn.Linear(512, 100)
2.datasets
datasets提供常用的数据集,数据集在设计上继承torch.utils.data.Dataset,主要包括MNIST、CIFAR10/100、ImageNet、COCO等。
from torchvision import datasets
# 指定数据集路径为data,如果数据集不存在则自动下载
train_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf, download=True)
test_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf)
3.transforms
transforms提供常用的图像处理的函数,主要有Tensor及PIL Image(PIL:Python Image Library, Python图像库)对象的操作。
对Tensor的有:
(1)Normalize():标准化(减去均值后,除以标准化)
(2)ToPILImage():将Tensor对象转换为PIL Image对象
对PIL Image有:
(1)Scale()调整图像的尺寸,长宽比保持不变
(2)CenterCrop()、RandomCrop()、RandomResizedCrop():裁剪图片
(3)Pad():填充图片
(4)ToTensor:将PIL Image对象转化为Tensor对象,会自动的将[0,255]归一化到[0,1]
如果需要进行多个操作,可以通过Compose()函数将这些操作拼接起来,起类似于nn.Sequential()函数,注意这些函数以函数的形式存在真正使用要调用它的_call_方法,这点类似于nn.Module()函数
Compose()函数示例代码如下:
from torchvision import transforms as T
transform = T.Compose([
T.Resize(128), # 缩放图像,保持长宽比不变,最短边长度为128
T.CenterCrop(128), # 从图片中间切出128*128的图片
T.toTensor(),
T.Normalize(mean=[.8, .8, .8], std=[.8, .8, .8])
])
二、全连接神经网络实现多分类
from torchvision import models
from torch import nn
from torchvision import datasets
class simpleNet(nn.Module):
# 定义一个最简单的三层全连接神经网络,每一层都是线性的
def __init__(self, in_dim, n_hidden_1, n_hiddle_2, out_dim):
super(simpleNet,self).__init__()
self.layer1 = nn.Linear(in_dim, n_hidden_1)
self.layer2 = nn.Linear(n_hidden_1, n_hiddle_2)
self.layer3 = nn.Linear(n_hiddle_2, out_dim)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
"""
改进一下simpleNet网络,添加激励函数,增强网络的非线性,将新网络命名为Activation_Net。激励函数的选择有很多,这里选择RELU()函数
"""
class Activation_Net(nn.Module):
# 在上面的simpleNet网络的基础上,在每层的输出部分添加激励函数
def __init__(self, in_dim, n_hiddle_1, n_hiddle_2, out_dim):
super(Activation_Net, self).__init__()
# 下部分代码(除了输出层)的输出部分都添加了激励函数,最后还用了nn.Sequential()函数,这个函数将
# nn.Linear()函数和nn.ReLU()函数组合到一起作为self。layer。注意输出层不能有激励函数,因为输出结果表示实际的预测值
self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hiddle_1), nn.ReLU(True))
self.layer2 = nn.Sequential(nn.Linear(n_hiddle_1, n_hiddle_2), nn.ReLU(True))
self.layer3 = nn.Sequential(nn.Linear(n_hiddle_2, out_dim))
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
"""
最后我们还需要增加一个加快收敛速度的函数——即为批标准化函数,将新网络命名为Batch_Net,
对于批处理同样使用nn.Sequential()函数,将nn.BatchNormld()函数组合进了网络中,
注意,批标准化函数一般放在激励函数的前面
"""
class Batch_Net(nn.Module):
def __init__(self, in_dim, n_hiddle_1, n_hiddle_2, out_dim):
super(Batch_Net, self).__init__()
self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hiddle_1), nn.BatchNorm1d(n_hiddle_1), nn.ReLU(True))
self.layer2 = nn.Sequential(nn.Linear(n_hiddle_1, n_hiddle_2), nn.BatchNorm1d(n_hiddle_2), nn.ReLU(True))
self.layer3 = nn.Sequential(nn.Linear(n_hiddle_2, out_dim))
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x