Быстрый старт Pytorch (1) — установка, тензоры и градиенты

глубокое обучение PyTorch

Оригинальная ссылка:Tickets.WeChat.QQ.com/Yes/WZ dBm2JQ4…

Это перевод из официального вводного учебника, адрес учебника выглядит следующим образом:

DEEP LEARNING WITH PYTORCH: A 60 MINUTE BLITZ

Хотя название учебника 60-минутное введение, в нем все еще много контента.Хотя многие статьи, содержащие почти 10 000 слов, неоднократно обновлялись ранее, на этот раз он разделен примерно на 4 статьи для введения.Это первый статья.Каталог выглядит следующим образом:


1. Что такое Питорч

Pytorch — это библиотека научных вычислений на основе Python, предназначенная для двух групп людей:

  • Ищете замену Numpy, чтобы использовать мощь графических процессоров;
  • Исследовательская платформа глубокого обучения, которая может обеспечить большую гибкость и скорость.

1.1 Установка

При установке pytorch можно напрямую просмотреть учебник на официальном веб-сайте, как показано ниже, адрес официального веб-сайта:py torch.org/individual-started…

В соответствии с подсказками выберите систему (Linux, Mac или Windows), метод установки (Conda, Pip, LibTorch или установка из исходного кода), используемый язык программирования (Python 2.7 или Python 3.5, 3.6, 3.7 или C++), если это Версия графического процессора. Вам нужно выбрать версию CUDA, поэтому, если вы выберете, как показано выше, команда установки:

conda install pytorch torchvision cudatoolkit=9.0 -c pytorch 

Здесь рекомендуется установка Conda, даже если Anaconda используется, в основном можно настроить разные параметры для разных сред.Для Anaconda вы можете проверить, что я писал ранее.Начало работы с основами Python — введение и настройка среды.

Конечно, здесь будет установлена ​​​​последняя версия Pytorch, версия 1.1, Если вы хотите установить предыдущую версию, вы можете щелкнуть следующий URL-адрес:

py torch.org/individual-started…

Как показано на рисунке ниже, установите версию 0.4.1 pytorch с разными версиями CUDA и без CUDA.

Тогда есть другие способы установки, вы можете нажать, чтобы просмотреть подробности.

После установки введите следующие команды:

from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)

Если вывод аналогичен следующему, установка прошла успешно:

tensor([[0.3380, 0.3845, 0.3217],
        [0.8337, 0.9050, 0.2650],
        [0.2979, 0.7141, 0.9069],
        [0.1449, 0.1132, 0.1375],
        [0.4675, 0.3947, 0.1426]])

Затем, чтобы убедиться, что он может правильно работать на графическом процессоре, введите следующий код, в этом кодеcuda.is_available()Он в основном используется для определения того, можно ли использовать текущую графическую карту GPU.Если он возвращает True, конечно, он может работать, иначе он не может.

import torch
torch.cuda.is_available()

1.2 Тензоры

Основная роль Pytorch заключается в том, что он может заменить библиотеку Numpy, поэтому сначала представьте тензоры, то есть тензоры, которые эквивалентны многомерным массивам Numpy (ndarrays). Разница между ними заключается в том, что тензоры могут применяться к графическим процессорам для ускорения вычислений.

Сначала импортируйте необходимые библиотеки, в основном torch

from __future__ import print_function
import torch
1.2.1 Заявления и определения

Первый — это метод объявления и определения тензоров, а именно:

  • torch.empty(): объявляет неинициализированную матрицу.
# 创建一个 5*3 的矩阵
x = torch.empty(5, 3)
print(x)

Результат выглядит следующим образом:

tensor([[9.2737e-41, 8.9074e-01, 1.9286e-37],
        [1.7228e-34, 5.7064e+01, 9.2737e-41],
        [2.2803e+02, 1.9288e-37, 1.7228e-34],
        [1.4609e+04, 9.2737e-41, 5.8375e+04],
        [1.9290e-37, 1.7228e-34, 3.7402e+06]])
  • torch.rand(): Произвольная инициализация матрицы
# 创建一个随机初始化的 5*3 矩阵
rand_x = torch.rand(5, 3)
print(rand_x)

Выходной результат:

tensor([[0.4311, 0.2798, 0.8444],
        [0.0829, 0.9029, 0.8463],
        [0.7139, 0.4225, 0.5623],
        [0.7642, 0.0329, 0.8816],
        [1.0000, 0.9830, 0.9256]])
  • torch.zeros(): Создать матрицу со всеми нулями
# 创建一个数值皆是 0,类型为 long 的矩阵
zero_x = torch.zeros(5, 3, dtype=torch.long)
print(zero_x)

Результат выглядит следующим образом:

tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])

