Assistant: 
User: Выполни задание, предполагая, что пишешь Jupyter Notebook и придерживайся хорошего стиля его написания: пиши красивые пояснения в markdown, логично разделяй код на ячейки, выводи полученные результаты как объекты или через print. Использй заголовки и другие способы выделения текста в markdown. Повествование имеет логику, вступление, заключение. Отвечай в формате json по заданному примеру: {1: ["markdown", "В этом ноутбуке будем использовать формулу $y_i=a_0 + a_1 + \epsilon_i$."], 2: ["code", "import numpy as np"], 3: ["markdown", "Заключение..."]}. Пиши на русском, если задание на русском. Начинай сразу с написания ячеек. Не останавливай генерацию, пока не выполнишь всё задание. Задание: Исходный код:
{0: ['code', 'import torch'], 1: ['markdown', '## 2.1 Создание нейронов и полносвязных слоев'], 2: ['markdown', '2.1.1. Используя операции над матрицами и векторами из библиотеки `torch`, реализовать нейрон с заданными весами `weights` и `bias`. Прогнать вектор `inputs` через нейрон и вывести результат. '], 3: ['code', 'class Neuron:\n  def __init__(self, weights, bias):\n    # <создать атрибуты объекта weights и bias>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику нейрона>\n'], 4: ['code', 'inputs = torch.tensor([1.0, 2.0, 3.0, 4.0])\nweights = torch.tensor([-0.2, 0.3, -0.5, 0.7])\nbias = 3.14'], 5: ['markdown', '2.1.2 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать полносвязный слой с заданными весами `weights` и `biases`. Прогнать вектор `inputs` через слой и вывести результат. '], 6: ['code', 'class Linear:\n  def __init__(self, weights, biases):\n    # <создать атрибуты объекта weights и biases>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику слоя>'], 7: ['code', 'inputs = torch.tensor([1.0, 2.0, 3.0, 4.0])\nweights = torch.tensor([[-0.2, 0.3, -0.5, 0.7],\n                        [0.5, -0.91, 0.26, -0.5],\n                        [-0.26, -0.27, 0.17, 0.87]]).T\n\nbiases = torch.tensor([3.14, 2.71, 7.2])'], 8: ['markdown', '2.1.3 Реализовать полносвязный слой из __2.1.2__ таким образом, чтобы он мог принимать на вход матрицу (батч) с данными. Продемонстрировать работу.\nРезультатом прогона сквозь слой должна быть матрица размера `batch_size` x `n_neurons`.\n'], 9: ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n                       [2, 5, -1, 2], \n                       [-1.5, 2.7, 3.3, -0.8]])'], 10: ['markdown', '2.1.4 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать полносвязный слой из `n_neurons` нейронов с `n_features` весами у каждого нейрона (инициализируются из стандартного нормального распределения). Прогнать вектор `inputs` через слой и вывести результат. Результатом прогона сквозь слой должна быть матрица размера `batch_size` x `n_neurons`.'], 11: ['code', 'class Linear:\n  def __init__(self, n_features, n_neurons):\n    # <создать атрибуты объекта weights и biases>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику слоя>'], 12: ['markdown', '2.1.5 Используя решение из __2.1.4__, создать 2 полносвязных слоя и пропустить матрицу `inputs` последовательно через эти два слоя. Количество нейронов в первом слое выбрать произвольно, количество нейронов во втором слое выбрать так, чтобы результатом прогона являлась матрица (3x7). '], 13: ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n                       [2, 5, -1, 2], \n                       [-1.5, 2.7, 3.3, -0.8]])'], 14: ['markdown', '## 2.2 Создание функций активации'], 15: ['markdown', '2.2.1 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать функцию активации ReLU:\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/f4353f4e3e484130504049599d2e7b040793e1eb)\n\nСоздать матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверить работоспособность функции активации.'], 16: ['code', 'class ReLU:\n  def forward(self, inputs):\n    # <реализовать логику ReLU>\n    pass'], 17: ['markdown', '2.2.2 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать функцию активации softmax:\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6d7500d980c313da83e4117da701bf7c8f1982f5)\n\nСоздать матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверить работоспособность функции активации. Строки матрицы трактовать как выходы линейного слоя некоторого классификатора для 4 различных примеров.'], 18: ['code', 'class Softmax:\n  def forward(self, inputs):\n    # <реализовать логику Softmax>\n    pass'], 19: ['markdown', '2.2.3 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать функцию активации ELU:\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/eb23becd37c3602c4838e53f532163279192e4fd)\n\nСоздать матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверить работоспособность функции активации.'], 20: ['code', 'class ELU:\n  def __init__(self, alpha):\n    # <создать атрибут объекта alpha>\n    pass\n\n  def forward(self, inputs):\n    # <реализовать логику ReLU>\n    pass'], 21: ['markdown', '## 2.3 Создание функции потерь'], 22: ['markdown', '2.3.1 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать функцию потерь MSE:\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/e258221518869aa1c6561bb75b99476c4734108e)\n\nСоздать полносвязный слой с 1 нейроном, прогнать через него батч `inputs` и посчитать значение MSE, трактуя вектор `y` как вектор правильных ответов.'], 23: ['code', 'class MSELoss:\n  def forward(self, y_pred, y_true):\n    return # <реализовать логику MSE>'], 24: ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n                       [2, 5, -1, 2], \n                       [-1.5, 2.7, 3.3, -0.8]])\n\ny = torch.tensor([2, 3, 4])'], 25: ['markdown', '2.3.2 Используя операции над матрицами и векторами из библиотеки `torch`, реализовать функцию потерь Categorical Cross-Entropy:\n\n<img src="https://i.ibb.co/93gy1dN/Screenshot-9.png" width="200">\n\nСоздать полносвязный слой с 3 нейронами и прогнать через него батч `inputs`. Полученный результат пропустить через функцию активации softmax. Посчитать значение CCE, трактуя вектор `y` как вектор правильных ответов.'], 26: ['code', 'class CategoricalCrossentropyLoss:\n  def forward(self, y_pred, y_true):\n    # <реализовать логику CCE>\n    pass'], 27: ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n                        [2, 5, -1, 2], \n                        [-1.5, 2.7, 3.3, -0.8]])\ny = torch.tensor([1, 0, 0])'], 28: ['markdown', '2.3.3 Модифицировать 2.3.1, добавив L2-регуляризацию.\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/d92ca2429275bfdc0474523babbafe014ca8b580)\n'], 29: ['code', 'class MSELossL2:\n  def __init__(self, lambda_):\n    # <создать атрибут объекта alpha>\n    pass\n\n  def data_loss(self, y_pred, y_true):\n    # <подсчет первого слагаемого из формулы>\n    pass\n\n  def reg_loss(self, layer):\n    # используйте атрибуты объекта layer, в которых хранятся веса слоя\n    # <подсчет второго слагаемого из формулы>\n    pass\n\n  def forward(self, y_pred, y_true):\n    return self.data_loss(y_pred, y_true) + self.reg_loss(y_pred, y_true)'], 30: ['markdown', '## 2.4 Обратное распространение ошибки'], 31: ['markdown', '2.4.1 Используя один нейрон и SGD (1 пример за шаг), решите задачу регрессии'], 32: ['code', 'from sklearn.datasets import make_regression\n\nX, y, coef = make_regression(n_features=4, n_informative=4, coef=True, bias=0.5)\nX = # <преобразуйте массивы numpy в тензоры torch с типом torch.float32\ny = # <преобразуйте массивы numpy в тензоры torch с типом torch.float32'], 33: ['markdown', '[Граф вычислений для этой задачи](https://i.ibb.co/2dhDxZx/photo-2021-02-15-17-18-04.jpg)'], 34: ['markdown', '2.4.1.1 Реализуйте класс `SquaredLoss`\n'], 35: ['code', 'class SquaredLoss:\n  def forward(self, y_pred, y_true):\n    return # <реализовать логику MSE>\n\n  def backward(self, y_pred, y_true):\n    self.dinput = # df/dc\n'], 36: ['markdown', '2.4.1.2. Модифицируйте класс `Neuron` из __2.1.1__:\n\n  1) Сделайте так, чтобы веса нейрона инициализировались из стандартного нормального распределения\n\n  2) Реализуйте расчет градиента относительно весов `weights` и `bias`'], 37: ['code', 'class Neuron:\n  def __init__(self, n_inputs):\n    # <создать атрибуты объекта weights и bias>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику нейрона>\n  \n  def backward(self, dvalue):\n    # dvalue - значение производной, которое приходит нейрону от следующего слоя сети\n    # в данном случае это будет значение df/dc (созданное методом backwards у объекта MSELoss)\n    self.dweights = # df/dW\n    self.dinput =  # df/wX\n    self.dbias = # df/db\n'], 38: ['markdown', '2.4.1.3 Допишите цикл для настройки весов нейрона\n\n[SGD](https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA)\n\n![](https://wikimedia.org/api/rest_v1/media/math/render/svg/dda3670f8a8996a0d3bf80856bb4a166cc8db6d4)'], 39: ['code', 'n_inputs = # <размерность элемента выборки >\nlearning_rate = 0.1 #  скорость обучения\nn_epoch = 100 #  количество эпох\n\nneuron = Neuron(n_inputs)\nloss = MSELoss()\n\nlosses = []\nfor epoch in range(100):\n  for x_example, y_example in zip(X, y):\n    # forward pass\n    y_pred = # <прогон через нейрон>\n    curr_loss = # <прогон через функцию потерь>\n    losses.append(curr_loss)\n\n    # backprop\n    # <вызов методов backward>\n    # обратите внимание на последовательность вызовов: от конца к началу\n\n    # <шаг оптимизации для весов (weights и bias) нейрона>'], 40: ['markdown', '2.4.2 Решите задачу 2.4.1, используя пакетный градиентный спуск'], 41: ['markdown', 'Вычисления для этой задачи: \n[1](https://i.ibb.co/rmtQT6P/photo-2021-02-15-18-00-43.jpg)\n[2](https://i.ibb.co/NmCFVnQ/photo-2021-02-15-18-01-17.jpg)'], 42: ['markdown', '2.4.1.1 Модифицируйте класс `MSELoss` из __2.3.1__, реализовав расчет производной относительно предыдущего слоя с учетом того, что теперь работа ведется с батчами, а не с индивидуальными примерами\n '], 43: ['code', 'class MSELoss:\n  def forward(self, y_pred, y_true):\n    return # <реализовать логику MSE>\n\n  def backward(self, y_pred, y_true):\n    self.dinput = # df/dy^\n'], 44: ['markdown', '2.4.2.2. Модифицируйте класс `Neuron` из __2.4.1.2__:\n\n  1) Реализуйте метод `forward` таким образом, чтобы он мог принимать на вход матрицу (батч) с данными. \n\n  2) Реализуйте расчет градиента относительно весов `weights` и `bias` с учетом того, что теперь работа ведется с батчами, а не с индивидуальными примерами'], 45: ['code', 'class Neuron:\n  def __init__(self, n_inputs):\n    # <создать атрибуты объекта weights и bias>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику нейрона>\n  \n  def backward(self, dvalue):\n    # dvalue - значение градиента, которое приходит нейрону от следующего слоя сети\n    # в данном случае это будет градиент L по y^ (созданный методом backwards у объекта MSELoss)\n    self.dweights = # df/dW\n    self.dbias = # df/db\n'], 46: ['markdown', '2.4.2.3 Допишите цикл для настройки весов нейрона'], 47: ['code', 'n_inputs = # <размерность элемента выборки >\nlearning_rate = 0.1 #  скорость обучения\nn_epoch = 100 #  количество эпох\n\nneuron = Neuron(n_inputs)\nloss = MSELoss()\n\n\nfor epoch in range(100):\n    # forward pass\n    y_pred = # <прогон через нейрон>\n    curr_loss = # <прогон через функцию потерь>\n    losses.append(curr_loss)\n\n    # backprop\n    # <вызов методов backward>\n    # обратите внимание на последовательность вызовов: от конца к началу\n\n    # <шаг оптимизации для весов (weights и bias) нейрона>'], 48: ['markdown', '2.4.3  Используя один полносвязный слой и  пакетный градиетный спуск, решите задачу регрессии из __2.4.1__'], 49: ['markdown', '2.4.3.1 Модифицируйте класс `Linear` из __2.1.4__. ([вычисление градиентов](https://i.ibb.co/kgVR6m6/photo-2021-02-15-21-30-28.jpg))'], 50: ['code', 'class Linear:\n  def __init__(self, n_features, n_neurons):\n    # <создать атрибуты объекта weights и biases>\n    pass\n  \n  def forward(self, inputs):\n    return # <реализовать логику слоя>\n\n  def backward(self, dvalues):\n    self.dweights = # df/dW\n    self.dbiases = # df/db\n    self.dinputs = # df/dX'], 51: ['markdown', '2.4.3.2 Создайте слой с одним нейроном. Используя класс MSELoss из 2.4.2, убедитесь, что модель обучается'], 52: ['markdown', '2.4.4 Используя наработки из 2.4, создайте нейросеть и решите задачу регрессии.\n\nПредлагаемая архитектура: \n1. Полносвязный слой с 10 нейронами\n2. Активация ReLU\n3. Полносвязный слой с 1 нейроном'], 53: ['code', 'X = torch.linspace(-1, 1, 100).view(-1, 1)\ny = X.pow(2) + 0.2 * torch.rand(X.size()) '], 54: ['code', 'class Activation_ReLU:\n  def forward(self, inputs):\n    self.inputs = inputs\n    self.output = inputs.clip(min=0)\n    return self.output\n  \n  def backward(self, dvalues):\n    self.dinputs = dvalues.clone()\n    self.dinputs[self.inputs <= 0] = 0'], 55: ['code', "# создание компонентов сети\n# fc1 = \n# relu1 = \n# fc2 = \n\nloss = MSELoss()\nlr = 0.02\n\nys = []\nfor epoch in range(2001):\n  # <forward pass>\n  # fc1 > relu1 > fc2 > loss\n\n  data_loss = # <прогон через функцию потерь>\n\n  if epoch % 200 == 0:\n    print(f'epoch {epoch} mean loss {data_loss}')\n    ys.append(out)\n  \n  # <backprop> \n  # loss > fc2 > relu1 > fc1\n\n  # <шаг оптимизации для fc1>\n\n  # <шаг оптимизации для fc2>\n"], 56: ['code', 'import matplotlib.pyplot as plt\n\nfig, axs = plt.subplots(len(ys), 1, figsize=(10, 40))\nfor ax, y_ in zip(axs, ys):\n  ax.scatter(X.numpy(), y.numpy(), color = "orange")\n  ax.plot(X.numpy(), y_.numpy(), \'g-\', lw=3)\n  ax.set_xlim(-1.05, 1.5)\n  ax.set_ylim(-0.25, 1.25)']}Выполни задания из ноутбука. Строго следуй заданию, не меняй его. Смотри, соотносится ли текущий код с предыдущим.Продолжи генерацию предыдущего ответа, опираясь на те же требования. Отвечай в форме json со следующего по порядку номера ячейки в прерыдущем ответе, не переписывая код предыдущих ячеек!. Не закрывай скобку, пока все задания не были выполнены!{'1': ['markdown', 'В этом ноутбуке мы будем создавать нейронные сети с использованием библиотеки `torch`. Мы начнем с создания нейронов и полносвязных слоев, а затем реализуем функции активации и функции потерь.'], '2': ['code', 'import torch'], '3': ['markdown', '## 2.1 Создание нейронов и полносвязных слоев'], '4': ['markdown', '### 2.1.1. Реализация нейрона'], '5': ['markdown', 'Используя операции над матрицами и векторами из библиотеки `torch`, реализуем нейрон с заданными весами `weights` и `bias`. Прогоняем вектор `inputs` через нейрон и выводим результат.'], '6': ['code', 'class Neuron:\n    def __init__(self, weights, bias):\n        self.weights = weights\n        self.bias = bias\n\n    def forward(self, inputs):\n        return torch.dot(inputs, self.weights) + self.bias'], '7': ['code', 'inputs = torch.tensor([1.0, 2.0, 3.0, 4.0])\nweights = torch.tensor([-0.2, 0.3, -0.5, 0.7])\nbias = 3.14\nneuron = Neuron(weights, bias)\noutput = neuron.forward(inputs)\nprint(output)'], '8': ['markdown', '### 2.1.2 Реализация полносвязного слоя'], '9': ['markdown', 'Теперь реализуем полносвязный слой с заданными весами `weights` и `biases`. Прогоняем вектор `inputs` через слой и выводим результат.'], '10': ['code', 'class Linear:\n    def __init__(self, weights, biases):\n        self.weights = weights\n        self.biases = biases\n\n    def forward(self, inputs):\n        return torch.matmul(inputs, self.weights) + self.biases'], '11': ['code', 'inputs = torch.tensor([1.0, 2.0, 3.0, 4.0])\nweights = torch.tensor([[-0.2, 0.3, -0.5, 0.7],\n [0.5, -0.91, 0.26, -0.5],\n [-0.26, -0.27, 0.17, 0.87]]).T\n\nbiases = torch.tensor([3.14, 2.71, 7.2])\nlinear_layer = Linear(weights, biases)\noutput = linear_layer.forward(inputs)\nprint(output)'], '12': ['markdown', '### 2.1.3 Реализация полносвязного слоя для батчей\n\nТеперь реализуем полносвязный слой таким образом, чтобы он мог принимать на вход матрицу (батч) с данными. Результатом прогона сквозь слой должна быть матрица размера `batch_size` x `n_neurons`.'], '13': ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n [2, 5, -1, 2], \n [-1.5, 2.7, 3.3, -0.8]])\nweights = torch.tensor([[-0.2, 0.3, -0.5, 0.7],\n [0.5, -0.91, 0.26, -0.5],\n [-0.26, -0.27, 0.17, 0.87]]).T\nbiases = torch.tensor([3.14, 2.71, 7.2])\nlinear_layer = Linear(weights, biases)\noutput = linear_layer.forward(inputs)\nprint(output)'], '14': ['markdown', '### 2.1.4 Реализация полносвязного слоя с инициализацией весов\n\nТеперь реализуем полносвязный слой из `n_neurons` нейронов с `n_features` весами у каждого нейрона, инициализируем их из стандартного нормального распределения.'], '15': ['markdown', 'Теперь прогоняем вектор `inputs` через слой и выводим результат. Результатом прогона сквозь слой должна быть матрица размера `batch_size` x `n_neurons`.'], '16': ['code', 'class Linear:\n    def __init__(self, n_features, n_neurons):\n        self.weights = torch.randn(n_features, n_neurons)\n        self.biases = torch.zeros(n_neurons)\n\n    def forward(self, inputs):\n        return torch.matmul(inputs, self.weights) + self.biases'], '17': ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n [2, 5, -1, 2], \n [-1.5, 2.7, 3.3, -0.8]])\nlinear_layer = Linear(n_features=4, n_neurons=3)\noutput = linear_layer.forward(inputs)\nprint(output)'], '18': ['markdown', '### 2.1.5 Создание двух полносвязных слоев\nТеперь создадим 2 полносвязных слоя и пропустим матрицу `inputs` последовательно через эти два слоя.'], '19': ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \n [2, 5, -1, 2], \n [-1.5, 2.7, 3.3, -0.8]])\nlinear_layer1 = Linear(n_features=4, n_neurons=5)\nlinear_layer2 = Linear(n_features=5, n_neurons=7)\noutput1 = linear_layer1.forward(inputs)\noutput2 = linear_layer2.forward(output1)\nprint(output2)'], '20': ['markdown', '## 2.2 Создание функций активации\nТеперь мы реализуем функции активации, которые будут использоваться в нашей нейронной сети.'], '21': ['markdown', '### 2.2.1 Реализация функции активации ReLU\nИспользуя операции над матрицами и векторами из библиотеки `torch`, реализуем функцию активации ReLU.'], '22': ['code', 'class ReLU:\n    def forward(self, inputs):\n        return torch.maximum(inputs, torch.tensor(0.0))'], '23': ['markdown', 'Теперь создадим матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверим работоспособность функции активации.'], '24': ['code', 'relu = ReLU()\ninputs = torch.randn(4, 3)\noutput = relu.forward(inputs)\nprint(output)'], '25': ['markdown', '### 2.2.2 Реализация функции активации softmax\nТеперь реализуем функцию активации softmax.'], '26': ['code', 'class Softmax:\n    def forward(self, inputs):\n        exp_values = torch.exp(inputs - torch.max(inputs, dim=1, keepdim=True).values)\n        return exp_values / torch.sum(exp_values, dim=1, keepdim=True)'], '27': ['markdown', 'Создадим матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверим работоспособность функции активации.'], '28': ['code', 'softmax = Softmax()\ninputs = torch.randn(4, 3)\noutput = softmax.forward(inputs)\nprint(output)'], '29': ['markdown', '### 2.2.3 Реализация функции активации ELU\nТеперь реализуем функцию активации ELU.'], '30': ['code', 'class ELU:\n    def __init__(self, alpha):\n        self.alpha = alpha\n\n    def forward(self, inputs):\n        return torch.where(inputs > 0, inputs, self.alpha * (torch.exp(inputs) - 1))'], '31': ['markdown', 'Создадим матрицу размера (4,3), заполненную числами из стандартного нормального распределения, и проверим работоспособность функции активации.'], '32': ['code', 'elu = ELU(alpha=1.0)\ninputs = torch.randn(4, 3)\noutput = elu.forward(inputs)\nprint(output)'], '33': ['markdown', '## 2.3 Создание функции потерь'], '34': ['markdown', '### 2.3.1 Реализация функции потерь MSE\\nТеперь мы реализуем функцию потерь MSE (Mean Squared Error).'], '35': ['code', 'class MSELoss:\\n    def forward(self, y_pred, y_true):\\n        return torch.mean((y_pred - y_true) ** 2)'], '36': ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \\n [2, 5, -1, 2], \\n [-1.5, 2.7, 3.3, -0.8]])\\n\\ny = torch.tensor([2, 3, 4])\\nlinear_layer = Linear(n_features=4, n_neurons=1)\\ny_pred = linear_layer.forward(inputs)\\nloss = MSELoss()\\nprint(loss.forward(y_pred=y_pred, y_true=y))'], '37': ['markdown', '### 2.3.2 Реализация функции потерь Categorical Cross-Entropy\\nТеперь мы реализуем функцию потерь Categorical Cross-Entropy.'], '38': ['code', 'class CategoricalCrossentropyLoss:\\n    def forward(self, y_pred, y_true):\\n        return -torch.sum(y_true * torch.log(y_pred + 1e-15)) / y_true.size(0)'], '39': ['code', 'inputs = torch.tensor([[1, 2, 3, 2.5], \\n [2, 5, -1, 2], \\n [-1.5, 2.7, 3.3, -0.8]])\\ny = torch.tensor([1, 0, 0])\\nlinear_layer = Linear(n_features=4, n_neurons=3)\\ny_pred = linear_layer.forward(inputs)\\ny_pred_softmax = softmax.forward(y_pred)\\nloss = CategoricalCrossentropyLoss()\\nprint(loss.forward(y_pred=softmax_output, y_true=y))'], '40': ['markdown', '### 2.3.3 Модификация функции потерь MSE с L2-регуляризацией\\nТеперь мы модифицируем функцию потерь MSE, добавив L2-регуляризацию.'], '41': ['code', 'class MSELossL2:\\n    def __init__(self, lambda_):\\n        self.lambda_ = lambda_\\n\\n    def data_loss(self, y_pred, y_true):\\n        return torch.mean((y_pred - y_true) ** 2)\\n\\n    def reg_loss(self, layer):\\n        return self.lambda_ * torch.sum(layer.weights ** 2)\\n\\n    def forward(self, y_pred, y_true, layer):\\n        return self.data_loss(y_pred, y_true) + self.reg_loss(layer)'], '42': ['markdown', '## 2.4 Обратное распространение ошибки\\nТеперь мы реализуем обратное распространение ошибки для нашей нейронной сети.'], '43': ['markdown', '### 2.4.1 Используя один нейрон и SGD (1 пример за шаг), решите задачу регрессии\\nМы будем использовать стохастический градиентный спуск для обучения нейрона.'], '44': ['code', 'from sklearn.datasets import make_regression\\n\\nX, y, coef = make_regression(n_features=4, n_informative=4, coef=True, bias=0.5)\\nX = torch.tensor(X, dtype=torch.float32)\\ny = torch.tensor(y, dtype=torch.float32)'], '45': ['markdown', '[Граф вычислений для этой задачи](https://i.ibb.co/2dhDxZx/photo-2021-02-15-17-18-04.jpg)'], '46': ['markdown', '### 2.4.1.1 Реализуйте класс `SquaredLoss`\nТеперь мы реализуем класс для вычисления потерь.'], '47': ['code', 'class SquaredLoss:\n    def forward(self, y_pred, y_true):\n        return torch.mean((y_pred - y_true) ** 2)\n\n    def backward(self, y_pred, y_true):\n        self.dinput = 2 * (y_pred - y_true) / y_true.numel()'], '48': ['markdown', '### 2.4.1.2 Модифицируйте класс `Neuron`\nТеперь мы модифицируем класс `Neuron`, чтобы веса нейрона инициализировались из стандартного нормального распределения и реализуем расчет градиента.'], '49': ['code', 'class Neuron:\n    def __init__(self, n_inputs):\n        self.weights = torch.randn(n_inputs)  # Инициализация весов\n        self.bias = torch.randn(1)  # Инициализация смещения\n\n    def forward(self, inputs):\n        return torch.dot(inputs, self.weights) + self.bias\n\n    def backward(self, dvalue):\n        self.dweights = dvalue * self.inputs\n        self.dbias = dvalue\n        self.dinput = dvalue * self.weights'], '50': ['markdown', '### 2.4.1.3 Допишите цикл для настройки весов нейрона\nТеперь мы добавим цикл для настройки весов нейрона с использованием стохастического градиентного спуска.'], '51': ['markdown', 'Теперь мы добавим цикл для настройки весов нейрона с использованием стохастического градиентного спуска.'], '52': ['code', 'n_inputs = 4\nlearning_rate = 0.1  # скорость обучения\nn_epoch = 100  # количество эпох\n\nneuron = Neuron(n_inputs)\nloss = SquaredLoss()\n\nlosses = []\nfor epoch in range(n_epoch):\n    for x_example, y_example in zip(X, y):\n        # forward pass\n        y_pred = neuron.forward(x_example)\n        curr_loss = loss.forward(y_pred, y_example)\n        losses.append(curr_loss)\n\n        # backprop\n        dvalue = loss.backward(y_pred, y_example)\n        neuron.backward(dvalue)\n        neuron.weights -= learning_rate * neuron.dweights\n        neuron.bias -= learning_rate * neuron.dbias'], '53': ['markdown', '### 2.4.2 Решите задачу 2.4.1, используя пакетный градиентный спуск'], '54': ['markdown', 'Теперь мы будем использовать пакетный градиентный спуск для обучения нейрона.'], '55': ['code', 'n_inputs = 4\nlearning_rate = 0.1  # скорость обучения\nn_epoch = 100  # количество эпох\n\nneuron = Neuron(n_inputs)\nloss = SquaredLoss()\n\nlosses = []\nfor epoch in range(n_epoch):\n    # forward pass\n    y_pred = neuron.forward(X)\n    curr_loss = loss.forward(y_pred, y)\n    losses.append(curr_loss)\n\n    # backprop\n    dvalue = loss.backward(y_pred, y)\n    neuron.backward(dvalue)\n    neuron.weights -= learning_rate * neuron.dweights.mean(dim=0)\n    neuron.bias -= learning_rate * neuron.dbias.mean()'], '56': ['markdown', '### 2.4.3 Используя один полносвязный слой и пакетный градиентный спуск, решите задачу регрессии из __2.4.1__'], '57': ['markdown', 'Теперь мы будем использовать полносвязный слой для решения задачи регрессии.'], '58': ['code', 'linear_layer = Linear(n_features=4, n_neurons=1)\ny_pred = linear_layer.forward(X)\nloss = SquaredLoss()\nprint(loss.forward(y_pred, y, y_pred))'], '59': ['markdown', '### 2.4.3.1 Модифицируйте класс `Linear` из __2.1.4__.'], '60': ['code', 'class Linear:\n    def __init__(self, n_features, n_neurons):\n        self.weights = torch.randn(n_features, n_neurons)\n        self.biases = torch.zeros(n_neurons)\n\n    def forward(self, inputs):\n        return torch.matmul(inputs, self.weights) + self.biases\n\n    def backward(self, dvalues):\n        self.dweights = np.dot(inputs.T, dvalues)\n        self.dbiases = np.sum(dvalues, axis=0)'], '61': ['markdown', '### 2.4.3.2 Создайте слой с одним нейроном.'], '62': ['code', 'linear_layer = Linear(n_features=4, n_neurons=1)\ny_pred = linear_layer.forward(X)\nloss = SquaredLoss()\nprint(loss.forward(y_pred, y, y_pred))'], '63': ['markdown', '### 2.4.4 Используя наработки из 2.4, создайте нейросеть и решите задачу регрессии.'], '64': ['markdown', 'Предлагаемая архитектура: \n1. Полносвязный слой с 10 нейронами\n2. Активация ReLU\n3. Полносвязный слой с 1 нейроном'], '65': ['code', 'X = torch.linspace(-1, 1, 100).view(-1, 1)\ny = X.pow(2) + 0.2 * torch.rand(X.size())']}
Assistant: