**Постановка** Мы создаем упрощенную версию нейронной сети, которая умеет классифицировать данные на несколько категорий сразу. * **Нейрон (`Neuron`):** Теперь это отдельный объект, хранящий свои уникальные веса и смещение (`bias`). Умеет вычислять активацию и корректировать веса методом градиентного спуска. * **Слой (`Layer`):** Содержит список объектов `Neuron`. Управляет передачей сигналов всем нейронам сразу. * **Тренер (`Trainer`):** Обучает слой, минимизируя среднюю ошибку по всем нейронам. **Задание** **Класс `Neuron`:** 1. Создайте класс `Neuron`. 2. В `__init__(self, inputs_count, learning_rate)` инициализируйте `weights` (список случайных значений, например 0.1) и `bias` (смещение, начните с 0.0). 3. Метод `predict(self, inputs)`: верните сумму произведений (входы * веса) + `bias`. 4. Метод `train(self, inputs, target)`: * Вычислите `prediction = self.predict(inputs)`. * Вычислите `error = target - prediction`. * Обновите веса: `w = w + (error * input * lr)`. * Обновите смещение: `bias = bias + (error * lr)`. **Класс `Layer`:** 1. Создайте класс `Layer`. 2. В `__init__(self, neurons_count, inputs_count, learning_rate)` создайте список `neurons`, заполнив его `neurons_count` объектами класса `Neuron`. 3. Метод `forward(self, inputs)`: возвращает список предсказаний каждого нейрона. 4. Метод `train_layer(self, inputs, targets)`: принимает список правильных ответов (для каждого нейрона свой). Проходит циклом по нейронам и вызывает у каждого метод `train` с соответствующим `target`. **Класс `Trainer`:** 1. Создайте класс `Trainer`. 2. Метод `fit(self, layer, dataset, epochs)`: * Внешний цикл `for epoch in range(epochs)`. * Внутренний цикл по датасету: берет `inputs` и список `targets`. * Вызывает `layer.train_layer(inputs, targets)`. * (Опционально) Каждую 10-ю эпоху выводить среднюю ошибку по слою. **Тесты:** 1. Создайте слой из 2 нейронов (каждый принимает 3 входа). 2. Создайте датасет: 3 примера, где каждый пример имеет 3 входа и 2 целевых значения. 3. Обучите слой в течение 200 эпох. 4. После обучения выведите результат предсказания для нового входа `[0.5, 0.2, 0.1]`.