Класс LazyLinear
Класс LazyLinear из модуля torch.nn представляет собой версию линейного слоя с отложенной инициализацией весов. В отличие от обычного Linear, этот слой не требует указания размера входных признаков на этапе создания. Размер определяется автоматически при первом прямом проходе на основе формы переданных данных. Это особенно удобно при построении моделей с динамическими входными размерами.
Синтаксис
torch.nn.LazyLinear(
out_features,
bias=True,
device=None,
dtype=None
)
Класс принимает следующие параметры:
-
out_features- размер выходных признаков (количество нейронов в слое); -
bias- булевый флаг, указывающий, использовать ли смещение (по умолчаниюTrue); -
device- устройство, на котором будет создан слой (по умолчаниюNone); -
dtype- тип данных для весов слоя (по умолчаниюNone).
Пример ⁅⋯n="sect"⁆
Давайте создадим ленивый линейный слой и применим его к данным:
import torch
# Create a lazy linear layer with 3 output features
layer = torch.nn.LazyLinear(3)
# Create input tensor with unknown size
t = torch.randn(5, 10)
# First forward pass initializes weights
res = layer(t)
print(res.shape)
Результат выполнения кода:
torch.Size([5, 3])
Пример ⁅⋯n="sect"⁆
Давайте посмотрим, как меняются веса слоя до и после первого прямого прохода:
import torch
# Create lazy layer
layer = torch.nn.LazyLinear(3)
# Try to access weights before forward pass
try:
print(layer.weight)
except RuntimeError as e:
print("Error:", str(e).split(":")[0] + ":")
# First forward pass
t = torch.randn(2, 4)
_ = layer(t)
# Now weights are initialized
print("Weight shape:", layer.weight.shape)
print("Bias shape:", layer.bias.shape)
Результат выполнения кода:
Error: The tensor has a shape of (0, 3) and no materialized dimensions:
Weight shape: torch.Size([3, 4])
Bias shape: torch.Size([3])
Пример ⁅⋯n="sect"⁆
Создадим модель с ленивым линейным слоем и обучим её на данных различной размерности:
import torch
# Define model with lazy linear layer
class Model(torch.nn.Module):
def __init__(self):
super().__init__()
self.lazy = torch.nn.LazyLinear(1)
def forward(self, x):
return self.lazy(x)
model = Model()
# Train on data with different input sizes
t1 = torch.randn(3, 5)
res1 = model(t1)
print("First pass:", res1.shape)
t2 = torch.randn(3, 7)
res2 = model(t2)
print("Second pass:", res2.shape)
print("Weights shape:", model.lazy.weight.shape)
Результат выполнения кода:
First pass: torch.Size([3, 1])
Second pass: torch.Size([3, 1])
Weights shape: torch.Size([1, 5])
Обратите внимание, что размер весов определяется по размерности первого переданного тензора и остаётся фиксированным для последующих проходов.
Пример ⁅⋯n="sect"⁆
Давайте создадим ленивый слой без смещения и проверим его работу:
import torch
# Create lazy layer without bias
layer = torch.nn.LazyLinear(5, bias=False)
# Forward pass
t = torch.randn(4, 3)
res = layer(t)
print("Output shape:", res.shape)
print("Weight shape:", layer.weight.shape)
print("Bias is:", layer.bias)
Результат выполнения кода:
Output shape: torch.Size([4, 5])
Weight shape: torch.Size([5, 3])
Bias is: None
Смотрите также
-
класс
Linear,
который является обычным линейным слоем с явным указанием входной размерности -
класс
LazyConv2d,
который является ленивой версией двумерного свёрточного слоя -
класс
Dropout,
который применяет регуляризацию отбрасыванием нейронов -
класс
BatchNorm1d,
который применяет пакетную нормализацию для одномерных данных