class LayerNorm(nn.Module): def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"): super(LayerNorm, self).__init__() self.weight = nn.Parameter(torch.ones(normalized_shape), requires_grad=True) self.bias = nn.Parameter(torch.zeros(normalized_shape), requires_grad=True) self.eps = eps self.data_format = data_format if self.data_format not in ['channels_last', 'channels_first']: raise ValueError(f"not support data format'{self.data_format}'") self.normalized_shape = (normalized_shape,) def forward(self, x: torch.Tensor) -> torch.Tensor: if self.data_format == 'channels_last': return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps) elif self.data_format == 'channels_first': # [B,C,H,W] mean = x.mean(1, keepdim=True) var = (x - mean).pow(2).mean(1, keepdim=True) x = (x - mean) / torch.sqrt(var + self.eps) x = self.weight[:, None, None] * x + self.bias[:, None, None] return x
时间: 2024-04-08 09:32:30 浏览: 202
这段代码实现了Layer Normalization(层归一化)的功能。Layer Normalization是一种用于神经网络的归一化方法,可以在训练过程中稳定神经网络的学习。
在代码中,LayerNorm类继承自nn.Module,并实现了初始化方法和前向传播方法。
在初始化方法中,normalized_shape参数指定了归一化的维度大小,eps参数用于防止除零错误,data_format参数用于指定输入数据的格式('channels_last'或'channels_first')。
前向传播方法中,根据输入数据的格式进行不同的处理。当data_format为'channels_last'时,调用了PyTorch中的F.layer_norm函数进行归一化操作。当data_format为'channels_first'时,首先计算输入数据的均值和方差,然后进行归一化操作,并使用参数weight和bias进行缩放和偏移。
最后返回归一化后的结果。
相关问题
class ContrastiveHead(nn.Module): """MLP head for contrastive representation learning, https://arxiv.org/abs/2003.04297 Args: dim_in (int): dimension of the feature intended to be contrastively learned feat_dim (int): dim of the feature to calculated contrastive loss Return: feat_normalized (tensor): L-2 normalized encoded feature, so the cross-feature dot-product is cosine similarity (https://arxiv.org/abs/2004.11362) """ def __init__(self, dim_in, feat_dim): super().__init__() self.head = nn.Sequential( nn.Linear(dim_in, dim_in), nn.ReLU(inplace=True), nn.Linear(dim_in, feat_dim), ) for layer in self.head: if isinstance(layer, nn.Linear): weight_init.c2_xavier_fill(layer) def forward(self, x): feat = self.head(x) feat_normalized = F.normalize(feat, dim=1) return feat_normalized
这是一个用于对比学习(contrastive learning)的 MLP 头部(MLP head)模型。在对比学习中,我们需要将输入的特征进行编码,使得相似的样本在编码后的特征空间中距离更近,不相似的样本距离更远。这个 MLP 头部的输入是 dim_in 维度的特征,输出是 feat_dim 维度的编码特征。在 MLP 头部中,我们使用了两个线性层和一个 ReLU 激活函数。在初始化时,我们使用了 Xavier 初始化方法对线性层的权重进行初始化。在前向传播时,我们将输入特征传递给 MLP 头部,得到编码特征,并对编码特征进行 L-2 归一化,使得特征向量的范数为 1,方便后续计算。最后返回编码后的特征。
ln = nn.LayerNorm(2) bn = nn.BatchNorm1d(2) X = torch.tensor([[1, 2], [2, 3]], dtype=torch.float32) # 在训练模式下计算X的均值和方差 print(’layer norm:’, ln(X), ’\nbatch norm:’, bn(X)) layer norm: tensor([[-1.0000, 1.0000], [-1.0000, 1.0000]], grad_fn=<NativeLayerNormBackward0>) batch norm: tensor([[-1.0000, -1.0000], [ 1.0000, 1.0000]], grad_fn=<NativeBatchNormBackward0>) #@save class AddNorm(nn.Module): """残差连接后进行层规范化""" def __init__(self, normalized_shape, dropout, **kwargs): super(AddNorm, self).__init__(**kwargs) self.dropout = nn.Dropout(dropout) self.ln = nn.LayerNorm(normalized_shape) def forward(self, X, Y): return self.ln(self.dropout(Y) + X) 残差连接要求两个输入的形状相同,以便加法操作后输出张量的形状相同。 add_norm = AddNorm([3, 4], 0.5) add_norm.eval() add_norm(torch.ones((2, 3, 4)), torch.ones((2, 3, 4))).shape torch.Size([2, 3, 4])
这段代码展示了如何使用LayerNorm和BatchNorm对输入进行规范化。首先创建了一个LayerNorm实例ln和一个BatchNorm1d实例bn。然后,将一个大小为(2, 2)的浮点型张量X输入到ln和bn中,并打印出规范化后的结果。
ln对输入进行层规范化,计算输入的均值和方差,并对输入进行归一化。结果是一个与输入相同大小的张量,其中每个元素都经过层规范化处理。bn对输入进行批规范化,计算输入的均值和方差,并对输入进行归一化。结果也是一个与输入相同大小的张量,其中每个元素都经过批规范化处理。
接下来定义了一个AddNorm类,用于在残差连接后进行层规范化。它包含一个dropout层和一个LayerNorm层。在前向传播中,将输入X和Y进行残差连接,并通过dropout层和LayerNorm层进行规范化处理。最后,打印出残差连接后输出张量的形状。
在代码的最后,创建了一个AddNorm的实例add_norm,并对其进行了评估(eval())。然后,将两个大小为(2, 3, 4)的张量输入到add_norm中,并打印出输出张量的形状。
结果是一个大小为(2, 3, 4)的张量,表示残差连接后的输出张量的形状与输入张量相同。
阅读全文