TheKernel01's picture
Sync from GitHub via hub-sync
0435337 verified
Raw
History Blame Contribute Delete
4.41 kB
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import numpy.random as random
import torch
import torch.nn as nn
import torch.nn.functional as F
# from MinkowskiEngine import SparseTensor
# class MinkowskiGRN(nn.Module):
# """ GRN layer for sparse tensors.
# """
# def __init__(self, dim):
# super().__init__()
# self.gamma = nn.Parameter(torch.zeros(1, dim))
# self.beta = nn.Parameter(torch.zeros(1, dim))
# def forward(self, x):
# cm = x.coordinate_manager
# in_key = x.coordinate_map_key
# Gx = torch.norm(x.F, p=2, dim=0, keepdim=True)
# Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6)
# return SparseTensor(
# self.gamma * (x.F * Nx) + self.beta + x.F,
# coordinate_map_key=in_key,
# coordinate_manager=cm)
# class MinkowskiDropPath(nn.Module):
# """ Drop Path for sparse tensors.
# """
# def __init__(self, drop_prob: float = 0., scale_by_keep: bool = True):
# super(MinkowskiDropPath, self).__init__()
# self.drop_prob = drop_prob
# self.scale_by_keep = scale_by_keep
# def forward(self, x):
# if self.drop_prob == 0. or not self.training:
# return x
# cm = x.coordinate_manager
# in_key = x.coordinate_map_key
# keep_prob = 1 - self.drop_prob
# mask = torch.cat([
# torch.ones(len(_)) if random.uniform(0, 1) > self.drop_prob
# else torch.zeros(len(_)) for _ in x.decomposed_coordinates
# ]).view(-1, 1).to(x.device)
# if keep_prob > 0.0 and self.scale_by_keep:
# mask.div_(keep_prob)
# return SparseTensor(
# x.F * mask,
# coordinate_map_key=in_key,
# coordinate_manager=cm)
# class MinkowskiLayerNorm(nn.Module):
# """ Channel-wise layer normalization for sparse tensors.
# """
# def __init__(
# self,
# normalized_shape,
# eps=1e-6,
# ):
# super(MinkowskiLayerNorm, self).__init__()
# self.ln = nn.LayerNorm(normalized_shape, eps=eps)
# def forward(self, input):
# output = self.ln(input.F)
# return SparseTensor(
# output,
# coordinate_map_key=input.coordinate_map_key,
# coordinate_manager=input.coordinate_manager)
class LayerNorm(nn.Module):
""" LayerNorm that supports two data formats: channels_last (default) or channels_first.
The ordering of the dimensions in the inputs. channels_last corresponds to inputs with
shape (batch_size, height, width, channels) while channels_first corresponds to inputs
with shape (batch_size, channels, height, width).
"""
def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"):
super().__init__()
self.weight = nn.Parameter(torch.ones(normalized_shape))
self.bias = nn.Parameter(torch.zeros(normalized_shape))
self.eps = eps
self.data_format = data_format
if self.data_format not in ["channels_last", "channels_first"]:
raise NotImplementedError
self.normalized_shape = (normalized_shape, )
def forward(self, x):
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":
u = x.mean(1, keepdim=True)
s = (x - u).pow(2).mean(1, keepdim=True)
x = (x - u) / torch.sqrt(s + self.eps)
x = self.weight[:, None, None] * x + self.bias[:, None, None]
return x
class GRN(nn.Module):
""" GRN (Global Response Normalization) layer
"""
def __init__(self, dim):
super().__init__()
self.gamma = nn.Parameter(torch.zeros(1, 1, 1, dim))
self.beta = nn.Parameter(torch.zeros(1, 1, 1, dim))
def forward(self, x):
Gx = torch.norm(x, p=2, dim=(1,2), keepdim=True)
Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6)
return self.gamma * (x * Nx) + self.beta + x