Точно так же вы можете создать матрицу, все значения которой равны 1, вызовитеtorch.ones

  • torch.tensor(): напрямую передать значение тензора для создания
# tensor 数值是 [5.5, 3]
tensor1 = torch.tensor([5.5, 3])
print(tensor1)

Выходной результат:

tensor([5.5000, 3.0000])

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

  • tensor.new_ones(): методы new_*() требуют ввода размера
# 显示定义新的尺寸是 5*3,数值类型是 torch.double
tensor2 = tensor1.new_ones(5, 3, dtype=torch.double)  # new_* 方法需要输入 tensor 大小
print(tensor2)

Выходной результат:

tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)
  • torch.randn_like(old_tensor): сохранить тот же размер
# 修改数值类型
tensor3 = torch.randn_like(tensor2, dtype=torch.float)
print('tensor3: ', tensor3)

Результат вывода здесь объявляется по предыдущему методуtensor2variable для объявления новой переменной, видно, что размер 5*3, но изменился тип значения.

tensor3:  tensor([[-0.4491, -0.2634, -0.0040],
        [-0.1624,  0.4475, -0.8407],
        [-0.6539, -1.2772,  0.6060],
        [ 0.2304,  0.0879, -0.3876],
        [ 1.2900, -0.7475, -1.8212]])

Наконец, размер тензоров можно получить, используяtensor.size()метод:

print(tensor3.size())  
# 输出: torch.Size([5, 3])

Уведомление:torch.Sizeв действительностиТип кортежа, поэтому поддерживаются все операции с кортежами..

1.2.2 Операции

Операция также содержит много синтаксиса, но здесь в качестве быстрого старта в качестве примера представлена ​​только операция сложения.Чтобы узнать больше об операции, вы можете щелкнуть следующий URL-адрес, чтобы просмотреть официальные документы, включая транспонирование, индекс, срез, математический расчет, линейная алгебра, случайное число и так далее:

py torch.org/docs/stable…

Для операции сложения существует несколько реализаций:

  • +
  • torch.add(tensor1, tensor2, [out=tensor3])
  • tensor1.add_(tensor2): напрямую изменить тензорную переменную
tensor4 = torch.rand(5, 3)
print('tensor3 + tensor4= ', tensor3 + tensor4)
print('tensor3 + tensor4= ', torch.add(tensor3, tensor4))
# 新声明一个 tensor 变量保存加法操作的结果
result = torch.empty(5, 3)
torch.add(tensor3, tensor4, out=result)
print('add result= ', result)
# 直接修改变量
tensor3.add_(tensor4)
print('tensor3= ', tensor3)

выходной результат

tensor3 + tensor4=  tensor([[ 0.1000,  0.1325,  0.0461],
        [ 0.4731,  0.4523, -0.7517],
        [ 0.2995, -0.9576,  1.4906],
        [ 1.0461,  0.7557, -0.0187],
        [ 2.2446, -0.3473, -1.0873]])

tensor3 + tensor4=  tensor([[ 0.1000,  0.1325,  0.0461],
        [ 0.4731,  0.4523, -0.7517],
        [ 0.2995, -0.9576,  1.4906],
        [ 1.0461,  0.7557, -0.0187],
        [ 2.2446, -0.3473, -1.0873]])

add result=  tensor([[ 0.1000,  0.1325,  0.0461],
        [ 0.4731,  0.4523, -0.7517],
        [ 0.2995, -0.9576,  1.4906],
        [ 1.0461,  0.7557, -0.0187],
        [ 2.2446, -0.3473, -1.0873]])

tensor3=  tensor([[ 0.1000,  0.1325,  0.0461],
        [ 0.4731,  0.4523, -0.7517],
        [ 0.2995, -0.9576,  1.4906],
        [ 1.0461,  0.7557, -0.0187],
        [ 2.2446, -0.3473, -1.0873]])

Уведомление: Операции, которые могут изменять тензорные переменные, имеют суффикс_, Напримерx.copy_(y), x.t_()можно изменить переменную x

В дополнение к операции сложения доступ к Tensor аналогичен доступу к Numpy для массивов.Индексы могут использоваться для доступа к данным определенного измерения, как показано ниже:

# 访问 tensor3 第一列数据
print(tensor3[:, 0])

Выходной результат:

tensor([0.1000, 0.4731, 0.2995, 1.0461, 2.2446])

Чтобы изменить размер Tensor, вы можете использоватьtorch.view(),Следующее:

x = torch.randn(4, 4)
y = x.view(16)
# -1 表示除给定维度外的其余维度的乘积
z = x.view(-1, 8)
print(x.size(), y.size(), z.size())

Выходной результат:

torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

