Примите участие в 20-м дне Ноябрьского испытания обновлений и узнайте подробности события:Вызов последнего обновления 2021 г.
В предыдущем разделе говорилось о том, как настроить параметры инициализации.Практическое руководство по глубокому обучению 5.2. Инициализация параметров PyTorch — самородки (juejin.cn)
В этом разделе рассматривается, как настраивать слои.
Таким образом, вы можете подумать о том, каким был предыдущий этаж. Напримерnn.Linear
,nn.ReLU
Ждать. Их роль заключается в том, чтобы выступать в качестве слоя обработки. Разница между ними заключается в том, что у первого есть параметры, а у второго нет списка параметров. Теперь давайте также реализуем некоторые операции со слоями со списками параметров и без них.
import torch
import torch.nn.functional as F
from torch import nn
Слой без параметров
class CenteredLayer(nn.Module):
def __init__(self):
super().__init__()
def forward(self, X):
return X - X.mean()
Нам также нужно только определить прямое распространение. Функция этого самостоятельно построенного слоя состоит в том, чтобы вычесть его среднее значение из каждого количества признаков.
layer = CenteredLayer()
X = torch.arange(5)*0.1
print(layer(X))
>>
tensor([-0.2000, -0.1000, 0.0000, 0.1000, 0.2000])
После тестирования мы видим, что этот слой полностью эффективен.
Что, если вы поместите это в сложную модель.
net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
Y = torch.rand(10, 8)
print(net(Y).mean().data)
>>
tensor(7.8231e-09)
Ну, эта модель на самом деле не такая уж сложная, в ней всего два слоя. Первый — линейный слой. Второй — наш пользовательский слой.
Сгенерируйте случайный набор тестовых данных Y. Затем используйте построенную нами сеть для выполнения внешних вычислений и выведите среднее значение ее результатов.
Неудивительно, что результат должен быть 0. Хотя здесь не отображается 0. Это связано с точностью хранения чисел с плавающей запятой, и вы, конечно, можете думать об этом чрезвычайно маленьком числе примерно как о 0.
Что касается того, почему не получается результат, то это математическая проблема, и вы можете решить ее, самостоятельно перечислив несколько чисел.
слой с параметрами
class MyLinear(nn.Module):
def __init__(self, in_units, units):
super().__init__()
self.weight = nn.Parameter(torch.ones(in_units, units))
self.bias = nn.Parameter(torch.zeros(units,))
def forward(self, X):
linear = torch.matmul(X, self.weight.data) + self.bias.data
return F.relu(linear)
Этот уровень аренды является пользовательской реализацией полностью связанного уровня. Параметры в этом слое должны использовать веса и смещения и, наконец, возвращаться к функции активации ReLU после вычисления.
linear = MyLinear(5, 3)
print(linear.weight.data)
>>
tensor([[ 1.0599, 0.3885, 1.2025],
[-1.8313, 0.2097, -1.6529],
[ 1.4119, 0.2675, -0.4148],
[ 0.2596, -0.0319, 1.9548],
[-1.2874, 1.0776, 0.5804]])
Взгляните на вывод его веса, он действительно может генерировать весовую матрицу 5×3.
X = torch.rand(2, 5)
linear(X)
>>
tensor([[2.3819, 2.3819, 2.3819],
[1.8295, 1.8295, 1.8295]])
Результаты однослойного теста также в порядке.
net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))
net(torch.rand(2, 64))
>>
tensor([[0.4589],
[0.0000]])
Выложить в сеть оказалось не проблема.
Теперь позвольте мне привести код сравнения, то есть как слой, который мы написали, и слой, написанный pytorch, могут выполнять одну и ту же функцию.
net1 = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))
net2 = nn.Sequential(nn.Linear(64,8),
nn.ReLU(),
nn.Linear(8,1),
nn.ReLU())
def init(m):
if type(m)==nn.Linear:
nn.init.ones_(m.weight)
nn.init.zeros_(m.bias)
net2.apply(init)
Y = torch.rand(4, 64)
print(net1(Y).data)
print(net2(Y).data)
>>
tensor([[270.5055],
[253.7892],
[238.7834],
[258.4998]])
tensor([[270.5055],
[253.7892],
[238.7834],
[258.4998]])
Итак, на первый взгляд, два результата не совсем одинаковы.
По сравнению с реализацией, поставляемой с pytorch, вам не нужно писать процесс взвешивания или добавлять слой ReLU.
Это выглядит просто, но на практике не рекомендуется реализовывать функции, которые уже есть в pytorch, самостоятельно. Потому что эффективнее использовать чужие методы.
-
Подробнее о серии «Практическое глубокое обучение» см. здесь:Колонка «Практическое глубокое обучение» (juejin.cn)
-
Примечания Адрес Github:DeepLearningNotes/d2l(github.com)
Все еще в процессе обновления......