Несреднюю статью можно найти на blog.datasloth.io.
Во-первых, это не учебник по машинному обучению,
это учебник по pytorch, поэтому вы можете манипулировать его
структурами данных и в полной мере использовать возможности JIT
скомпилированного графического процессора pytorch в любой ваш числовой код!
Недавно я начал писать книгу
[Создай свой собственный Shazzam!](https://leanpub.com/build-your-own-shazzam-python)
В приложении I будет предоставлять некоторые указатели для использования pytorch и numpy.
Вот пример учебника Pytorch.
Основы Pytorch
Почему бы просто не использовать списки Python для вычислений
вместо того, чтобы перенести все это в библиотеку?
Списки Python очень общие.
Они могут содержать объекты любого типа.
Они динамически типизированы.
Они не поддерживают математические функции, такие как матричное
умножение точек и т. д.
Тензоры Pytorch статически типизированы и однородны, они
также могут использовать высокую пропускную способность графических процессоров.
Тип элементов определяется при создании массива.
Тензоры Pytorch эффективно используют память и имеют общее двоичное
представление, позволяющее без затрат использовать уже существующие данные numpy
.
Из-за статической типизации быстрая реализация
математических такие функции, как умножение и сложение
тензоров Pytorch, могут быть реализованы на скомпилированном
языке (используются C и Fortran, а также некоторые специфические функции на основе графического процессора
, что позволяет нам использовать все, от
CUDA, OpenCL и SYCL).
Оптимизация размещения памяти также позволяет выполнять числовые
вычисления параллельно данным (SIMD и т. д.)
Теперь давайте оценим простоту разработка при прохождении
Pytorch Primer.
[Примечание!]: в некоторых ссылках на документацию предоставляется версия numpy, учитывая, что она
значительно лучше объясняет удобство использования некоторых функций.
Начните с установки и импорта библиотеки pytorch.
Установка
# CUDA 10.0 install pip install torch==1.2.0 torchvision==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html # CUDA 9.2 pip install torch==1.2.0+cu92 torchvision==0.4.0+cu92 -f https://download.pytorch.org/whl/torch_stable.html # CPU only install pip install torch==1.2.0+cpu torchvision==0.4.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
Инициализация
import torch
Создание тензора
Создайте неинициализированный тензор
>>> a = torch.empty(2, 4) [Out]: tensor([[ 0.0000e+00, 2.0000e+00, -1.8032e-07, 4.6577e-10], [ 8.4078e-45, 1.1210e-44, 4.2039e-45, 0.0000e+00]])
Или нулевой инициализированный тензор
>>> a = torch.empty(5, 6) [Out]: tensor([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]])
Создание тензора: аргументом функции массива является список Python
>>> a = torch.empty(5, 6) [Out]: tensor([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]])
Создание тензора: аргументом функции массива является список Python
>>> v = torch.Tensor([1.1, 2, 3, 4]) [Out]: tensor([1.1000, 2.0000, 3.0000, 4.0000])
Создание многомерного тензора (матрицы):
аргументом функции массива является вложенный список Python.
>>> M = torch.Tensor([[1, 2], [3, 4]]) [Out]: tensor([[1., 2.], [3., 4.]])
Объекты v и M относятся к типу torch.Tensor, который предоставляет модуль pytorch.
Мы можем проверить это так же, как и любой другой объект Python.
>>> type(v), type(M) [Out]: (torch.Tensor, torch.Tensor)
Разница между массивами v и M заключается только в их форме.
Мы можем получить информацию о форме массива, используя
свойство Tensor.shape.
>>> print( f”v: {v.shape} ; M: {M.shape}”) [Out]: v: torch.Size([4]) ; M: torch.Size([2, 2])
Количество элементов в массиве доступно через
метод Tensor.size:
>> print( f”v: {v.size()} ; M: {M.size()}”) [Out]: v: torch.Size([4]) ; M: torch.Size([2, 2])
Используя свойство dtype (тип данных) тензора,
мы можем увидеть, какой тип имеют данные тензора:
>>> print( f”v: {v.dtype} ; M: {M.dtype}”) [Out]: v: torch.float32 ; M: torch.float32
Используя метод elemetn_size тензора, мы можем увидеть байты на элемент тензора:
>>> print( f”v: {v.element_size()} ; M: {M.element_size()}”) [Out]: v: 4 ; M: 4
Используя метод element_size тензора и метод flatten
, мы можем увидеть количество байтов в тензоре:
>>> print(f”v: {v.element_size() * v.flatten().shape[0]};\ M: {M.element_size() * M.flatten().shape[0]}”) [Out]: v: 16 ; M: 16
Вы также можете проверить структуру памяти
В настоящее время поддерживается torch.strided (плотные тензоры)
и есть экспериментальная поддержка torch.sparse_coo (разреженные тензоры COO).
>>> print(f”v: {v.layout} M: {M.layout}”) [Out]: v: torch.strided M: torch.strided
Используя свойство ndim тензора,
мы можем увидеть количество измерений данного тензора:
>>> print( f”v: {v.ndim} ; M: {M.ndim}”) [Out]: v: 1 ; M: 2
Поскольку тензоры Pytorch строго типизированы
, мы получим ошибку, если попытаемся присвоить значение неправильного типа
элементу в тензоре Pytorch:
>>> M[0,0] = “hello” [Out]: TypeError: cant assign a str to a torch.FloatTensor
Мы можем явно определить тип тензора
с помощью аргумента ключевого слова dtype:
[ПРИМЕЧАНИЕ!]: в отличие от numpy квантованные и сложные типы еще не поддерживаются в pytorch
>>> float_tensor = torch.ones(11, dtype=torch.float) [Out]: tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
Мы также можем создавать тензоры, используя функции, генерирующие тензоры.
Создайте тензор на основе диапазона
>>> x = torch.arange(0, 10, 1) # arguments: start, stop, step [Out]: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Создайте тензор на основе диапазона значений с плавающей запятой
>>> x = torch.arange(-1, 1, 0.1) [Out]: tensor([-1.0000, -0.9000, -0.8000, -0.7000, -0.6000, -0.5000, -0.4000, -0.3000, -0.2000, -0.1000, 0.0000, 0.1000, 0.2000, 0.3000, 0.4000, 0.5000, 0.6000, 0.7000, 0.8000, 0.9000])
Используя [linspace](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html),
включены обе конечные точки
>>> torch.linspace(0, 10, 25) [Out]: tensor([ 0.0000, 0.4167, 0.8333, 1.2500, 1.6667, 2.0833, 2.5000, 2.9167, 3.3333, 3.7500, 4.1667, 4.5833, 5.0000, 5.4167, 5.8333, 6.2500, 6.6667, 7.0833, 7.5000, 7.9167, 8.3333, 8.7500, 9.1667, 9.5833, 10.0000])
Использование [logspace](https://docs.scipy.org/doc/numpy/reference/generated/numpy.logspace.html)
>>> torch.logspace(0, 10, 10, base=np.e) [Out]: tensor([1.0000e+00, 3.0377e+00, 9.2278e+00, 2.8032e+01, 8.5153e+01, 2.5867e+02, 7.8577e+02, 2.3870e+03, 7.2510e+03, 2.2026e+04])
Использование [meshgrid](https://docs.scipy.org/doc/numpy/reference/generated/numpy.meshgrid.html)
>>> x, y = torch.meshgrid([torch.arange(0,5), torch.arange(0,5)]) # similar to meshgrid in MATLAB >>> x [Out]: tensor([[0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]) >>> y [Out]: tensor([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])
Создавайте тензоры с хорошей поддержкой случайных чисел
Равномерные случайные числа в [0,1]
>>> torch.rand(5,5) [Out]: tensor([[0.8045, 0.6434, 0.6919, 0.1928, 0.1206], [0.6650, 0.9219, 0.7604, 0.3623, 0.7129], [0.2362, 0.8861, 0.2842, 0.6565, 0.4014], [0.8429, 0.3326, 0.2073, 0.2165, 0.7568], [0.4814, 0.4796, 0.5633, 0.3096, 0.7262]])
Стандартные нормально распределенные случайные числа
>>> torch.randn(5,5) [Out]: tensor([[ 0.7389, -0.0692, -0.4417, 0.2532, -0.6249], [-0.7023, 0.2570, 0.1416, -1.7092, -1.1454], [-0.5858, -1.7136, -2.0907, 0.0318, -1.0332], [ 0.6930, 0.9322, 1.3171, -0.4396, 1.9546], [ 0.1334, -1.5349, 0.7378, -0.5799, -0.8226]])
Диагональная матрица
>>> torch.diag(torch.arange(1,5)) [Out]: tensor([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]])
Диагональ со смещением от главной диагонали
>>> torch.diag(torch.arange(1,5),1) [Out]: tensor([[0, 1, 0, 0, 0], [0, 0, 2, 0, 0], [0, 0, 0, 3, 0], [0, 0, 0, 0, 4], [0, 0, 0, 0, 0]])
Создайте тензоры с нулями
>>> torch.zeros((3,3)) [Out]: tensor([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
Создавайте тензоры с единицами
>>> torch.ones((3,3)) [Out]: tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
Упорство
Сохраните тензор в файл
>>> torch.save(M, ‘tst.csv’)
Загрузить тензоры
учитывая гетерогенную вычислительную природу pytorch
, мы можем загружать их по-разному
Загрузите все тензоры в ЦП
>>> torch.load(‘tst.csv’) [Out]: tensor([[1., 2.], [3., 4.]])
Загрузите все тензоры в ЦП, используя функцию
>>> torch.load(‘tst.csv’, map_location=torch.device(‘cpu’)) [Out]: tensor([[1., 2.], [3., 4.]])
Проверьте, доступна ли cuda
>>> torch.cuda.is_available() [Out]: True/False
Загрузите тензор на GPU cuda, иначе cpu
if torch.cuda.is_available() map_location=lambda storage, loc: storage.cuda() else: map_location=’cpu’
Загрузите все тензоры в GPU 1
>>> torch.load(‘tst.csv’, map_location=lambda storage, loc: storage) [Out]: tensor([[1., 2.], [3., 4.]])
Сопоставьте тензоры от GPU 1 до GPU 0
>>> torch.load(‘tst.csv’, map_location={‘cuda:1’:’cuda:0'}) [Out]: tensor([[1., 2.], [3., 4.]])
сохранить в объект BytesIO
>>> import io >>> buffer = io.BytesIO() >>> torch.save(M, buffer) >>> buffer.seek(0) [Out]: <_io.BytesIO at 0x11ea80cb0>
Загрузить тензоры из объекта BytesIO