Нейросети: создание и оптимизация будущего. Джеймс Девис

Читать онлайн.
Название Нейросети: создание и оптимизация будущего
Автор произведения Джеймс Девис
Жанр
Серия
Издательство
Год выпуска 2025
isbn



Скачать книгу

= self.layer1(x)

      x = self.bn1(x) # Применение Batch Normalization

      x = torch.relu(x) # Активация ReLU

      x = self.layer2(x)

      x = self.bn2(x) # Применение Batch Normalization

      x = torch.relu(x) # Активация ReLU

      x = self.layer3(x) # Применение финального линейного слоя

      return x

      # Пример данных и оптимизации

      model = SimpleNet()

      criterion = nn.CrossEntropyLoss() # Функция потерь для классификации

      optimizer = optim.Adam(model.parameters(), lr=0.001) # Оптимизатор Adam

      # Пример одного шага обучения

      inputs = torch.randn(64, 784) # Входной батч из 64 изображений размером 28x28 (784 = 28*28)

      labels = torch.randint(0, 10, (64,)) # Случайные метки классов для примера

      # Обнуление градиентов

      optimizer.zero_grad()

      # Прямой проход

      outputs = model(inputs)

      loss = criterion(outputs, labels)

      # Обратное распространение и обновление весов

      loss.backward()

      optimizer.step()

      print("Значение функции потерь:", loss.item())

      ```

      Объяснение работы Batch Normalization в коде

      – `nn.BatchNorm1d(256)` и `nn.BatchNorm1d(128)` добавлены после каждого линейного слоя. Они нормализуют выходы, уменьшая разброс значений и стабилизируя обратное распространение.

      – Batch Normalization вычитает среднее и делит на стандартное отклонение для каждого батча, обеспечивая равномерное распределение значений. После этого применяются параметры смещения и масштабирования, которые обучаются вместе с остальными параметрами сети.

      – Использование нормализации особенно полезно в случае глубоких сетей, так как она позволяет сократить время обучения и уменьшить зависимость от инициализации весов.

      Инициализация весов с использованием методов Xavier и He помогает улучшить процесс обучения нейронных сетей, особенно глубоких, за счет предотвращения проблем с затуханием или взрывом градиентов. В PyTorch это можно сделать с помощью функций из модуля `torch.nn.init`.

      – Инициализация Xavier (также известная как Glorot) работает лучше всего с активациями, которые сохраняют значения в пределах (-1, 1), как, например, сигмоид или гиперболический тангенс.

      – Инициализация He (также известная как Kaiming) лучше подходит для активаций ReLU и производных от нее функций, так как она помогает компенсировать тенденцию ReLU обнулять градиенты.

      Ниже приведен пример нейронной сети, где используется оба подхода к инициализации:

      ```python

      import torch

      import torch.nn as nn

      import torch.optim as optim

      # Определяем класс нейронной сети

      class SimpleNet(nn.Module):

      def __init__(self):

      super(SimpleNet, self).__init__()

      # Определяем слои сети

      self.layer1 = nn.Linear(784, 256) # Первый полносвязный слой

      self.layer2 = nn.Linear(256, 128) # Второй полносвязный слой

      self.layer3 = nn.Linear(128, 10) # Выходной слой (например, для 10 классов)

      # Применяем инициализацию весов

      self._initialize_weights()

      def _initialize_weights(self):

      # Инициализация первого и второго слоя методом He для ReLU активации

      nn.init.kaiming_normal_(self.layer1.weight, nonlinearity='relu')

      nn.init.kaiming_normal_(self.layer2.weight, nonlinearity='relu')

      # Инициализация выходного слоя методом Xavier, подходящим для softmax или других линейных активаций

      nn.init.xavier_normal_(self.layer3.weight)

      def forward(self, x):

      x = torch.relu(self.layer1(x)) # Применение ReLU после первого слоя

      x = torch.relu(self.layer2(x)) # Применение ReLU после второго слоя

      x = self.layer3(x) # Прямой выход для классификации (например, softmax на последнем слое)

      return x

      # Пример данных и оптимизации

      model = SimpleNet()

      criterion