hyper-connections 0.3.8__tar.gz → 0.3.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (17) hide show
  1. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/PKG-INFO +1 -1
  2. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/manifold_constrained_hyper_connections.py +2 -0
  3. hyper_connections-0.3.9/hyper_connections/vit.py +163 -0
  4. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/pyproject.toml +1 -1
  5. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/tests/test_hyper_connections.py +21 -0
  6. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/.github/workflows/python-publish.yml +0 -0
  7. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/.github/workflows/test.yml +0 -0
  8. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/.gitignore +0 -0
  9. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/LICENSE +0 -0
  10. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/README.md +0 -0
  11. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper-connections.png +0 -0
  12. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/__init__.py +0 -0
  13. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/hyper_connections.py +0 -0
  14. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/hyper_connections_channel_first.py +0 -0
  15. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/hyper_connections_with_multi_branch_inputs.py +0 -0
  16. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/hyper_connections_with_multi_input_streams.py +0 -0
  17. {hyper_connections-0.3.8 → hyper_connections-0.3.9}/hyper_connections/residuals.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyper-connections
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: Hyper-Connections
5
5
  Project-URL: Homepage, https://pypi.org/project/hyper-connections/
6
6
  Project-URL: Repository, https://github.com/lucidrains/hyper-connections
@@ -486,6 +486,8 @@ class ManifoldConstrainedHyperConnections(Module):
486
486
 
487
487
  return add_residual_fn(branch_output)
488
488
 
489
+ mHC = ManifoldConstrainedHyperConnections
490
+
489
491
  ManifoldConstrainedHyperConnections.get_expand_reduce_stream_functions = staticmethod(get_expand_reduce_stream_functions)
490
492
  ManifoldConstrainedHyperConnections.get_init_and_expand_reduce_stream_functions = staticmethod(get_init_and_expand_reduce_stream_functions)
491
493
 
