PyTorch基础知识总结

PyTorch基础知识总结

Tensor(张量)

张量是PyTorch里的基本运算单位,与numpy的ndarray相同都表示一个多维的矩阵。与ndarray最大的区别在于Tensor能使用GPU加速,而ndarray只能用在CPU上。


与Numpy之间进行转换

将Tensor转换成numpy,只需调用.numpy()方法即可。

将numpy转换成Tensor,使用torch.from_numpy()进行转换。

# a --> Tensor
a = torch.rand(3, 2)
# Tensor --> numpy
numpy_a = a.numpy()
# numpy --> Tensor
b = torch.from_numpy(numpy_a)


Tensor初始化
  • torch.rand(*size) : 使用[0, 1]均匀分布随机初始化
  • torch.randn(*size) : 服从正太分布初始化
  • torch.zeros(*size) : 使用1填充
  • torch.ones(*size):使用0填充
  • torch.eye(*size) :初始化一个单位矩阵,即对角线为1,其余为0



Autograd

PyTorch中的Autograd模块实现了深度学习的算法中的反向传播求导数,在Tensor上的所有操作,Autograd都能为它们自动计算微分,简化了手动求导数的过程。


在张量创建时,通过设置requires_grad = True来告诉PyTorch需要对该张量进行自动求导,PyTorch会记录该张量的每一步操作历史并自动计算导数。requires_grad默认为False。

x = torch.randn(5, 5, requires_grad = True)

在计算完成后,调用backward()方法会自动根据历史操作来计算梯度,并保存在grad中。



神经网络包nn (torch.nn)

torch.nn是专门为神经网络设计的模块化接口,建立在Autogard之上。

通常定义一个神经网络类除了使用到nn之外还会引用nn.functional,这个包中包含了神经网络中使用的一些常见函数(ReLu, pool, sigmoid, softmax等),这些函数一般放在forward函数中。


通常一个神经网络类需要继承nn.Module,并实现forward方法,PyTorch就会根据autograd自动实现backward方法。下面是LeNet网络模型的定义。

import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()

        # 卷积层
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)

        # 全连接层
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 卷积 --> ReLu --> 池化
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))

        # reshape, '-1'表示自适应
        # x = (n * 16 * 5 * 5) --> n : batch size
        # x.size()[0] == n --> batch size
        x = x.view(x.size()[0], -1)

        # 全连接层
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x



损失函数

在torch.nn中还定义了一些常用的损失函数,比如MESLoss(均方误差),CrossEntropyLoss(交叉熵误差)等。

labels = torch.arange(10).view(1, 10).float()
out = net(input)
criterion = nn.MSELoss()
# 计算loss
loss = criterion(labels, out)



优化器(torch.optim)

在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的参数,常用的优化方法有随机梯度下降法(SGD),策略如下:

weight = weight - learning_rate * gradient

import torch.optim
import torch.nn as nn

out = net(input)
criterion = nn.MSELoss(out, labels)
# 新建一个优化器,SGD只需要输入要调整的参数和学习率
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01)
# 反向传播前,先梯度清0, optimizer.zero_grad()等同于net.zero_grad()
optimizer.zero_grad()
loss.backward()

# 更新参数
optimizer.step()



数据的加载和预处理

PyTorch通过torch.utils.data对一般常用的数据加载进行了封装,可以很容易实现数据预处理和批量加载。torchvision已经有一些常用的数据集以及训练好的模型(例如,CIFAR-10, ImageNet, COCO等),可以很方便的在这些模型上进行训练以及测试。


Dataset(torch.utils.data.Dataset)

为了方便数据的读取,通常需要将使用的数据集包装为Dataset类。可以使用torchvision.dataset包中存在数据集来生成Dataset,同时也可以自定义Dataset类。

以torchvision.dataset中MNIST数据集为例生成dataset

dataset = tv.datasets.MNIST(
    root='data/',
    train=True,
    download=True,
    transform=None
)


自定义Dataset,当torchvision.dataset包中没有相应的数据集,这时候就需要我们自定义Dataset类了,自定义类必须继承于torch.utils.data.Dataset类,并且实现__ len __ () 和 __ getitem __ () 方法。

  • __ len __ () 该方法返回数据集的总长度。
  • __ getitem __ () 该方法通过索引[0, len(self) - 1]来获取一条数据或者一个样本。


DataLoader(torch.utils.data.DataLoader)

DataLoader为我们提供了对Dataset的读取操作,常用的参数有batch_size(每一批数据的大小), shuffle(是否进行随机读取操作), num_workers(加载数据的时候使用几个子进程)

trainloader = torch.utils.data.DataLoader(dataset, batch_size=10, shuffle=True, num_works=0)

# trainloader是一个可迭代的对象,我们可以使用iter分次获取数据。
# 但是通常使用for循环来对其进行遍历,如下。
for i, data in enumerate(trainloader):
    # deal the data
    pass

此时,我们可以通过Dataset加装数据集,并使用DataLoader来遍历处理数据。


torchvision包

torchvision是专门用来处理图像的库,里面有datasets, models, transforms等类,其中最常用的类是transforms,它通常用来进行数据的预处理(ToTensor, 归一化等),如下。

from torchvision import transforms as transforms
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225)), #R,G,B每层的归一化用到的均值和方差
])


THE END


原文链接:加载失败,请重新获取