Если тензор имеет только один элемент, вы можете использовать.item()чтобы получить числовое значение, подобное целочисленному типу в Python:

x = torch.randn(1)
print(x)
print(x.item())

Выходной результат:

tensor([0.4549])
0.4549027979373932

Для получения дополнительных сведений об операциях вы можете просмотреть введение в официальную документацию:

py torch.org/docs/stable…

1.3 Преобразование с массивами Numpy

Массивы Tensor и Numpy могут быть преобразованы друг в друга, и после преобразования они делят пространство памяти под ЦП, то есть, если значение одного изменяется, другая переменная также будет изменена.

1.3.1 Преобразование тензоров в массивы Numpy

Пример преобразования массива Tensor в Numpy показан ниже, вызываяtensor.numpy()Эта операция преобразования может быть реализована.

a = torch.ones(5)
print(a)
b = a.numpy()
print(b)

Выходной результат:

tensor([1., 1., 1., 1., 1.])
[1. 1. 1. 1. 1.]

Кроме того, я только что сказал, что они используют одно и то же пространство памяти.Пример выглядит следующим образом: изменитеtensorПеременнаяa, см. отaПреобразованная переменная массива Numpybизменения.

a.add_(1)
print(a)
print(b)

Вывод, очевидно, следующий:bвместе сaменяется с изменением.

tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
1.3.2 Преобразование массивов Numpy в тензоры

Операция преобразования заключается в вызовеtorch.from_numpy(numpy_array)метод. Примеры следующие:

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)

Выходной результат:

[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)

существуетCPUна, кромеCharTensorВсе кромеTensorпеременные типа, как поддерживающие, так иNumpyОперации преобразования массива.

1.4 Тензоры CUDA

Tensorsв состоянии пройти.toМетод преобразуется в другое устройство, т. е. ЦП или ГП. Примеры следующие:

# 当 CUDA 可用的时候,可用运行下方这段代码,采用 torch.device() 方法来改变 tensors 是否在 GPU 上进行计算操作
if torch.cuda.is_available():
    device = torch.device("cuda")          # 定义一个 CUDA 设备对象
    y = torch.ones_like(x, device=device)  # 显示创建在 GPU 上的一个 tensor
    x = x.to(device)                       # 也可以采用 .to("cuda") 
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # .to() 方法也可以改变数值类型

Выведите результат, первый результат — это результат на графическом процессоре, а переменная будет напечатана сdevice='cuda:0', а вторая — это переменная на процессоре.

tensor([1.4549], device='cuda:0')

tensor([1.4549], dtype=torch.float64)

Учебник в этом разделе:

py torch.org/tutorials/ нет…

Код для этого подраздела:

GitHub.com/CCC013/глубокий…

2. autograd

Для нейронной сети Pytorch очень важной библиотекой являетсяautograd, которая в основном обеспечивает автоматическую дифференциацию всех операций над Тензорами, то есть функцию вычисления градиентов. это принадлежитdefine-by-runКадр типа, то есть определение операции обратного распространения, основан на том, как выполняется код, поэтому каждая итерация может быть разной.

Ниже кратко представлены некоторые примеры, иллюстрирующие роль этой библиотеки.

2.1 Тензоры

torch.Tensorявляется основной библиотекой для Pytorch, при настройке ее свойств.requires_grad=True, то он начнет отслеживать все операции над переменной, а после завершения расчета можно будет вызвать.backward()И автоматически рассчитать все градиенты, полученные градиенты сохраняются в атрибуте.gradсередина.

перечислить.detach()Этот метод изолирует историю вычислений, что может помешать тензорной переменной продолжать отслеживать свою историю, а также предотвратить отслеживание будущих вычислений.

И если вы хотите предотвратить отслеживание истории (и использование памяти), вы можете поместить блок кода вwith torch.no_grad():, это очень полезно при использовании модели для оценки, поскольку модель будет содержать некоторыеrequires_grad=True, но на самом деле им не нужна информация о градиенте.

заautogradРеализация, там класс тоже очень важна -Function.

TensorиFunctionЭти два класса связаны и строят ациклический граф, который кодирует полную запись вычислений. Каждая тензорная переменная имеет свойства.grad_fn, который ссылается на свойство, которое создало переменнуюFunction(За исключением созданных пользователем тензоров, чьиgrad_fn=None).

Если вы хотите выполнить производную операцию, вы можете вызватьTensorпеременный метод.backward(). Если переменная является скалярной, т.е. имеет только один элемент, то в метод не нужно передавать аргументы.backward(), если он содержит несколько элементов, необходимо указатьgradientПараметр, указывающий тензор соответствующего размера, эта часть описана во втором разделе для содержимого градиента.

Далее, давайте начнем с кода для дальнейшего введения.

