forked from SabariKumar/ripsnet-torch-init
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
57 lines (42 loc) · 2.21 KB
/
Copy pathutils.py
File metadata and controls
57 lines (42 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import torch
import torch.nn as nn
# Based on https://colab.research.google.com/drive/1k2AfI6kPJmXK-gN6mi6_EegJQd4SybDz?usp=sharing#scrollTo=_0flZ1L6cWEL
def rand(shape, low, high):
"""Tensor of random numbers, uniformly distributed on [low, high]."""
return torch.rand(shape) * (high - low) + low
class DeepSetLayer(nn.Module):
# Converts a (batch, in_size, n) tensor to a (batch, out_size, n) tensor.
# Replaces the DenseRagged layer from Ripsnet - note that the activation function needs
# to be applied sequentially afterwards when building the neural net.
def __init__(self, in_blocks, out_blocks, use_bias = True, **kwargs):
super().__init__()
self.in_blocks = in_blocks
self.out_blocks = out_blocks
self.use_bias = use_bias
#Initialization trick from nn.linear
lim = (in_blocks) ** -0.5 / 2
self.alpha = torch.nn.Parameter(data=rand((out_blocks, in_blocks), -lim, lim))
self.beta = torch.nn.Parameter(data=rand((out_blocks, in_blocks), -lim, lim))
if self.use_bias:
self.gamma = torch.nn.Parameter(data=rand((out_blocks), -lim, lim))
def forward(self, x):
if self.use_bias:
return (
torch.einsum('...jz, ij -> ...iz', x, self.alpha)
+ torch.einsum('...jz, ij -> ...iz', x.sum(axis=-1)[..., None], self.beta)
+ self.gamma[..., None]
)
else:
return (
torch.einsum('...jz, ij -> ...iz', x, self.alpha)
+ torch.einsum('...jz, ij -> ...iz', x.sum(axis=-1)[..., None], self.beta))
class DeepSetSum(nn.Module):
# Reduces a (batch, blocks, n) tensor to a regular layer of shape (batch, blocks) via projection of
# a direct sum of trivial representations (last tensor dimension.)
def __init__(self, in_blocks, **kwargs):
super().__init__()
lim = (in_blocks) ** -0.5 / 2
self.weight = torch.nn.Parameter(data=rand(in_blocks, -lim, lim))
self.bias = torch.nn.Parameter(data=rand(in_blocks, -lim, lim))
def forward(self, x):
return x.sum(dim = -1) * self.weight + self.bias