PyTorch - одна из самых известных фреймворков глубокого обучения. Я лично предпочитаю PyTorch из-за его питонической природы. Очень легко рассматривать каждую строку кода как функцию с четким вводом и выводом.

В этом посте я расскажу о следующих основных структурах и операциях, которые играют ключевую роль при глубоком обучении с использованием PyTorch.

  1. Матрицы или тензоры
  2. Тензорные операции
  3. Переменные и градиенты

Матрицы или тензоры

Матрицы формально определяются как «прямоугольный массив чисел». В библиотеке numpy они называются «ndarrays», тогда как в PyTorch они называются «тенорами».

Тензор, показанный на рисунке выше, представляет собой 2D-тензор с 3 строками и 2 столбцами. Давайте посмотрим, как мы можем создавать тензоры в PyTorch.

import numpy as np
import torch

# 1) Create a PyTorch Tensor an array

arr = [[3, 4], [8, 5]] # python array
pyt_tensor = torch.Tensor(arr) # PyTorch tensor

# 2) Create a tensor

ones_tensor = torch.ones((2, 2)) # tensor containing all ones
torch.manual_seed(0)             # to have same values for random generation
rand_tensor = torch.rand((2, 2)) # tensor containing random values

# if running on GPU, set random seed value as follows
if torch.cuda.is_available():
    torch.cuda.manual_seed_all(0)

# 3) Create a tensor from numpy array (dtype must be either double, float, int64, int32, or uint8)

np_arr = np.ones((2, 2))
pyt_tensor = torch.from_numpy(np_arr)
np_arr_from_tensor = pyt_tensor.numpy() # convert tensor to numpy array

Тензорные операции

Все операции, применимые к массивам, также могут применяться к тензорам. Вот как это делается в PyTorch.

import numpy as np
import torch

# 1) Resizing a tensor

pyt_tensor = torch.ones((2, 2))
print(pyt_tensor.size())        # shows the size of this tensor
pyt_tensor = pyt_tensor.view(4) # resizing 2x2 tensor to 4x1

# 2) Mathematical Operations

pyt_tensor_a = torch.ones((2, 2))
pyt_tensor_b = torch.ones((2, 2))
res_tensor = pyt_tensor_a + pyt_tensor_b               # simple element wise addidtion
res_tensor = torch.add(pyt_tensor_a, pyt_tensor_b)     # another way of addidtion
pyt_tensor_a.add_(pyt_tensor_b)                         # In-place addition

# Operation     operator    function_name
#  => Addition        +           add
#  => Subtraction     -           sub
#  => Multiplication  *           mul
#  => Divide          /           div

# 3) Mean and Standart deviation

pyt_tensor = torch.Tensor([1, 2, 3, 4, 5])
mean = pyt_tensor.mean(dim=0)                        # if multiple rows then dim = 1
std_dev = pyt_tensor.std(dim=0)                        # if multiple rows then dim = 1

Переменные и градиенты

Вычисление градиента - одна из ключевых вещей в глубоком обучении. В PyTorch переменные используются для расчета градиентов. Переменные, по сути, являются лишь оболочкой вокруг тензоров с функцией вычисления градиента.

Ниже приведен код Python, используемый для управления переменными.

import numpy as np
import torch
from torch.autograd import Variable

pyt_var = Variable(torch.ones((2, 2)), requires_grad = True)

# behaves exactly the same as tensors, so we can apply all operations in the same way

Теперь мы посмотрим, как мы можем использовать переменные в PyTorch для расчета градиентов.

import numpy as np
import torch
from torch.autograd import Variable

# let's consider the following equation
# y = 5(x + 1)^2

x = Variable(torch.ones(1), requires_grad = True)
y = 5 * (x + 1) ** 2        # implementing the equation.
y.backward()                # calculate gradient
print(x.grad)               # get the gradient of variable x
# differentiating the above mentioned equation
# => 5(x + 1)^2 = 10(x + 1) = 10(2) = 20

Вещи, упомянутые в этом посте, очень просты и понятны, но также очень важны. Знание фреймворка сильно возрастает, если основы усваиваются правильно. Я сам считаю полезным время от времени повторять эти основы, чтобы избежать ненужных задержек во время фактического написания кода.