{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Введение в Pytorch\n", "\n", "Александр Дьяконов, 2020\n", "\n", "#### использованные материалы\n", "\n", "* https://github.com/MLWhiz/data_science_blogs/blob/master/pytorch_guide/Pytorch%20Guide.ipynb\n", "* https://d2l.ai/\n", "* https://atcold.github.io/pytorch-Deep-Learning/\n", "* семинары OzonMasters\n", "* https://habr.com/ru/post/334380/\n", "\n", "### Фишки Pytorch:\n", "\n", "* очень похож на numpy, но многие вещи строже\n", "* динамический граф вычислений (создаётся при работе)\n", "* можно вычислять на GPU (минимальные изменения кода)\n", "* хорошо поддерживается, есть полезные модули (например, torchvision)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# from __future__ import print_function\n", "import torch\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# служебная функция\n", "\n", "from matplotlib import pyplot as plt\n", "\n", "def plot_data(X, y, d=0, auto=False, zoom=1):\n", " X = X.cpu()\n", " y = y.cpu()\n", " plt.scatter(X.numpy()[:, 0], X.numpy()[:, 1], c=y, s=20, cmap=plt.cm.Spectral)\n", " plt.axis('square')\n", " plt.axis(np.array((-1.1, 1.1, -1.1, 1.1)) * zoom)\n", " if auto is True: plt.axis('equal')\n", " plt.axis('off')\n", "\n", " _m, _c = 0, '.15'\n", " plt.axvline(0, ymin=_m, color=_c, lw=1, zorder=0)\n", " plt.axhline(0, xmin=_m, color=_c, lw=1, zorder=0)\n", "\n", "def plot_model(X, y, model):\n", " model.cpu()\n", " mesh = np.arange(-1.1, 1.1, 0.01)\n", " xx, yy = np.meshgrid(mesh, mesh)\n", " with torch.no_grad():\n", " data = torch.from_numpy(np.vstack((xx.reshape(-1), yy.reshape(-1))).T).float()\n", " Z = model(data).detach()\n", " Z = np.argmax(Z, axis=1).reshape(xx.shape)\n", " plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.3)\n", " plot_data(X, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Помощь, общие моменты" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# основная помощь\n", "torch.nn.Module?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# + код функции\n", "torch.nn.Module??" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.7.3\n", "1.5.0\n" ] } ], "source": [ "# Проверка версии\n", "from platform import python_version\n", "print(python_version())\n", "print(torch.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Тензоры\n", "* тензоры\n", "* доступ к элементам, слайсинг\n", "* реализация inplace-операций\n", "* связь с numpy\n", "* параметры тензора\n", "* выцепление элементов (item)" ] }, { "cell_type": "code", "execution_count": 206, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[0., 0., 0.],\n", " [0., 0., 0.]]) 1685962910464\n" ] } ], "source": [ "x = torch.FloatTensor(2, 3)\n", "print (x, x.data_ptr()) # + где лежит в памяти" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[1.0194e-38, 8.4490e-39, 1.0469e-38, 9.3674e-39, 9.9184e-39],\n", " [8.7245e-39, 9.2755e-39, 8.9082e-39, 9.9184e-39, 8.4490e-39],\n", " [9.6429e-39, 1.0653e-38, 1.0469e-38, 4.2246e-39, 1.0378e-38]])\n" ] } ], "source": [ "# пустая матрица (тензор)\n", "x = torch.empty(3, 5)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1.0194e-38, 8.4490e-39],\n", " [8.7245e-39, 9.2755e-39],\n", " [9.6429e-39, 1.0653e-38]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,:2]" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[8.4490e-39],\n", " [9.2755e-39],\n", " [1.0653e-38]]),\n", " tensor([8.4490e-39, 9.2755e-39, 1.0653e-38]))" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,[1]], x[:, 1]" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[0.2961, 0.5166, 0.2517, 0.6886, 0.0740],\n", " [0.8665, 0.1366, 0.1025, 0.1841, 0.7264],\n", " [0.3153, 0.6871, 0.0756, 0.1966, 0.3164]])\n" ] } ], "source": [ "# случайная матрица\n", "torch.manual_seed(123)\n", "x = torch.rand(3, 5)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[3., 3., 3., 3., 3.],\n", " [3., 3., 3., 3., 3.],\n", " [3., 3., 3., 3., 3.]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# заполнение\n", "x.fill_(3) # черта - признак выполнения на данном тензоре" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0., 0., 0., 0., 0.],\n", " [0., 0., 0., 0., 0.],\n", " [0., 0., 0., 0., 0.]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# обнуление\n", "x.zero_()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([1, 2, 3, 4])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.arange(1, 5)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[1, 2],\n", " [3, 4]]) torch.LongTensor 2 torch.Size([2, 2]) 4\n" ] } ], "source": [ "# матрица из данных\n", "x = torch.tensor([[1, 2], [3, 4]])\n", "print(x, x.type(), x.dim(), x.size(), x.numel()) # тип тензора" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 1.],\n", " [1., 1.]], dtype=torch.float64)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# из numpy.array\n", "torch.from_numpy(np.ones((2, 2)))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[0.1479, 0.5331, 0.4066],\n", " [0.2318, 0.4545, 0.9737],\n", " [0.4606, 0.5159, 0.4220],\n", " [0.5786, 0.9455, 0.8057],\n", " [0.6775, 0.6087, 0.6179]])\n", "tensor(0.9737) 0.9737018942832947\n" ] } ], "source": [ "x = torch.rand(5, 3)\n", "print(x)\n", "print (x.max(), x.max().item()) # item - выцепляет элемент" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[1, 2],\n", " [3, 4]]) 1\n", " 2\n", " 3\n", " 4\n", "[torch.LongStorage of size 4] (2, 1) (1, 2)\n" ] } ], "source": [ "x = torch.tensor([[1, 2], [3, 4]])\n", "\n", "# как хранятся данные, где следующий элемент по каждой из разметностей\n", "print (x, x.storage(), x.stride(), x.t().stride()) " ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[10, 2],\n", " [ 3, 4]]) tensor([[1, 2],\n", " [3, 4]])\n", "tensor([[30, 3],\n", " [ 2, 4]]) tensor([[30, 3],\n", " [ 2, 4]])\n" ] } ], "source": [ "x = torch.tensor([[1, 2], [3, 4]])\n", "y = x.clone()\n", "# print (id(x.storage()) == id(y.storage()))\n", "x[0, 0] = 10\n", "print (x, y)\n", "xt = x.t_()\n", "x[0, 0] = 30\n", "print (x, xt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Тензоры - получение одних из других " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[ 1, 10],\n", " [ 3, 4]]),\n", " tensor([[1, 2],\n", " [3, 4]]))" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# клонирование\n", "x = torch.tensor([[1, 2], [3, 4]])\n", "x2 = x.clone() # в отличие от copy_() через оригинал проносят градиенты\n", "x[0, 1] = 10 \n", "x, x2" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[ 0.3123, 1.3540],\n", " [-0.3501, 1.6162]])\n" ] } ], "source": [ "# матрица такого же размера\n", "y = torch.randn_like(x, dtype=torch.float)\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[1, 2, 2, 2],\n", " [3, 4, 2, 2]]),\n", " tensor([[1, 2],\n", " [3, 4],\n", " [2, 2],\n", " [2, 2]]))" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# конкатенация по 0 и 1 размерностям\n", "x = torch.tensor([[1, 2], [3, 4]])\n", "y = torch.tensor([[2, 2], [2, 2]])\n", "torch.cat([x, y], axis=1), torch.cat([x, y], axis=0)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(torch.Size([1, 2, 2]), torch.Size([2, 1, 2]), torch.Size([2, 2, 1]))" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# создание фиктивной размерности - в какую позицию вставлять фиктивную\n", "x.unsqueeze(dim=0).shape, x.unsqueeze(dim=1).shape, x.unsqueeze(dim=2).shape" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[[1, 2],\n", " [2, 2]],\n", "\n", " [[3, 2],\n", " [4, 2]]])" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# конкатенация по 2-й размерности\n", "torch.cat([x.unsqueeze(dim=2), y.unsqueeze(dim=2)], axis=2)" ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([3, 2])" ] }, "execution_count": 141, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# удаляем единичные размеры\n", "torch.empty(3, 1, 2, 1).squeeze().shape" ] }, { "cell_type": "code", "execution_count": 160, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[ 9, 12],\n", " [15, 18]])\n", "tensor([[ 3, 8],\n", " [15, 24]])\n", "tensor([[ 9, 16],\n", " [25, 36]])\n" ] } ], "source": [ "x = torch.tensor([[1, 2], [3, 4]])\n", "print(3 * x.add(2)) # смотри на порядок операций\n", "print(x * x.add(2)) # смотри на порядок операций\n", "print(x * x.add_(2)) # смотри на порядок операций" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Операции над тензорами" ] }, { "cell_type": "code", "execution_count": 208, "metadata": {}, "outputs": [], "source": [ "x = torch.tensor([[1, 2], [3, 4]])\n", "y = torch.tensor([[2, 2], [2, 2]])\n", "v = torch.tensor([1, 2])" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[3, 4],\n", " [5, 6]])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# сложение\n", "x + y" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[3, 4],\n", " [5, 6]])" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.add(y)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[2, 4],\n", " [6, 8]])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x * y" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[ 6, 6],\n", " [14, 14]]),\n", " tensor([[ 6, 6],\n", " [14, 14]]))" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x @ y, x.mm(y)\n", "# скалярные произведения по строкам" ] }, { "cell_type": "code", "execution_count": 217, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor(5) tensor(5)\n" ] }, { "data": { "text/plain": [ "tensor(20)" ] }, "execution_count": 217, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print (torch.dot(v, v), v.dot(v)) # скалярное умножение\n", "torch.dot(x.view(-1), y.view(-1))" ] }, { "cell_type": "code", "execution_count": 211, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([ 5, 11]), tensor([ 5, 11]))" ] }, "execution_count": 211, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.mv(x, v), x.mv(v) # умножение на вектор" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[3, 4],\n", " [5, 6]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# inplace\n", "y.add_(x)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0.0000, 0.6931],\n", " [1.0986, 1.3863]], dtype=torch.float64)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.type(torch.DoubleTensor).log() # приводим тип - иначе не сработает log" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[ 1, 4],\n", " [ 9, 16]]),\n", " tensor([[ 1, 4],\n", " [ 9, 16]]))" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.pow(2), x**2" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1, 3],\n", " [2, 4]])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# транспонирование\n", "x.t()" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1, 3],\n", " [2, 4]])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# эквивалениное транспонирование\n", "x.transpose(0, 1)" ] }, { "cell_type": "code", "execution_count": 222, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([2., 1.])\n", "tensor([2., 1.])\n", "tensor([2., 1.])\n", "tensor([2., 1.])\n" ] } ], "source": [ "# как распределяется память\n", "# ПРОВЕРИТЬ В ПОСЛЕДНЕЙ ВЕРСИИ?????\n", "\n", "x = torch.Tensor([1, 2])\n", "y = torch.Tensor([1, 1])\n", "z = torch.Tensor([0, 2])\n", "\n", "print (x + y - z) # два промежуточных тензора будут созданы.\n", "print (x.add(y).sub_(z)) # один промежуточный тензор.\n", "print (x.add_(y).sub_(z)) # не будет создано промежуточных тензоров\n", "print(x) # поменяется" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## статистики над тензорами, размеры\n", "* ...\n", "* связь с Numpy\n", "* приведение размеров" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "x = torch.tensor([[1, 2], [3, 4]])\n", "y = torch.tensor([[2, 2], [2, 2]])" ] }, { "cell_type": "code", "execution_count": 218, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor(10), tensor(10), tensor([4, 6]), tensor([3, 7]))" ] }, "execution_count": 218, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.sum(x), x.sum(), x.sum(axis=0), x.sum(axis=1)" ] }, { "cell_type": "code", "execution_count": 219, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor(4),\n", " tensor(4),\n", " torch.return_types.max(\n", " values=tensor([3, 4]),\n", " indices=tensor([1, 1])),\n", " torch.return_types.max(\n", " values=tensor([2, 4]),\n", " indices=tensor([1, 1])))" ] }, "execution_count": 219, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.max(x), x.max(), x.max(axis=0), x.max(axis=1)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([2, 2]) torch.Size([4]) torch.Size([2, 1, 2]) torch.Size([1, 4])\n" ] } ], "source": [ "# resize/reshape\n", "x = torch.rand(2, 2)\n", "\n", "a = x.view(4)\n", "b = x.view(2, 1, -1)\n", "\n", "y = x.reshape(1, 4)\n", "\n", "print (x.size(), a.size(), b.size(), y.size())" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([3, 2, 5])" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# переставить размерности\n", "\n", "x = torch.rand(2, 3, 5)\n", "x.permute(1,0,2).size()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [3, 4]], dtype=int64)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# -> numpy\n", "\n", "x.numpy()" ] }, { "cell_type": "code", "execution_count": 187, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1. 1. 1. 1. 1.]\n", "tensor([1., 1., 1., 1., 1.], dtype=torch.float64)\n", "tensor([1., 1., 1., 1., 1.])\n", "[11. 11. 11. 11. 11.]\n", "tensor([11., 11., 11., 11., 11.], dtype=torch.float64)\n", "tensor([1., 1., 1., 1., 1.])\n" ] } ], "source": [ "# numpy -> pytorch\n", "# изменение в Numpy атоматически меняет тензор\n", "\n", "import numpy as np\n", "a = np.ones(5)\n", "b = torch.from_numpy(a)\n", "c = torch.Tensor(a)\n", "print(a)\n", "print(b)\n", "print(c)\n", "np.add(a, 10, out=a)\n", "# a = a + 1 # а так - нет\n", "print(a)\n", "print(b)\n", "print(c) # а тут нет" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[11, 22],\n", " [13, 24]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# приведение размеров\n", "\n", "x = torch.tensor([[1, 2], [3, 4]])\n", "y = torch.tensor([10, 20])\n", "\n", "x + y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Сохранение и загрузка тензоров" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([1., 2., 3.])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# сохранение и загрузка тензоров\n", "torch.save(x, 'x-file')\n", "x2 = torch.load(\"x-file\")\n", "x2" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([1., 2., 3.]),\n", " tensor([[ 3., 0.],\n", " [ 3., 12.]], requires_grad=True))" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.save([x, y],'x-files')\n", "x2, y2 = torch.load('x-files')\n", "(x2, y2)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'x': tensor([1., 2., 3.]),\n", " 'y': tensor([[ 3., 0.],\n", " [ 3., 12.]], requires_grad=True)}" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mydict = {'x': x, 'y': y}\n", "torch.save(mydict, 'mydict')\n", "mydict2 = torch.load('mydict')\n", "mydict2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Тензоры: примеры" ] }, { "cell_type": "code", "execution_count": 134, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", " [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n", " [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n", " [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n", " [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])" ] }, "execution_count": 134, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# OHE\n", "target = torch.tensor([0,3,2,2,0])\n", "target_onehot = torch.zeros(target.shape[0], 10)\n", "target_onehot.scatter_(1, target.unsqueeze(1), 1.0)" ] }, { "cell_type": "code", "execution_count": 148, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([10, 20, 1200])\n", "torch.Size([10, 20, 1200])\n" ] } ], "source": [ "# матрица -> вектор\n", "x = torch.rand(10, 20, 30, 40)\n", "print (x.view(-1, 20, 30*40).shape)\n", "print (torch.flatten(x, 2).shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## GPU\n", "\n", "переменные и модели на разных устройствах не видят друг друга!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# самая популярная конструкция\n", "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", "m.to(device) # перенос на доступное устройство" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[2, 3],\n", " [4, 5]], device='cuda:0')\n", "tensor([[2., 3.],\n", " [4., 5.]], dtype=torch.float64)\n" ] } ], "source": [ "if torch.cuda.is_available():\n", " device = torch.device(\"cuda\")\n", " y = torch.ones_like(x, device=device) \n", " x = x.to(device) \n", " z = x + y\n", " print(z)\n", " print(z.to(\"cpu\", torch.double)) \n", "else:\n", " device = torch.device(\"cpu\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x.cuda()\n", "x.cpu()\n", "x.is_cuda" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Whether to train on a gpu\n", "train_on_gpu = torch.cuda.is_available()\n", "print(f'Train on gpu: {train_on_gpu}')# Number of gpus\n", "if train_on_gpu:\n", " gpu_count = torch.cuda.device_count()\n", " print(f'{gpu_count} gpus detected.')\n", " if gpu_count > 1:\n", " multi_gpu = True\n", " else:\n", " multi_gpu = False\n", "if train_on_gpu:\n", " model = model.to('cuda')\n", "if multi_gpu:\n", " model = nn.DataParallel(model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ниже эксперименты со временем" ] }, { "cell_type": "code", "execution_count": 191, "metadata": {}, "outputs": [], "source": [ "x = torch.randn((1000, 1000))\n", "y = torch.randn((1000, 1000))" ] }, { "cell_type": "code", "execution_count": 193, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Wall time: 11 ms\n" ] } ], "source": [ "%%time\n", "z = x @ y " ] }, { "cell_type": "code", "execution_count": 195, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Wall time: 4.96 ms\n" ] } ], "source": [ "%%time\n", "x = x.cuda()\n", "y = y.cuda() # на перебрасывание тоже нужно время\n", "z = x @ y " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Авто дифференцирование" ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor(4.5000, grad_fn=)\n" ] } ], "source": [ "x = torch.tensor([[1, 2], [3, 4]], requires_grad=True, dtype=torch.float32)\n", "\n", "y = 3 * (x - 2) ** 2\n", "\n", "f = y.mean()\n", "\n", "print (f)" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "%3\r\n", "\r\n", "\r\n", "1686543498824\r\n", "\r\n", "MeanBackward0\r\n", "\r\n", "\r\n", "1686543497144\r\n", "\r\n", "MulBackward0\r\n", "\r\n", "\r\n", "1686543497144->1686543498824\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "1686543496136\r\n", "\r\n", "PowBackward0\r\n", "\r\n", "\r\n", "1686543496136->1686543497144\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "1686401450672\r\n", "\r\n", "SubBackward0\r\n", "\r\n", "\r\n", "1686401450672->1686543496136\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "1686543516616\r\n", "\r\n", " (2, 2)\r\n", "\r\n", "\r\n", "1686543516616->1686401450672\r\n", "\r\n", "\r\n", "\r\n", "\r\n", "\r\n" ], "text/plain": [ "" ] }, "execution_count": 162, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from torchviz import make_dot\n", "\n", "make_dot(f)" ] }, { "cell_type": "code", "execution_count": 163, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[1., 2.],\n", " [3., 4.]], requires_grad=True) tensor([[-1.5000, 0.0000],\n", " [ 1.5000, 3.0000]]) tensor([[-1.5000, 0.0000],\n", " [ 1.5000, 3.0000]], grad_fn=)\n" ] } ], "source": [ "f.backward()\n", "print(x, x.grad, 3*2*(x - 2)/4)" ] }, { "cell_type": "code", "execution_count": 168, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(None, None)" ] }, "execution_count": 168, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x += 1 # будет ошибка - inplace-операции не работают\n", "f.grad, y.grad # тут тоже ничего нет !!! (не было requires_grad=True - по этим переменным не бралась производная)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "tensor([1., 2., 3.])\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\djako\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:2: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " \n" ] } ], "source": [ "x = torch.Tensor([1, 2, 3])\n", "w = torch.tensor(torch.Tensor([1, 1, 1]), requires_grad=True)\n", "z = w @ x\n", "z.backward()\n", "print(x.grad, w.grad, sep='\\n')" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "tensor([2., 4., 6.])\n" ] } ], "source": [ "z = w @ x\n", "z.backward()\n", "print(x.grad, w.grad, sep='\\n') # идёт накопление!!!" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "tensor([2., 4., 6.])\n", "None\n", "tensor([1., 2., 3.])\n" ] } ], "source": [ "with torch.no_grad(): # нет накопления\n", " z = w @ x\n", " # z.backward()\n", "print(x.grad, w.grad, sep='\\n')\n", "\n", "w.grad.data.zero_() # а так - совсем обнулить\n", "z = w @ x\n", "z.backward()\n", "print(x.grad, w.grad, sep='\\n')" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1., 1., 1.], dtype=float32)" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# w.numpy() - будет ошибка\n", "w.detach().numpy() # создаётся копия, которую можно в np - у неё requires_grad=False" ] }, { "cell_type": "code", "execution_count": 188, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[ 1., 16.],\n", " [ 81., 256.]], grad_fn=) None\n", "tensor([[1., 2.],\n", " [3., 4.]], requires_grad=True) tensor([[ 1., 8.],\n", " [27., 64.]])\n" ] } ], "source": [ "# динамический граф вычислений в цикле\n", "\n", "x = torch.tensor([[1, 2], [3, 4]], requires_grad=True, dtype=torch.float32)\n", "x0 = x\n", "for i in range(2):\n", " x = x * x\n", "\n", "z = x.mean() # здесь будет 1/4 !!!\n", "z.backward()\n", "\n", "print(x, x.grad)\n", "print(x0, x0.grad) # градиент лежит здесь!!!\n", "# поскольку x превратился во внутреннюю вершину графа вычислений" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## TensorDataset / DataLoader\n", "\n", "организация подачи данных в модель\n", "* DataLoader - подаёт батчами\n", "* TensorDataset - для представления датасета" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[3., 1.],\n", " [9., 1.],\n", " [7., 1.],\n", " [5., 1.]])\n", "tensor([[ 9.],\n", " [81.],\n", " [49.],\n", " [25.]])\n", "tensor([[1., 1.],\n", " [8., 1.],\n", " [6., 1.],\n", " [4., 1.]])\n", "tensor([[ 1.],\n", " [64.],\n", " [36.],\n", " [16.]])\n", "tensor([[2., 1.],\n", " [0., 1.]])\n", "tensor([[4.],\n", " [0.]])\n" ] } ], "source": [ "from torch.utils.data import TensorDataset\n", "import numpy as np\n", "\n", "x = torch.from_numpy(np.vstack([np.arange(10, dtype='float32'), np.ones(10, dtype='float32')]).T)\n", "y = torch.from_numpy(np.arange(10, dtype='float32')[:, np.newaxis] ** 2)\n", "\n", "train_ds = TensorDataset(x, y)\n", "\n", "from torch.utils.data import DataLoader\n", "\n", "batch_size = 4\n", "train_dl = DataLoader(train_ds, batch_size, shuffle=True)\n", "\n", "for xb, yb in train_dl:\n", " print(xb)\n", " print(yb)\n", " # break" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# загрузка с трансформациями\n", "from torchvision import datasets\n", "\n", "train_loader = torch.utils.data.DataLoader(\n", " datasets.MNIST('../data', train=True, download=True,\n", " transform=transforms.Compose([\n", " transforms.ToTensor(),\n", " transforms.Normalize((0.1307,), (0.3081,))\n", " ])),\n", " batch_size=64, shuffle=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# есть стандартные датасеты\n", "trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)\n", "testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# загрузка из директории\n", "\n", "traindir = \"/home/rahul/projects/compvisblog/data/train/\"\n", "t = transforms.Compose([transforms.Resize(size=256),\n", " transforms.CenterCrop(size=224),\n", " transforms.ToTensor()])\n", "\n", "train_dataset = torchvision.datasets.ImageFolder(root=traindir, transform=t)\n", "\n", "for i in range(0,len(train_dataset)):\n", " image ,label = train_dataset[i]\n", " print(image,label)\n", " break\n", " \n", "train_dataloader = DataLoader(train_dataset,batch_size = 64, shuffle=True, num_workers=10)\n", "for image_batch, label_batch in train_dataloader:\n", " print(image_batch.size(),label_batch.size())\n", " break" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['CenterCrop',\n", " 'ColorJitter',\n", " 'Compose',\n", " 'FiveCrop',\n", " 'Grayscale',\n", " 'Lambda',\n", " 'LinearTransformation',\n", " 'Normalize',\n", " 'Pad',\n", " 'RandomAffine',\n", " 'RandomApply',\n", " 'RandomChoice',\n", " 'RandomCrop',\n", " 'RandomErasing',\n", " 'RandomGrayscale',\n", " 'RandomHorizontalFlip',\n", " 'RandomOrder',\n", " 'RandomPerspective',\n", " 'RandomResizedCrop',\n", " 'RandomRotation',\n", " 'RandomSizedCrop',\n", " 'RandomVerticalFlip',\n", " 'Resize',\n", " 'Scale',\n", " 'TenCrop',\n", " 'ToPILImage',\n", " 'ToTensor',\n", " '__builtins__',\n", " '__cached__',\n", " '__doc__',\n", " '__file__',\n", " '__loader__',\n", " '__name__',\n", " '__package__',\n", " '__path__',\n", " '__spec__',\n", " 'functional',\n", " 'transforms']" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# все трансформации\n", "from torchvision import transforms\n", "dir(transforms)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы pytorch работал с датасетом, надо определить\n", "* __getitem__\n", "* __len__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Свой датасет\n", "class CustomTextDataset(Dataset):\n", " '''\n", " Simple Dataset initializes with X and y vectors\n", " We start by sorting our X and y vectors by sequence lengths\n", " '''\n", " def __init__(self,X,y=None):\n", " self.data = list(zip(X,y))\n", " # Sort by length of first element in tuple\n", " self.data = sorted(self.data, key=lambda x: len(x[0]))\n", " \n", " def __len__(self):\n", " return len(self.data)\n", "\n", " def __getitem__(self, idx):\n", " return self.data[idx]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# свой загрузчик данных\n", "from glob import glob\n", "from PIL import Image\n", "from torch.utils.data import Dataset\n", "\n", "class customImageFolderDataset(Dataset):\n", " \"\"\"Custom Image Loader dataset.\"\"\"\n", " def __init__(self, root, transform=None):\n", " \"\"\"\n", " Args:\n", " root (string): Path to the images organized in a particular folder structure.\n", " transform: Any Pytorch transform to be applied\n", " \"\"\"\n", " # Get all image paths from a directory\n", " self.image_paths = glob(f\"{root}/*/*\")\n", " # Get the labels from the image paths\n", " self.labels = [x.split(\"/\")[-2] for x in self.image_paths]\n", " # Create a dictionary mapping each label to a index from 0 to len(classes).\n", " self.label_to_idx = {x:i for i,x in enumerate(set(self.labels))}\n", " self.transform = transform\n", " \n", " def __len__(self):\n", " # return length of dataset\n", " return len(self.image_paths)\n", " \n", " def __getitem__(self, idx):\n", " # open and send one image and label\n", " img_name = self.image_paths[idx]\n", " label = self.labels[idx]\n", " image = Image.open(img_name)\n", " if self.transform:\n", " image = self.transform(image)\n", " return image,self.label_to_idx[label]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### датасет с несколькими входами в сеть" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# если несколько входов в сеть\n", "\n", "from torch.utils.data import DataLoader, Dataset\n", "\n", "class TrainDataset(Dataset):\n", " def __init__(self, df, num_features, cat_features, labels):\n", " self.cont_values = df[num_features].values\n", " self.cate_values = df[cat_features].values\n", " self.labels = labels\n", " \n", " def __len__(self):\n", " return len(self.cont_values)\n", "\n", " def __getitem__(self, idx):\n", " cont_x = torch.FloatTensor(self.cont_values[idx])\n", " cate_x = torch.LongTensor(self.cate_values[idx])\n", " label = torch.tensor(self.labels[idx]).float()\n", " \n", " return cont_x, cate_x, label\n", " \n", "\n", "class TestDataset(Dataset):\n", " def __init__(self, df, num_features, cat_features):\n", " self.cont_values = df[num_features].values\n", " self.cate_values = df[cat_features].values\n", " \n", " def __len__(self):\n", " return len(self.cont_values)\n", "\n", " def __getitem__(self, idx):\n", " cont_x = torch.FloatTensor(self.cont_values[idx])\n", " cate_x = torch.LongTensor(self.cate_values[idx])\n", " \n", " return cont_x, cate_x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## nn" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Parameter containing:\n", "tensor([[0.5873, 0.3891]], requires_grad=True)\n", "Parameter containing:\n", "tensor([0.2473], requires_grad=True)\n" ] }, { "data": { "text/plain": [ "[Parameter containing:\n", " tensor([[0.5873, 0.3891]], requires_grad=True),\n", " Parameter containing:\n", " tensor([0.2473], requires_grad=True)]" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from torch import nn\n", "model = nn.Linear(2, 1)\n", "print(model.weight)\n", "print(model.bias)\n", "list(model.parameters())" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1.8111],\n", " [0.6364]], grad_fn=)" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model(xb)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor(2.5982, grad_fn=)\n" ] } ], "source": [ "import torch.nn.functional as F\n", "loss_fn = F.mse_loss\n", "loss = loss_fn(model(xb), yb)\n", "print(loss)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* train() / eval() - какой режим использовать\n", "\n", "влияет на BN и DO" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [], "source": [ "opt = torch.optim.SGD(model.parameters(), lr=1e-5)\n", "\n", "# Пример обучения модели\n", "def fit(num_epochs, model, loss_fn, opt, train_dl):\n", " \n", " # повторяем нужное число эпох\n", " for epoch in range(num_epochs):\n", " model.train() # перенести раньше, если не выходим из режима обучения\n", " for xb, yb in train_dl: # по батчам\n", " pred = model(xb) # прогнать прямой ход\n", " opt.zero_grad() # обнулить градиенты \n", " loss = loss_fn(pred, yb) # вычислить ошибку\n", " loss.backward() # обратный ход - вычислить градиенты\n", " opt.step() # изменить параметры\n", " if (epoch+1) % 10 == 0: # прогресс\n", " print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item()))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# валидация\n", "model.eval()\n", "with torch.no_grad():\n", " train, y_train = train_dataset.tensors\n", " # train, y_train = train.to(device), y_train.to(device)\n", " train_preds = model(train)\n", " train_loss = loss_fn(train_preds, y_train).item()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# само обучение\n", "optimizer.zero_grad() # = net.zero_grad()\n", "output = net(x)\n", "loss = criterion(output,y)\n", "loss.backward()\n", "optimizer.step()\n", "print(loss)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch [10/100], Loss: 19.5047\n", "Epoch [20/100], Loss: 2674.4380\n", "Epoch [30/100], Loss: 83.3502\n", "Epoch [40/100], Loss: 185.8370\n", "Epoch [50/100], Loss: 175.2909\n", "Epoch [60/100], Loss: 54.3152\n", "Epoch [70/100], Loss: 2347.3945\n", "Epoch [80/100], Loss: 7.9410\n", "Epoch [90/100], Loss: 182.1962\n", "Epoch [100/100], Loss: 331.3730\n" ] } ], "source": [ "fit(100, model, loss_fn, opt, train_dl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Простейшее задание нейронной сети, параметры\n", "* nn\n", "* эквивалентная форма\n", "* доступ к параметрам" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[-0.1064, -0.4379],\n", " [-0.0843, -0.4140],\n", " [-0.0656, -0.4279]], grad_fn=)" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# через nn.Sequential\n", "net = nn.Sequential(nn.Linear(10, 5),\n", " nn.ReLU(),\n", " nn.Linear(5, 2))\n", "\n", "X = torch.rand(3, 10)\n", "net(X)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[ 0.2691, -0.5603],\n", " [ 0.2428, -0.5813],\n", " [ 0.2394, -0.4632]], grad_fn=)" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# эквивалентная форма\n", "\n", "class MLP(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.hidden = nn.Linear(10, 5) # Hidden layer\n", " self.out = nn.Linear(5, 2) # Output layer\n", "\n", " def forward(self, X):\n", " # как получается ответ\n", " return self.out(F.relu(self.hidden(X)))\n", "\n", "net2 = MLP()\n", "net2(X)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sequential(\n", " (0): Linear(in_features=10, out_features=5, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=5, out_features=2, bias=True)\n", ")" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "MLP(\n", " (hidden): Linear(in_features=10, out_features=5, bias=True)\n", " (out): Linear(in_features=5, out_features=2, bias=True)\n", ")" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net2" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Linear(in_features=10, out_features=5, bias=True),\n", " Linear(in_features=10, out_features=5, bias=True))" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net[0], net2.hidden" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(OrderedDict([('weight',\n", " tensor([[-0.2913, 0.2741, -0.1572, -0.0602, -0.1266, 0.3091, 0.0150, -0.2267,\n", " -0.2864, 0.2689],\n", " [ 0.1637, 0.1041, -0.2499, 0.0425, 0.2751, 0.1211, 0.0142, 0.0580,\n", " -0.1686, -0.1782],\n", " [-0.2128, -0.2699, -0.2654, 0.1590, 0.1555, 0.0836, 0.1484, -0.2917,\n", " -0.0426, -0.3108],\n", " [ 0.1652, -0.2611, -0.0391, -0.0729, 0.0614, 0.2785, -0.0926, 0.2232,\n", " 0.0170, -0.1833],\n", " [ 0.0161, -0.2227, -0.0627, 0.2687, -0.2884, -0.1729, 0.0918, -0.2091,\n", " -0.1096, 0.2262]])),\n", " ('bias',\n", " tensor([ 0.2531, -0.1746, -0.2381, 0.0756, -0.3050]))]),\n", " OrderedDict([('weight',\n", " tensor([[-0.0298, -0.1098, 0.2952, 0.0838, -0.1459, 0.2697, 0.2458, -0.0543,\n", " 0.1449, 0.1264],\n", " [-0.2429, 0.1897, -0.1040, 0.2425, -0.2561, 0.1547, -0.0331, -0.2910,\n", " -0.0013, -0.1380],\n", " [-0.2489, 0.1274, -0.0307, -0.2244, -0.0548, 0.2250, -0.0645, -0.1102,\n", " -0.0484, -0.1338],\n", " [ 0.1526, 0.1736, -0.1106, -0.0456, 0.1500, -0.0332, -0.2646, -0.0886,\n", " 0.1390, 0.1706],\n", " [-0.0915, -0.3143, 0.1661, 0.1954, 0.1994, -0.0674, 0.0939, 0.2139,\n", " -0.0600, 0.1535]])),\n", " ('bias',\n", " tensor([-0.2741, -0.0290, 0.2044, -0.3139, 0.1633]))]))" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net[0].state_dict(), net2.hidden.state_dict()" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([ 0.2531, -0.1746, -0.2381, 0.0756, -0.3050]),\n", " tensor([-0.2741, -0.0290, 0.2044, -0.3139, 0.1633]))" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net[0].bias.data, net2.hidden.bias.data" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(None, None)" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net[0].bias.grad, net2.hidden.bias.grad # не было обучения (BP), поэтому None" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('0.weight', torch.Size([5, 10])) ('0.bias', torch.Size([5])) ('2.weight', torch.Size([2, 5])) ('2.bias', torch.Size([2]))\n", "tensor([[-0.2913, 0.2741, -0.1572, -0.0602, -0.1266, 0.3091, 0.0150, -0.2267,\n", " -0.2864, 0.2689],\n", " [ 0.1637, 0.1041, -0.2499, 0.0425, 0.2751, 0.1211, 0.0142, 0.0580,\n", " -0.1686, -0.1782],\n", " [-0.2128, -0.2699, -0.2654, 0.1590, 0.1555, 0.0836, 0.1484, -0.2917,\n", " -0.0426, -0.3108]], grad_fn=)\n", "tensor([ 0.2531, -0.1746, -0.2381], grad_fn=)\n", "tensor([[-0.0220, -0.1656, 0.3063, 0.3028, -0.2868],\n", " [-0.3693, -0.2013, 0.1348, 0.3793, 0.2336]],\n", " grad_fn=)\n", "tensor([-0.1386, 0.3527], grad_fn=)\n" ] } ], "source": [ "# перечислить параметры\n", "print(*[(name, param.shape) for name, param in net.named_parameters()])\n", "\n", "for param in net.parameters():\n", " print(param[:3])" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(67, [50, 5, 10, 2])" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# считаем число параметров\n", "numel_list = [p.numel() for p in net.parameters() if p.requires_grad == True]\n", "sum(numel_list), numel_list" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linear output shape: \t torch.Size([20, 5])\n", "ReLU output shape: \t torch.Size([20, 5])\n", "Linear output shape: \t torch.Size([20, 2])\n" ] } ], "source": [ "# вывод размеров по слоям\n", "\n", "# X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)\n", "X = torch.rand(size=(20, 10), dtype=torch.float32)\n", "\n", "for layer in net:\n", " X = layer(X)\n", " print(layer.__class__.__name__,'output shape: \\t',X.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ещё примеры заданий нейросетей" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class myCrazyNeuralNet(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.lin1 = nn.Linear(784, 30)\n", " self.lin2 = nn.Linear(30, 784)\n", " self.lin3 = nn.Linear(30, 10)\n", " \n", " def forward(self, x):\n", " x_lin1 = self.lin1(x)\n", " x_lin2 = x + self.lin2(x_lin1)\n", " x_lin2 = self.lin1(x_lin2)\n", " x = self.lin3(x_lin2)\n", " return x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def conv_block(in_f, out_f, activation='relu', *args, **kwargs):\n", " activations = nn.ModuleDict([\n", " ['lrelu', nn.LeakyReLU()],\n", " ['relu', nn.ReLU()]\n", " ])\n", " \n", " return nn.Sequential(\n", " nn.Conv2d(in_f, out_f, *args, **kwargs),\n", " nn.BatchNorm2d(out_f),\n", " activations[activation]\n", " )\n", "\n", "def dec_block(in_f, out_f):\n", " return nn.Sequential(\n", " nn.Linear(in_f, out_f),\n", " nn.Sigmoid()\n", " )\n", "\n", "class MyEncoder(nn.Module):\n", " def __init__(self, enc_sizes, *args, **kwargs):\n", " super().__init__()\n", " self.conv_blokcs = nn.Sequential(*[conv_block(in_f, out_f, kernel_size=3, padding=1, *args, **kwargs) \n", " for in_f, out_f in zip(enc_sizes, enc_sizes[1:])])\n", " \n", " def forward(self, x):\n", " return self.conv_blokcs(x)\n", " \n", "class MyDecoder(nn.Module):\n", " def __init__(self, dec_sizes, n_classes):\n", " super().__init__()\n", " self.dec_blocks = nn.Sequential(*[dec_block(in_f, out_f) \n", " for in_f, out_f in zip(dec_sizes, dec_sizes[1:])])\n", " self.last = nn.Linear(dec_sizes[-1], n_classes)\n", "\n", " def forward(self, x):\n", " return self.dec_blocks()\n", " \n", " \n", "class MyCNNClassifier(nn.Module):\n", " def __init__(self, in_c, enc_sizes, dec_sizes, n_classes, activation='relu'):\n", " super().__init__()\n", " self.enc_sizes = [in_c, *enc_sizes]\n", " self.dec_sizes = [32 * 28 * 28, *dec_sizes]\n", "\n", " self.encoder = MyEncoder(self.enc_sizes, activation=activation)\n", " \n", " self.decoder = MyDecoder(dec_sizes, n_classes)\n", " \n", " def forward(self, x):\n", " x = self.encoder(x)\n", " \n", " x = x.flatten(1) # flat\n", " \n", " x = self.decoder(x)\n", " \n", " return x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# явное прописывание весов\n", "\n", "class MyNetworkWithParams(nn.Module):\n", " def __init__(self,input_size, hidden_size, output_size):\n", " super(MyNetworkWithParams,self).__init__()\n", " self.layer1_weights = nn.Parameter(torch.randn(input_size,hidden_size))\n", " self.layer1_bias = nn.Parameter(torch.randn(hidden_size))\n", " self.layer2_weights = nn.Parameter(torch.randn(hidden_size,output_size))\n", " self.layer2_bias = nn.Parameter(torch.randn(output_size))\n", " \n", " def forward(self,x):\n", " h1 = torch.matmul(x,self.layer1_weights) + self.layer1_bias\n", " h1_act = torch.max(h1, torch.zeros(h1.size())) # ReLU\n", " output = torch.matmul(h1_act,self.layer2_weights) + self.layer2_bias\n", " return output\n", "\n", "net = MyNetworkWithParams(32,128,10)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sequential(\n", " (0): Sequential(\n", " (block 0): Sequential(\n", " (0): Linear(in_features=10, out_features=4, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=4, out_features=10, bias=True)\n", " (3): ReLU()\n", " )\n", " (block 1): Sequential(\n", " (0): Linear(in_features=10, out_features=4, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=4, out_features=10, bias=True)\n", " (3): ReLU()\n", " )\n", " (block 2): Sequential(\n", " (0): Linear(in_features=10, out_features=4, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=4, out_features=10, bias=True)\n", " (3): ReLU()\n", " )\n", " (block 3): Sequential(\n", " (0): Linear(in_features=10, out_features=4, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=4, out_features=10, bias=True)\n", " (3): ReLU()\n", " )\n", " )\n", " (1): Linear(in_features=10, out_features=1, bias=True)\n", ")\n" ] } ], "source": [ "# вложенные блоки\n", "\n", "def block1():\n", " return nn.Sequential(nn.Linear(10, 4), nn.ReLU(),\n", " nn.Linear(4, 10), nn.ReLU())\n", "\n", "def block2():\n", " net = nn.Sequential()\n", " for i in range(4):\n", " # Nested here\n", " net.add_module(f'block {i}', block1())\n", " return net\n", "\n", "rgnet = nn.Sequential(block2(), nn.Linear(10, 1))\n", "\n", "rgnet(X)\n", "\n", "print(rgnet)" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Parameter containing:\n", "tensor([ 0.2119, 0.1545, -0.0612, 0.2647, -0.3946, -0.0332, -0.0323, 0.3765,\n", " -0.1765, -0.4842], requires_grad=True)" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rgnet[0][2][2].bias" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Разделение параметров" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [], "source": [ "shared = nn.Linear(8, 8)\n", "net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),\n", " shared, nn.ReLU(),\n", " shared, nn.ReLU(),\n", " nn.Linear(8, 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Свои слои, задание слоёв\n", "* пример слоя\n", "* слой + NN\n", "* списки слоёв" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [], "source": [ "# центрирующий слой без параметров\n", "\n", "class CenteredLayer(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", "\n", " def forward(self, X):\n", " return X - X.mean()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from torch import nn\n", "\n", "class myCustomLinearLayer(nn.Module):\n", " def __init__(self,in_size,out_size):\n", " super().__init__()\n", " self.weights = nn.Parameter(torch.randn(in_size, out_size))\n", " self.bias = nn.Parameter(torch.zeros(out_size))\n", "\n", " def forward(self, x):\n", " return x.mm(self.weights) + self.bias\n", "\n", "class myCustomNeuralNet(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " # Define all Layers Here\n", " self.lin1 = myCustomLinearLayer(784,10)\n", " \n", " def forward(self, x):\n", " # Connect the layer Outputs here to define the forward pass\n", " x = self.lin1(x)\n", " return x\n", " \n", "x = torch.randn((100,784))\n", "model = myCustomNeuralNet()\n", "model(x).size()" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [], "source": [ "# списки слоёв\n", "\n", "class MyNet(nn.Module):\n", " def __init__(self,n_hidden_layers):\n", " super(MyNet,self).__init__()\n", " self.n_hidden_layers=n_hidden_layers\n", " self.final_layer = nn.Linear(128,10)\n", " self.act = nn.ReLU()\n", " self.hidden = []\n", " for i in range(n_hidden_layers):\n", " self.hidden.append(nn.Linear(128,128))\n", " self.hidden = nn.ModuleList(self.hidden) # это важно!\n", " \n", " def forward(self,x):\n", " h = x\n", " for i in range(self.n_hidden_layers):\n", " h = self.hidden[i](h)\n", " h = self.act(h)\n", " out = self.final_layer(h)\n", " return out" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Инициализация" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([-0.0137, -0.0014, 0.0093, 0.0124, -0.0141, 0.0154, -0.0074, 0.0009,\n", " 0.0061, -0.0013]),\n", " tensor(0.))" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# инициализация\n", "\n", "def init_normal(m):\n", " if type(m) == nn.Linear:\n", " nn.init.normal_(m.weight, mean=0, std=0.01)\n", " nn.init.zeros_(m.bias)\n", "\n", "net.apply(init_normal)\n", "\n", "net[0].weight.data[0], net[0].bias.data[0]" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([-0.3876, 0.1836, 0.5121, -0.5632, 0.3504, 0.0779, -0.6140, -0.2752,\n", " -0.0533, -0.3310])\n", "tensor([[42., 42., 42., 42., 42.],\n", " [42., 42., 42., 42., 42.]])\n" ] } ], "source": [ "# инициализация по блокам\n", "\n", "def xavier(m):\n", " if type(m) == nn.Linear:\n", " nn.init.xavier_uniform_(m.weight)\n", "\n", "def init_42(m):\n", " if type(m) == nn.Linear:\n", " nn.init.constant_(m.weight, 42)\n", "\n", "net[0].apply(xavier)\n", "net[2].apply(init_42)\n", "\n", "print(net[0].weight.data[0])\n", "print(net[2].weight.data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Функции обучения и теста на одной эпохе" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def train_epoch(model, train_loader, criterion, optimizer):\n", " model.train()\n", "\n", " running_loss = 0.0\n", " \n", " start_time = time.time()\n", " for batch_idx, (data, target) in enumerate(train_loader): \n", " optimizer.zero_grad() # .backward() accumulates gradients\n", " data = data.to(device)\n", " target = target.to(device) # all data & model on same device\n", "\n", " outputs = model(data)\n", " loss = criterion(outputs, target)\n", " running_loss += loss.item()\n", "\n", " loss.backward()\n", " optimizer.step()\n", " \n", " end_time = time.time()\n", " \n", " running_loss /= len(train_loader)\n", " print('Training Loss: ', running_loss, 'Time: ',end_time - start_time, 's')\n", " return running_loss\n", "\n", "def test_model(model, test_loader, criterion):\n", " with torch.no_grad():\n", " model.eval()\n", "\n", " running_loss = 0.0\n", " total_predictions = 0.0\n", " correct_predictions = 0.0\n", "\n", " for batch_idx, (data, target) in enumerate(test_loader): \n", " data = data.to(device)\n", " target = target.to(device)\n", "\n", " outputs = model(data)\n", "\n", " _, predicted = torch.max(outputs.data, 1)\n", " total_predictions += target.size(0)\n", " correct_predictions += (predicted == target).sum().item()\n", "\n", " loss = criterion(outputs, target).detach()\n", " running_loss += loss.item()\n", "\n", "\n", " running_loss /= len(test_loader)\n", " acc = (correct_predictions/total_predictions)*100.0\n", " print('Testing Loss: ', running_loss)\n", " print('Testing Accuracy: ', acc, '%')\n", " return running_loss, acc\n", " \n", "n_epochs = 10\n", "Train_loss = []\n", "Test_loss = []\n", "Test_acc = []\n", "\n", "for i in range(n_epochs):\n", " train_loss = train_epoch(model, train_loader, criterion, optimizer)\n", " test_loss, test_acc = test_model(model, test_loader, criterion)\n", " Train_loss.append(train_loss)\n", " Test_loss.append(test_loss)\n", " Test_acc.append(test_acc)\n", " print('='*20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Сохранение / загрузка сети" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "torch.save(model, \"/tmp/model\")\n", "torch.save(model.state_dict(), \"/tmp/model\") # только параметры\n", "\n", "model = torch.load(\"/tmp/model\")\n", "\n", "model = MLP()\n", "model.load_state_dict(torch.load(\"/tmp/model\")) # только параметры\n", "model.eval()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Свёртки, пулинг" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([100, 64, 24, 24])" ] }, "execution_count": 142, "metadata": {}, "output_type": "execute_result" } ], "source": [ "conv_layer = nn.Conv2d(in_channels = 3, out_channels = 64, kernel_size = (3,3), stride = 1, padding=1)\n", "x = torch.randn((100,3,24,24))\n", "conv_layer(x).size()" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([1, 10, 2, 3])" ] }, "execution_count": 143, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Адаптивный пулинг - выход фиксированного размера\n", "m = nn.AdaptiveAvgPool2d((2, 3))\n", "input = torch.randn(1, 10, 20, 30)\n", "output = m(input)\n", "output.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Своя Loss-функция" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class CustomNLLLoss(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " def forward(self, x, y):\n", " # x should be output from LogSoftmax Layer \n", " log_prob = -1.0 * x\n", " # Get log_prob based on y class_index as loss=-mean(ylogp)\n", " loss = log_prob.gather(1, y.unsqueeze(1))\n", " loss = loss.mean()\n", " return loss\n", " \n", "criterion = CustomNLLLoss() # nn.NLLLoss()\n", "CustomNLLLossClass = criterion(preds,y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Transfer Learning" ] }, { "cell_type": "code", "execution_count": 152, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Downloading: \"https://download.pytorch.org/models/resnet34-333f7ec4.pth\" to C:\\Users\\djako/.cache\\torch\\checkpoints\\resnet34-333f7ec4.pth\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "96c51bea5eb3415db816795f3f102d5d", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(FloatProgress(value=0.0, max=87306240.0), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# берём готовую модель\n", "from torchvision import models\n", "transfer_model = models.resnet34(pretrained=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# заморозка слоёв\n", "for name, param in model_cnn.named_parameters():\n", " if (\"bn\" not in name):\n", " param.requires_grad = False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# меняем голову\n", "\n", "# TO DO\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# BiLSTM" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class BiLSTM(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.hidden_size = 64\n", " drp = 0.1\n", " max_features, embed_size = 10000,300\n", " self.embedding = nn.Embedding(max_features, embed_size)\n", " self.lstm = nn.LSTM(embed_size, self.hidden_size, bidirectional=True, batch_first=True)\n", " self.linear = nn.Linear(self.hidden_size*4 , 64)\n", " self.relu = nn.ReLU()\n", " self.dropout = nn.Dropout(drp)\n", " self.out = nn.Linear(64, 1)\n", "\n", "\n", " def forward(self, x):\n", " h_embedding = self.embedding(x)\n", " h_embedding = torch.squeeze(torch.unsqueeze(h_embedding, 0))\n", " \n", " h_lstm, _ = self.lstm(h_embedding)\n", " avg_pool = torch.mean(h_lstm, 1)\n", " max_pool, _ = torch.max(h_lstm, 1)\n", " conc = torch.cat(( avg_pool, max_pool), 1)\n", " conc = self.relu(self.linear(conc))\n", " conc = self.dropout(conc)\n", " out = self.out(conc)\n", " return out" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Как сеть искриволяет пространство" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import torch.nn as nn\n", "\n", "X = torch.rand(500, 2)\n", "y = X[:, 0] + X[:, 1]\n", "plt.figure(figsize=(12, 5))\n", "plt.subplot(1, 2, 1)\n", "plt.scatter(X[:,0], X[:,1], 20, y)\n", "\n", "n_hidden = 10\n", "model = nn.Sequential(nn.Linear(2, n_hidden),\n", " nn.ReLU(),\n", " nn.Linear(n_hidden, n_hidden),\n", " nn.ReLU(),\n", " nn.Linear(n_hidden, 2))\n", "# model.to(device)\n", "with torch.no_grad():\n", " Y = model(X)\n", "plt.subplot(1, 2, 2)\n", "plt.scatter(Y[:,0], Y[:,1], 20, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Пример" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shapes:\n", "X: (3000, 2)\n", "y: (3000,)\n" ] } ], "source": [ "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", "\n", "import random, math\n", "seed = 12345\n", "random.seed(seed)\n", "torch.manual_seed(seed)\n", "N = 1000 # num_samples_per_class\n", "D = 2 # dimensions\n", "C = 3 # num_classes\n", "H = 100 # num_hidden_units\n", "\n", "# данные\n", "X = torch.zeros(N * C, D).to(device)\n", "y = torch.zeros(N * C, dtype=torch.long).to(device)\n", "for c in range(C):\n", " index = 0\n", " t = torch.linspace(0, 1, N)\n", "\n", " inner_var = torch.linspace((2 * math.pi / C) * (c), (2 * math.pi / C) * (2 + c), N) + torch.randn(N) * 0.2\n", " \n", " for ix in range(N * c, N * (c + 1)):\n", " X[ix] = t[index] * torch.FloatTensor((math.sin(inner_var[index]), math.cos(inner_var[index])))\n", " y[ix] = c\n", " index += 1\n", "\n", "print(\"Shapes:\")\n", "print(\"X:\", tuple(X.size()))\n", "print(\"y:\", tuple(y.size()))" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[EPOCH]: 999, [LOSS]: 0.161706, [ACCURACY]: 0.954\n" ] } ], "source": [ "from IPython import display\n", "learning_rate = 1e-3\n", "lambda_l2 = 1e-5\n", "\n", "model = nn.Sequential(\n", " nn.Linear(D, H),\n", " nn.ReLU(),\n", " nn.Linear(H, C)\n", ")\n", "model.to(device)\n", "\n", "criterion = torch.nn.CrossEntropyLoss()\n", "\n", "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=lambda_l2)\n", "\n", "for t in range(1000):\n", " \n", " y_pred = model(X)\n", "\n", " loss = criterion(y_pred, y)\n", " score, predicted = torch.max(y_pred, 1)\n", " acc = (y == predicted).sum().float() / len(y)\n", " print(\"[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f\" % (t, loss.item(), acc))\n", " display.clear_output(wait=True)\n", " \n", " optimizer.zero_grad()\n", " \n", " loss.backward()\n", "\n", " optimizer.step()" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sequential(\n", " (0): Linear(in_features=2, out_features=100, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=100, out_features=3, bias=True)\n", ")\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "print(model)\n", "plot_model(X, y, model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### НС на numpy\n", "\n", "дальше примеры из https://pytorch.org/tutorials/beginner/pytorch_with_examples.html" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.74824768139619e-24\n", "Wall time: 2.55 s\n" ] } ], "source": [ "%%time\n", "\n", "import numpy as np\n", "\n", "# N is batch size; D_in is input dimension;\n", "# H is hidden dimension; D_out is output dimension.\n", "N, D_in, H, D_out = 64, 1000, 100, 10\n", "\n", "# Create random input and output data\n", "x = np.random.randn(N, D_in)\n", "y = np.random.randn(N, D_out)\n", "\n", "# Randomly initialize weights\n", "w1 = np.random.randn(D_in, H)\n", "w2 = np.random.randn(H, D_out)\n", "\n", "learning_rate = 1e-6\n", "for t in range(5000):\n", " # Forward pass: compute predicted y\n", " h = x.dot(w1)\n", " h_relu = np.maximum(h, 0)\n", " y_pred = h_relu.dot(w2)\n", "\n", " # Compute and print loss\n", " loss = np.square(y_pred - y).sum()\n", " # print(t, loss)\n", "\n", " # Backprop to compute gradients of w1 and w2 with respect to loss\n", " grad_y_pred = 2.0 * (y_pred - y)\n", " grad_w2 = h_relu.T.dot(grad_y_pred)\n", " grad_h_relu = grad_y_pred.dot(w2.T)\n", " grad_h = grad_h_relu.copy()\n", " grad_h[h < 0] = 0\n", " grad_w1 = x.T.dot(grad_h)\n", "\n", " # Update weights\n", " w1 -= learning_rate * grad_w1\n", " w2 -= learning_rate * grad_w2\n", " \n", "print(loss)" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.74573608294304e-07\n", "Wall time: 7.42 s\n" ] } ], "source": [ "%%time\n", "\n", "import torch\n", "\n", "\n", "dtype = torch.float\n", "# device = torch.device(\"cpu\")\n", "device = torch.device(\"cuda:0\") # Uncomment this to run on GPU\n", "\n", "# N is batch size; D_in is input dimension;\n", "# H is hidden dimension; D_out is output dimension.\n", "N, D_in, H, D_out = 64, 1000, 100, 10\n", "\n", "# Create random input and output data\n", "x = torch.randn(N, D_in, device=device, dtype=dtype)\n", "y = torch.randn(N, D_out, device=device, dtype=dtype)\n", "\n", "# Randomly initialize weights\n", "w1 = torch.randn(D_in, H, device=device, dtype=dtype)\n", "w2 = torch.randn(H, D_out, device=device, dtype=dtype)\n", "\n", "learning_rate = 1e-6\n", "for t in range(5000):\n", " # Forward pass: compute predicted y\n", " h = x.mm(w1)\n", " h_relu = h.clamp(min=0)\n", " y_pred = h_relu.mm(w2)\n", "\n", " # Compute and print loss\n", " loss = (y_pred - y).pow(2).sum().item()\n", " #if t % 100 == 99:\n", " # print(t, loss)\n", "\n", " # Backprop to compute gradients of w1 and w2 with respect to loss\n", " grad_y_pred = 2.0 * (y_pred - y)\n", " grad_w2 = h_relu.t().mm(grad_y_pred)\n", " grad_h_relu = grad_y_pred.mm(w2.t())\n", " grad_h = grad_h_relu.clone()\n", " grad_h[h < 0] = 0\n", " grad_w1 = x.t().mm(grad_h)\n", "\n", " # Update weights using gradient descent\n", " w1 -= learning_rate * grad_w1\n", " w2 -= learning_rate * grad_w2\n", "\n", "print(loss)\n", "# CPU 3.05 s\n", "# GPU 6.77 s" ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.4651128544282983e-07\n", "Wall time: 7.52 s\n" ] } ], "source": [ "%%time\n", "\n", "import torch\n", "\n", "dtype = torch.float\n", "# device = torch.device(\"cpu\")\n", "device = torch.device(\"cuda:0\") # Uncomment this to run on GPU\n", "\n", "# N is batch size; D_in is input dimension;\n", "# H is hidden dimension; D_out is output dimension.\n", "N, D_in, H, D_out = 64, 1000, 100, 10\n", "\n", "# Create random Tensors to hold input and outputs.\n", "# Setting requires_grad=False indicates that we do not need to compute gradients\n", "# with respect to these Tensors during the backward pass.\n", "x = torch.randn(N, D_in, device=device, dtype=dtype)\n", "y = torch.randn(N, D_out, device=device, dtype=dtype)\n", "\n", "# Create random Tensors for weights.\n", "# Setting requires_grad=True indicates that we want to compute gradients with\n", "# respect to these Tensors during the backward pass.\n", "w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)\n", "w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)\n", "\n", "learning_rate = 1e-6\n", "for t in range(5000):\n", " # Forward pass: compute predicted y using operations on Tensors; these\n", " # are exactly the same operations we used to compute the forward pass using\n", " # Tensors, but we do not need to keep references to intermediate values since\n", " # we are not implementing the backward pass by hand.\n", " y_pred = x.mm(w1).clamp(min=0).mm(w2)\n", "\n", " # Compute and print loss using operations on Tensors.\n", " # Now loss is a Tensor of shape (1,)\n", " # loss.item() gets the scalar value held in the loss.\n", " loss = (y_pred - y).pow(2).sum()\n", " #if t % 100 == 99:\n", " # print(t, loss.item())\n", "\n", " # Use autograd to compute the backward pass. This call will compute the\n", " # gradient of loss with respect to all Tensors with requires_grad=True.\n", " # After this call w1.grad and w2.grad will be Tensors holding the gradient\n", " # of the loss with respect to w1 and w2 respectively.\n", " loss.backward()\n", "\n", " # Manually update weights using gradient descent. Wrap in torch.no_grad()\n", " # because weights have requires_grad=True, but we don't need to track this\n", " # in autograd.\n", " # An alternative way is to operate on weight.data and weight.grad.data.\n", " # Recall that tensor.data gives a tensor that shares the storage with\n", " # tensor, but doesn't track history.\n", " # You can also use torch.optim.SGD to achieve this.\n", " with torch.no_grad():\n", " w1 -= learning_rate * w1.grad\n", " w2 -= learning_rate * w2.grad\n", "\n", " # Manually zero the gradients after updating weights\n", " w1.grad.zero_()\n", " w2.grad.zero_()\n", " \n", "print (loss.item())\n", "\n", "# CPU 5.7 s\n", "# GPU 8.87 s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Пример пакета nn" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0499554350951179e-11\n", "Wall time: 7.21 s\n" ] } ], "source": [ "%%time\n", "\n", "import torch\n", "\n", "# N is batch size; D_in is input dimension;\n", "# H is hidden dimension; D_out is output dimension.\n", "N, D_in, H, D_out = 64, 1000, 100, 10\n", "\n", "# Create random Tensors to hold inputs and outputs\n", "x = torch.randn(N, D_in)\n", "y = torch.randn(N, D_out)\n", "\n", "# Use the nn package to define our model as a sequence of layers. nn.Sequential\n", "# is a Module which contains other Modules, and applies them in sequence to\n", "# produce its output. Each Linear Module computes output from input using a\n", "# linear function, and holds internal Tensors for its weight and bias.\n", "model = torch.nn.Sequential(\n", " torch.nn.Linear(D_in, H),\n", " torch.nn.ReLU(),\n", " torch.nn.Linear(H, D_out),\n", ")\n", "\n", "# The nn package also contains definitions of popular loss functions; in this\n", "# case we will use Mean Squared Error (MSE) as our loss function.\n", "loss_fn = torch.nn.MSELoss(reduction='sum')\n", "\n", "learning_rate = 1e-4\n", "for t in range(5000):\n", " # Forward pass: compute predicted y by passing x to the model. Module objects\n", " # override the __call__ operator so you can call them like functions. When\n", " # doing so you pass a Tensor of input data to the Module and it produces\n", " # a Tensor of output data.\n", " y_pred = model(x)\n", "\n", " # Compute and print loss. We pass Tensors containing the predicted and true\n", " # values of y, and the loss function returns a Tensor containing the\n", " # loss.\n", " loss = loss_fn(y_pred, y)\n", " #if t % 100 == 99:\n", " # print(t, loss.item())\n", "\n", " # Zero the gradients before running the backward pass.\n", " model.zero_grad()\n", "\n", " # Backward pass: compute gradient of the loss with respect to all the learnable\n", " # parameters of the model. Internally, the parameters of each Module are stored\n", " # in Tensors with requires_grad=True, so this call will compute gradients for\n", " # all learnable parameters in the model.\n", " loss.backward()\n", "\n", " # Update the weights using gradient descent. Each parameter is a Tensor, so\n", " # we can access its gradients like we did before.\n", " with torch.no_grad():\n", " for param in model.parameters():\n", " param -= learning_rate * param.grad\n", " \n", "print(loss.item())\n", "# CPU 8.05 s" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0213095993916177e-11\n", "Wall time: 10.3 s\n" ] } ], "source": [ "%%time\n", "\n", "import torch\n", "\n", "N, D_in, H, D_out = 64, 1000, 100, 10\n", "\n", "x = torch.randn(N, D_in)\n", "y = torch.randn(N, D_out)\n", "\n", "model = torch.nn.Sequential(\n", " torch.nn.Linear(D_in, H),\n", " torch.nn.ReLU(),\n", " torch.nn.Linear(H, D_out),\n", ")\n", "\n", "loss_fn = torch.nn.MSELoss(reduction='sum')\n", "\n", "\n", "learning_rate = 1e-4\n", "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n", "\n", "for t in range(5000):\n", " y_pred = model(x)\n", "\n", " loss = loss_fn(y_pred, y)\n", " # if t % 100 == 99:\n", " # print(t, loss.item())\n", "\n", " optimizer.zero_grad()\n", "\n", " loss.backward()\n", "\n", " optimizer.step()\n", " \n", "print(loss.item())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## отдельные Log-регрессии и одна многомерная\n", "\n", "* отдельные - очень медленно на 1 GPU" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [], "source": [ "class MyOneModel(nn.Module):\n", " def __init__(self, in_features, out_features):\n", " super(MyOneModel, self).__init__()\n", " self.bn1 = nn.BatchNorm1d(in_features)\n", " self.do1 = nn.Dropout(0.3)\n", " self.ln1 = nn.Linear(in_features, out_features) # nn.utils.weight_norm(nn.Linear(n1, n2))\n", " self.ph1 = nn.Sigmoid()\n", " \n", " def forward(self, x):\n", " z = self.ph1(self.ln1(self.do1(self.bn1(x)))) # \n", " return z\n", " \n", "class MyModel(nn.Module):\n", " def __init__(self, in_features, out_features):\n", " super(MyModel, self).__init__()\n", " # self.out_features = out_features\n", " self.mymodules = nn.ModuleList([MyOneModel(in_features, 1) for _ in range(out_features)])\n", " # self.parameters = nn.ParameterList([f.parameters for f in self.mymodules])\n", " \n", " def forward(self, x):\n", " z = torch.cat([f(x) for f in self.mymodules], axis=1)\n", " # print(z.size(), self.mymodules[0](x).size())\n", " return z" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }