UP | HOME

PyTorch

Table of Contents

1 PyTorch

PyTorch 和 Numpy 的数组和相似,PyTorch 的数据类型大多数是叫 Tensor,并且 Tensor 可以在 GPU 上进行计算,用于提高计算效率

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

import torchvision
import torchvision.transforms as transforms

import numpy as np

torch.set_printoptions(linewidth=200)

2 基础运算

2.1 初始化、数据类型

x0 = torch.zeros(2, 3)
x1 = torch.ones(3, 2)
x2 = torch.zeros(2, 3, dtype=torch.long) # dtype: int32 int64 float32 float64
x3 = torch.tensor([1.1, 3.0])
print(x1)
print(x2)
print(x3)
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]])
tensor([[0, 0, 0],
        [0, 0, 0]])
tensor([1.1000, 3.0000])

获取默认创建的数据类型

print(torch.get_default_dtype())
torch.float32

2.2 获取形状

获取 Tensor 的形状和元素数量

x1 = torch.tensor([1.1, 3.0])
print(x1.size())
print(x1.numel()) # number of elements

x2 = torch.tensor([[1.1, 3.0, 3.3], [3, 4, 5]])
print(x2.size())
print(x2.numel())
torch.Size([2])
2
torch.Size([2, 3])
6

2.3 Tensor 和 ndarray 数据类型互转

t1 = torch.randn((2, 3)) # normal distribution with shape (2,3)
a1 = t1.numpy()
print(t1)
print(a1)

a2 = np.random.normal(0, 0.01, 6)
t2 = torch.from_numpy(a2)
print(a2)
print(t2)
tensor([[-0.0652, -0.3537,  1.3550],
        [-0.6979, -0.7713, -0.5261]])
[[-0.0652356  -0.35367048  1.3549587 ]
 [-0.6978578  -0.7712709  -0.5261264 ]]
[-0.0092347  -0.00012146 -0.00581832 -0.00620685 -0.00119326 -0.00189925]
tensor([-0.0092, -0.0001, -0.0058, -0.0062, -0.0012, -0.0019], dtype=torch.float64)

PyTorch 和 Numpy 数据关系包含两种关系:share vs. copy

a = np.array([1, 2, 3])
print(a)

t1 = torch.Tensor(a)
t2 = torch.tensor(a)
t3 = torch.as_tensor(a)
t4 = torch.from_numpy(a)

a[0] = 0
a[1] = 0
print(t1)
print(t2)
print(t3)
print(t4)
[1 2 3]
tensor([1., 2., 3.])
tensor([1, 2, 3])
tensor([0, 0, 3])
tensor([0, 0, 3])

3 形状变换

3.1 变形

如果想要 resize 或 reshape 一个 tensor,可以使用 view 方法。如果需要 copy,用 clone, 如果需要源数据,用 view, reshape 这玩意不好控制,则没那么可控,他的执 行结果可能是源数据的一个 copy,也可能不是,最好少用

x1 = torch.randn(24)
x2 = x1.view(2, 3, 4)
x3 = x1.view(4, -1)
print(x2)
print(x3)
tensor([[[-0.0513,  1.5727,  1.4737,  0.3913],
         [ 2.2639,  0.4963,  0.3401, -0.2731],
         [-1.4023,  1.7182,  0.9297,  0.1243]],

        [[-0.4909, -0.5568,  1.9808,  0.7490],
         [ 0.1885,  0.4245,  0.0027, -0.8911],
         [-0.7410,  1.0522, -0.8816, -2.5483]]])
tensor([[-0.0513,  1.5727,  1.4737,  0.3913,  2.2639,  0.4963],
        [ 0.3401, -0.2731, -1.4023,  1.7182,  0.9297,  0.1243],
        [-0.4909, -0.5568,  1.9808,  0.7490,  0.1885,  0.4245],
        [ 0.0027, -0.8911, -0.7410,  1.0522, -0.8816, -2.5483]])

如果 tensor 里只有一个数字,item 方法可以把里面的 value 变成 Python 数值

x = torch.randn(1)
print(x)
print(x.item())
tensor([-0.4755])
-0.47550874948501587

修改矩阵的形状,转置,交换维度等操作