Сначала импортируйте необходимые библиотеки:

import torch

Начните создавать тензор и дайтеrequires_grad=Trueдля отслеживания вычислительных операций, связанных с этой переменной:

x = torch.ones(2, 2, requires_grad=True)
print(x)

Выходной результат:

tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

Выполните произвольные вычислительные операции, вот простая операция сложения:

y = x + 2
print(y)

Выходной результат:

tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward>)

yявляется результатом операции, поэтому он имеет свойстваgrad_fn:

print(y.grad_fn)

Выходной результат:

<AddBackward object at 0x00000216D25DCC88>

продолжать изменятьyСделай это:

z = y * y * 3
out = z.mean()

print('z=', z)
print('out=', out)

Выходной результат:

z= tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward>)

out= tensor(27., grad_fn=<MeanBackward1>)

Фактически,Tensorпеременная по умолчаниюrequires_gradдаFalse, вы можете указать атрибут при определении переменной, как указано выше.True, конечно, вы также можете определить переменные после вызова.requires_grad_(True)Установить какTrue, здесь с суффиксом_Это изменит свойства самой переменной.Операция сложения была введена в предыдущем разделе.add_()Тем не менее, вот пример кода:

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)

Вывод выглядит следующим образом, первая строка предназначена для настройкиrequires_grad, затем отобразите вызов.requires_grad_(True), выходTrue.

False

True

<SumBackward0 object at 0x00000216D25ED710>

2.2 Градиент

Следующий шаг — начать вычисление градиента и выполнить операцию обратного распространения ошибки.outПеременная определена в предыдущем подразделе, это скаляр, поэтомуout.backward()эквивалентноout.backward(torch.tensor(1.)), код показан ниже:

out.backward()
# 输出梯度 d(out)/dx
print(x.grad)

Выходной результат:

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

В результате должна получиться матрица со значениями всего 4,5. Здесь мы используемoвыражатьoutпеременной, то согласно предыдущему определению будет:

o = \frac{1}{4}\sum_iz_i,\\ z_i = 3(x_i + 2)^2, \\ z_i|_{x_i=1} = 27

В частности, первоначально определенныеxявляется матрицей всех единиц, то операция сложенияx+2получитьy,тогдаy*y*3, получитьz, а в это времяzпредставляет собой матрицу 2 * 2, поэтому общее среднее значение равноoutПеременная должна быть разделена на 4, так что вы получите три приведенные выше формулы.

Следовательно, вычисление градиента:

\frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2),\\ \frac{\partial o}{\partial x_i}|_{x_i=1} = \frac{9}{2} = 4.5

С математической точки зрения, если у вас есть функция с векторным знаком:

\vec{y}=f(\vec{x})

Тогда соответствующий градиент является матрицей Якоби:

\begin{split}J=\left(\begin{array}{ccc}  \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{1}}{\partial x_{n}}\\  \vdots & \ddots & \vdots\\  \frac{\partial y_{m}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}}  \end{array}\right)\end{split}

Вообще говоря,torch.autogradЭто инструмент, используемый для вычисления произведения вектора Якобиана (вектор-якобиан). Математическая формула здесь опущена, а непосредственно представлен пример кода:

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

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

Выходной результат:

tensor([ 237.5009, 1774.2396,  274.0625], grad_fn=<MulBackward>)

переменная здесьyбольше не является скаляром,torch.autogradПолный якобиан нельзя вычислить напрямую, но мы можем просто передать вектор вbackward()В качестве аргумента метод принимает произведение векторов Якоби, пример такой:

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)

Выходной результат:

tensor([ 102.4000, 1024.0000,    0.1024])

Наконец, добавьтеwith torch.no_grad()Вы можете остановить отслеживание истории переменных для автоматического расчета градиента:

print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)

Выходной результат:

True

True

False

больше оautogradиFunctionВступление к:

py torch.org/docs/auto персональный…

Учебник в этом разделе:

py torch.org/tutorials/ нет…

Код для этого подраздела:

GitHub.com/CCC013/глубокий…


резюме

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

Кроме того, также представлены самые важные и базовые знания о тензорах. Его методы и операции очень похожи на массивы Numpy, и их также можно преобразовать друг в друга. Небольшое отличие состоит в том, что тензоры могут применяться к графическим процессорам для ускорения вычисление.

Наконец, краткое введениеautogradЭта библиотека, очень важная для глубокого обучения, может автоматически рассчитывать градиенты, что очень полезно.

Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись WeChat — машинное обучение и компьютерное зрение, или отсканируйте QR-код ниже, давайте общаться, учиться и прогрессировать вместе!

Прекрасная рекомендация в прошлом

Серия машинного обучения
Рекомендация руководства по проектам и ресурсам Github