@@ -0,0 +1,163 @@
1
+ import torch
2
+ from torch import nn
3
+ from torch.nn import Module, ModuleList
4
+
5
+ from einops import rearrange, repeat
6
+ from einops.layers.torch import Rearrange
7
+
8
+ from hyper_connections.manifold_constrained_hyper_connections import mHC
9
+
10
+ # helpers
11
+
12
+ def pair(t):
13
+ return t if isinstance(t, tuple) else (t, t)
14
+
15
+ # classes
16
+
17
+ class FeedForward(Module):
18
+ def __init__(self, dim, hidden_dim, dropout = 0.):
19
+ super().__init__()
20
+ self.net = nn.Sequential(
21
+ nn.LayerNorm(dim),
22
+ nn.Linear(dim, hidden_dim),
23
+ nn.GELU(),
24
+ nn.Dropout(dropout),
25
+ nn.Linear(hidden_dim, dim),
26
+ nn.Dropout(dropout)
27
+ )
28
+
29
+ def forward(self, x):
30
+ return self.net(x)
31
+
32
+ class Attention(Module):
33
+ def __init__(self, dim, heads = 8, dim_head = 64, dropout = 0.):
34
+ super().__init__()
35
+ inner_dim = dim_head * heads
36
+ project_out = not (heads == 1 and dim_head == dim)
37
+
38
+ self.heads = heads
39
+ self.scale = dim_head ** -0.5
40
+
41
+ self.norm = nn.LayerNorm(dim)
42
+
43
+ self.attend = nn.Softmax(dim = -1)
44
+ self.dropout = nn.Dropout(dropout)
45
+
46
+ self.to_qkv = nn.Linear(dim, inner_dim * 3, bias = False)
47
+
48
+ self.to_out = nn.Sequential(
49
+ nn.Linear(inner_dim, dim),
50
+ nn.Dropout(dropout)
51
+ ) if project_out else nn.Identity()
52
+
53
+ def forward(self, x):
54
+ x = self.norm(x)
55
+
56
+ qkv = self.to_qkv(x).chunk(3, dim = -1)
57
+ q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h = self.heads), qkv)
58
+
59
+ dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale
60
+
61
+ attn = self.attend(dots)
62
+ attn = self.dropout(attn)
63
+
64
+ out = torch.matmul(attn, v)
65
+ out = rearrange(out, 'b h n d -> b n (h d)')
66
+ return self.to_out(out)
67
+
68
+ class Transformer(Module):
69
+ def __init__(self, dim, depth, heads, dim_head, mlp_dim, dropout = 0., num_residual_streams = 4):
70
+ super().__init__()
71
+ self.norm = nn.LayerNorm(dim)
72
+ self.layers = ModuleList([])
73
+
74
+ init_hyper_conn, self.expand_streams, self.reduce_streams = mHC.get_init_and_expand_reduce_stream_functions(num_residual_streams)
75
+
76
+ for _ in range(depth):
77
+ self.layers.append(ModuleList([
78
+ init_hyper_conn(dim = dim , branch = Attention(dim, heads = heads, dim_head = dim_head, dropout = dropout)),
79
+ init_hyper_conn(dim = dim, branch = FeedForward(dim, mlp_dim, dropout = dropout))
80
+ ]))
81
+
82
+ def forward(self, x):
83
+
84
+ x = self.expand_streams(x)
85
+
86
+ for attn, ff in self.layers:
87
+ x = attn(x)
88
+ x = ff(x)
89
+
90
+ x = self.reduce_streams(x)
91
+
92
+ return self.norm(x)
93
+
94
+ class ViT(Module):
95
+ def __init__(self, *, image_size, patch_size, num_classes, dim, depth, heads, mlp_dim, pool = 'cls', channels = 3, dim_head = 64, dropout = 0., emb_dropout = 0., num_residual_streams = 4):
96
+ super().__init__()
97
+ image_height, image_width = pair(image_size)
98
+ patch_height, patch_width = pair(patch_size)
99
+
100
+ assert image_height % patch_height == 0 and image_width % patch_width == 0, 'Image dimensions must be divisible by the patch size.'
101
+
102
+ num_patches = (image_height // patch_height) * (image_width // patch_width)
103
+ patch_dim = channels * patch_height * patch_width
104
+
105
+ assert pool in {'cls', 'mean'}, 'pool type must be either cls (cls token) or mean (mean pooling)'
106
+ num_cls_tokens = 1 if pool == 'cls' else 0
107
+
108
+ self.to_patch_embedding = nn.Sequential(
109
+ Rearrange('b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = patch_height, p2 = patch_width),
110
+ nn.LayerNorm(patch_dim),
111
+ nn.Linear(patch_dim, dim),
112
+ nn.LayerNorm(dim),
113
+ )
114
+
115
+ self.cls_token = nn.Parameter(torch.randn(num_cls_tokens, dim))
116
+ self.pos_embedding = nn.Parameter(torch.randn(num_patches + num_cls_tokens, dim))
117
+
118
+ self.dropout = nn.Dropout(emb_dropout)
119
+
120
+ self.transformer = Transformer(dim, depth, heads, dim_head, mlp_dim, dropout)
121
+
122
+ self.pool = pool
123
+ self.to_latent = nn.Identity()
124
+
125
+ self.mlp_head = nn.Linear(dim, num_classes)
126
+
127
+ def forward(self, img):
128
+ batch = img.shape[0]
129
+ x = self.to_patch_embedding(img)
130
+
131
+ cls_tokens = repeat(self.cls_token, '... d -> b ... d', b = batch)
132
+ x = torch.cat((cls_tokens, x), dim = 1)
133
+
134
+ seq = x.shape[1]
135
+
136
+ x = x + self.pos_embedding[:seq]
137
+ x = self.dropout(x)
138
+
139
+ x = self.transformer(x)
140
+
141
+ x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0]
142
+
143
+ x = self.to_latent(x)
144
+ return self.mlp_head(x)
145
+
146
+ if __name__ == '__main__':
147
+ v = ViT(
148
+ image_size = 256,
149
+ patch_size = 32,
150
+ num_classes = 1000,
151
+ dim = 1024,
152
+ depth = 6,
153
+ heads = 16,
154
+ mlp_dim = 2048,
155
+ dropout = 0.1,
156
+ emb_dropout = 0.1,
157
+ num_residual_streams = 4
158
+ )
159
+
160
+ img = torch.randn(1, 3, 256, 256)
161
+
162
+ preds = v(img) # (1, 1000)
163
+ assert preds.shape == (1, 1000)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyper-connections"
3
- version = "0.3.8"
3
+ version = "0.3.9"
4
4
  description = "Hyper-Connections"
5
5
  authors = [
6
6
  { name = "Phil Wang", email = "lucidrains@gmail.com" }
@@ -252,3 +252,24 @@ def test_mhc_dtype_restoration():
252
252
  residual = mhc.depth_connection(branch_output, residual, **residual_kwargs)
253
253
 
254
254
  assert residual.dtype == torch.half
255
+
256
+ def test_mhc_vit():
257
+ from hyper_connections.vit import ViT
258
+
259
+ v = ViT(
260
+ image_size = 256,
261
+ patch_size = 32,
262
+ num_classes = 1000,
263
+ dim = 1024,
264
+ depth = 6,
265
+ heads = 16,
266
+ mlp_dim = 2048,
267
+ dropout = 0.1,
268
+ emb_dropout = 0.1,
269
+ num_residual_streams = 4
270
+ )
271
+
272
+ img = torch.randn(1, 3, 256, 256)
273
+
274
+ preds = v(img) # (1, 1000)
275
+ assert preds.shape == (1, 1000)