6.6. Ввод-вывод файлов¶
До сих пор мы обсуждали, как обрабатывать данные и как строить, обучать и тестировать модели глубокого обучения. Однако в какой-то момент мы, надеюсь, будем достаточно довольны полученными моделями, чтобы сохранить результаты для последующего использования в различных контекстах (возможно, даже для выполнения предсказаний при развертывании). Кроме того, при выполнении длительного процесса обучения хорошей практикой является периодическое сохранение промежуточных результатов (чекпоинтинг), чтобы убедиться, что мы не потеряем результаты нескольких дней вычислений в случае, если кто-то случайно выдернет шнур питания нашего сервера. Таким образом, пришло время научиться загружать и сохранять как отдельные векторы весов, так и целые модели. В этом разделе рассматриваются обе эти задачи.
import torch
from torch import nn
from torch.nn import functional as F
6.6.1. Загрузка и сохранение тензоров¶
Для отдельных тензоров мы можем напрямую вызывать функции load и
save для их чтения и записи соответственно. Обе функции требуют
указания имени, а функция save в качестве входного параметра
принимает переменную, которую необходимо сохранить.
x = torch.arange(4)
torch.save(x, 'x-file')
Теперь мы можем загрузить данные из сохранённого файла обратно в память.
x2 = torch.load('x-file')
x2
Мы можем сохранить список тензоров и загрузить их обратно в память.
y = torch.zeros(4)
torch.save([x, y],'x-files')
x2, y2 = torch.load('x-files')
(x2, y2)
Мы можем даже записывать и считывать словарь, сопоставляющий строки с тензорами. Это удобно, когда нужно прочитать или записать все веса модели.
mydict = {'x': x, 'y': y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
mydict2
6.6.2. Загрузка и сохранение параметров модели¶
Сохранение отдельных векторов весов (или других тензоров) полезно, но становится очень утомительным, если мы хотим сохранить (а затем загрузить) всю модель. Ведь у нас могут быть сотни групп параметров, разбросанных по всей сети. По этой причине фреймворк глубокого обучения предоставляет встроенные функции для загрузки и сохранения целых сетей. Важный момент заключается в том, что при этом сохраняются параметры модели, а не сама модель целиком. Например, если у нас есть многослойный перцептрон (MLP) из трёх слоёв, нам нужно отдельно задать архитектуру. Причина этого в том, что сами модели могут содержать произвольный код, поэтому их нельзя сериализовать так же естественно. Таким образом, чтобы восстановить модель, нам нужно сначала задать архитектуру в коде, а затем загрузить параметры с диска. Начнём с нашего знакомого MLP.
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.LazyLinear(256)
self.output = nn.LazyLinear(10)
def forward(self, x):
return self.output(F.relu(self.hidden(x)))
net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)
Далее мы сохраняем параметры модели в файл с именем “mlp.params”.
torch.save(net.state_dict(), 'mlp.params')
Чтобы восстановить модель, мы создаём копию исходной модели MLP. Вместо случайной инициализации параметров модели мы считываем параметры, сохранённые в файле, напрямую.
clone = MLP()
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()
Поскольку оба экземпляра имеют одинаковые параметры модели, результат
вычислений для одного и того же входного данных X должен совпадать.
Давайте проверим это.
Y_clone = clone(X)
Y_clone == Y
6.6.3. Итог¶
Функции save и load можно использовать для выполнения операций
ввода-вывода файлов для объектов-тензоров. Мы можем сохранять и
загружать полный набор параметров сети через словарь параметров.
Сохранение архитектуры должно выполняться в коде, а не в параметрах.
6.6.4. Упражнения¶
Даже если нет необходимости развертывать обученные модели на другом устройстве, какие практические преимущества даёт сохранение параметров модели?
Предположим, что мы хотим использовать лишь часть сети, чтобы включить её в сеть с другой архитектурой. Как бы вы поступили, например, чтобы использовать первые два слоя из предыдущей сети в новой?
Как вы будете сохранять архитектуру сети и её параметры? Какие ограничения вы бы наложили на архитектуру?