Переход с TensorFlow
Недавно я читал несколько научных статей о машинном обучении. Я обнаружил, что во многих исследованиях, которые я читал, модели написаны в PyTorch.
Что такое ПиТорч? Почему PyTorch так важен?
PyTorch — это платформа машинного обучения, разработанная Meta. Это основной конкурент TensorFlow.
В результате небольшого дальнейшего исследования я обнаружил, что многие исследования ML/AI проводятся с использованием PyTorch, но компании предпочитают использовать Tensorflow для создания производственных моделей. Таким образом, если вы хотите иметь возможность понимать множество исследовательских работ по машинному обучению, знание основ PyTorch является обязательным.
В настоящее время я знаю только Tensorflow. В этой статье я расскажу о PyTorch-эквивалентах некоторых базовых компонентов Tensorflow и объясню, как создать базовую модель.
Обзор PyTorch
PyTorch использует объектно-ориентированный подход к машинному обучению, что делает его относительно простым для программистов (и исследователей).
Два основных компонента машинного обучения, модель и набор данных, создаются путем подкласса модуля PyTorch и класса набора данных (находятся в пакетах PyTorch.nn и torch.utils.data соответственно). Затем пользователь должен реализовать несколько методов, чтобы все заработало.
Создание простой модели в PyTorch
Внутри PyTorch.nn есть множество объектов-«модулей», которые могут показаться знакомыми пользователю Tensorflow. Вот как сделать базовую модель:
import torch from torch import nn class NeuralNetwork(nn.Module): def __init__(self): super().__init__() self.flatten = nn.Flatten() # equivalent of keras.layers.Flatten self.layers = nn.Sequential( nn.Linear(28*28, 512), # input shape, output shape nn.ReLU(), # you have to add the activation function after nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10) ) def forward(self, x): # when you call a layer on an input, it will execute its # operations. Below, this will flatten x. x = self.flatten(x) logits = self.layers(x) return logits model = NeuralNetwork()
В модуле keras.layers Tensorflow есть много эквивалентных компонентов для слоев. Эти компоненты, такие как Linear(), ReLU() и Flatten(), также являются модулями.
Когда модуль вызывается с некоторыми входными данными, его метод forward() будет работать с входными данными. Таким образом, мы должны переопределить метод forward() при создании нашей нейронной сети, указав, как данные должны проходить через нее.
Обучение модели
В отличие от Tensorflow, мы не можем просто скомпилировать и обучить модель с помощью встроенных методов. Мы должны написать обучающий цикл. Мы также должны инициализировать функцию потерь и оптимизатор.
Не беспокойтесь о загрузчиках данных, мы обсудим это позже.
Каждый шаг обучения довольно прост. Модель пройдет через все партии. Он будет распространяться вперед, делая прогнозы для пакетов, вычисляя функцию потерь для своих прогнозов и выполняя обратное распространение для обновления весов модели.
Основная идея, которую следует здесь отметить, заключается в том, как выполняется обратное распространение в PyTorch. Обратное распространение в PyTorch требует от нас понимания того, как на самом деле работает обратное распространение.
Нашему оптимизатору дается ссылка на параметры нашей модели. Для каждого параметра отслеживается значение и атрибут «grad», представляющий градиент.
Мы устанавливаем градиенты равными нулю, используя метод оптимизатора zero_grad(). Это гарантирует, что ранее рассчитанные градиенты не будут использоваться на текущем этапе обратного распространения. Затем мы вызываем метод потерь back() для расчета новых градиентов (принимая во внимание расчеты, связанные с потерями, такие как импульс), и запускаем метод оптимизатора step() для обновления всех весов модели с их градиентами.
В целом, этот тренировочный цикл довольно интуитивно понятен, и кажется, что его довольно легко модифицировать.
Создание набора данных
В PyTorch мы можем создать набор данных, создав подкласс класса Dataset.
import torch from torch.utils.data import dataset import os import pandas as pd class ImageDataset(Dataset): def __init__(self, ..., transform=None, target_transform=None): # initialize necessary variables ... self.transform = transform self.target_transform = target_transform def __len__(self): ... def __getitem__(self, idx): # read the image from filesystem or wherever ... if self.transform: x = self.transform(x) if self.target_transform: y = self.target_transform(y) return x, y
Основная идея заключается в том, что нам нужно переопределить три метода: инициализатор (очевидно), метод длины и метод getitem, чтобы мы могли получить доступ к элементам по индексу.
Большинство наборов данных включают атрибуты преобразования и target_transform, которые представляют собой две функции, применяемые к объектам и меткам соответственно при возврате данных.
Эта структура легко настраивается. Например, если нам нужно несколько источников ввода, мы можем заставить метод __getitem__ возвращать кортеж длины 3, представляющий два источника ввода и цель. Затем мы можем изменить класс нашей модели, чтобы отразить это. Вот что я имею в виду, когда говорю, что разработчикам легко освоить PyTorch.
Загрузчики данных
Наконец, PyTorch предоставляет класс DataLoader, который оборачивает набор данных в итерируемый объект, чтобы вы могли использовать его в цикле обучения. Помимо прочего, загрузчик данных помогает пакетировать входные данные.
Все, что вам нужно сделать, это инициализировать его.
from torch.utils.data import DataLoader dl = DataLoader(dataset, batch_size=64, shuffle=True)
Заключение
Надеюсь, это даст вам хорошее представление о том, как работает PyTorch, и либо поможет вам начать изучение фреймворка, либо немного лучше поймет модели, которые вы видите в Интернете!