x = torch.arange(12).view(2, 3, 2)
print(x)
print(x.transpose(1, 0))
print(x.permute(1, 0, 2))
tensor([[[ 0,  1],
         [ 2,  3],
         [ 4,  5]],

        [[ 6,  7],
         [ 8,  9],
         [10, 11]]])
tensor([[[ 0,  1],
         [ 6,  7]],

        [[ 2,  3],
         [ 8,  9]],

        [[ 4,  5],
         [10, 11]]])
tensor([[[ 0,  1],
         [ 6,  7]],

        [[ 2,  3],
         [ 8,  9]],

        [[ 4,  5],
         [10, 11]]])

压扁给定的维度为 1 的维度值

x = torch.arange(6).view(1, -1)
print(x.shape)
print(x)
a1 = x.squeeze(0)
print(a1.shape)
print(a1)
a2 = a1.unsqueeze(0)
print(a2)
torch.Size([1, 6])
tensor([[0, 1, 2, 3, 4, 5]])
torch.Size([6])
tensor([0, 1, 2, 3, 4, 5])
tensor([[0, 1, 2, 3, 4, 5]])

定义一个 flatten 函数,将输入数据扁平化

def flatten(t):
    t = t.view(1, -1)
    t = t.squeeze()
    return t

x1 = torch.tensor([1, 2, 3, 4, 5, 6], dtype=torch.float32).reshape(2, 3)
print(x1)
print(flatten(x1))
tensor([[1., 2., 3.],
        [4., 5., 6.]])
tensor([1., 2., 3., 4., 5., 6.])

3.2 拼接

将多个张量合并拼接成一个向量

t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])

x1 = torch.cat((t1, t2), dim=0)
print(x1)
x2 = torch.cat((t1, t2), dim=1)
print(x2)
tensor([[1, 2],
        [3, 4],
        [5, 6],
        [7, 8]])
tensor([[1, 2, 5, 6],
        [3, 4, 7, 8]])

4 CUDA 技术

Tensor 可以放在 CUDA 显卡上进行计算

x = torch.randn(2, 3)
if torch.cuda.is_available():
    device = torch.device("cuda:0")  # a CUDA device object
    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU
    x = x.to(device)  # or just use strings ``.to("cuda")``
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))  # ``.to`` can also change dtype together!
else:
    print("gpu is not available")
gpu is not available

5 定义模型

PyTorch 构造模型时主要包含两个步骤:

  1. 继承 nn.Module
  2. 实现 forward() 方法
import torch
import torch.nn as nn


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

    def forward(self, in_data):
        out_data = in_data
        return out_data

5.1 实验代码

完整的定义网络模型的代码参考如下代码

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

import torchvision
import torchvision.transforms as transforms

torch.set_printoptions(linewidth=200)

class Network(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
    self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)

    self.fc1 = nn.Linear(in_features=12 * 4 * 4, out_features=120)
    self.fc2 = nn.Linear(in_features=120, out_features=60)
    self.out = nn.Linear(in_features=60, out_features=10)

  def forward(self, t):
    t = F.relu(self.conv1(t))
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    t = F.relu(self.conv2(t))
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    t = F.relu(self.fc1(t.view(-1, 12 * 4 * 4)))
    t = F.relu(self.fc2(t))
    t = self.out(t)

    return t


train_set = torchvision.datasets.FashionMNIST(
  root='./data',
  train=True,
  download=True,
  transform=transforms.Compose([transforms.ToTensor()])
)


network = Network()
sample = next(iter(train_set))
image, label = sample

image.unsqueeze(0).shape
pred = network(image.unsqueeze(0))
print(pred)
print(pred.argmax(dim=1))
tensor([[ 0.0885,  0.1149,  0.0712,  0.0994, -0.0972,  0.0525, -0.0515,  0.0867,  0.1027,  0.0180]], grad_fn=<AddmmBackward>)
tensor([1])

6 附录

安装 PyTorch 之前最好是配合 Anaconda3 发行版一起安装,安装好 Anaconda 过后直接 使用下面命令安装

conda install pytorch torchvision -c pytorch

也可以使用 pip 安装对应的 wheel 包

pip3 install torch torchvision

7 参考链接

Last Updated 2020-11-01 Sun 10:50. Created by Jinghui Hu at 2020-10-12 Mon 10:48.