Skip to content

Commit 3e6698b

Browse files
committed
updated tests and started extensive testing
1 parent 9fe71de commit 3e6698b

17 files changed

+905
-146
lines changed

orthogonium/layers/channel_shuffle.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,3 @@ def forward(self, x):
2424

2525
def extra_repr(self):
2626
return f"group_in={self.group_in}, group_out={self.group_out}"
27-
28-
29-
if __name__ == "__main__":
30-
x = torch.randn(2, 6)
31-
# takes two groups of size 3, and return 3 groups of size 2
32-
gm = ChannelShuffle(2, 3)
33-
print(f"in: {x}")
34-
y = gm(x)
35-
print(f"out: {y}")
36-
x2 = torch.randn(2, 6, 32, 32)
37-
gm = ChannelShuffle(2, 3)
38-
y2 = gm(x2)
39-
print(f"in shape: {x2.shape}, out shape: {y2.shape}")
40-
gp = ChannelShuffle(3, 2)
41-
x2b = gp(y2)
42-
assert torch.allclose(x2, x2b), "ChannelShuffle is not invertible"
43-
print("ChannelShuffle is invertible")

orthogonium/layers/conv/AOC/bcop_x_rko_conv.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,20 @@ def __init__(
5454
if (self.dilation[0] != 1 or self.dilation[1] != 1) and (
5555
self.stride[0] != 1 or self.stride[1] != 1
5656
):
57-
raise RuntimeError(
57+
raise ValueError(
5858
"dilation must be 1 when stride is not 1. The set of orthonal convolutions is empty in this setting."
5959
)
6060
# raise runtime error if kernel size >= stride
6161
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
62-
raise RuntimeError(
62+
raise ValueError(
6363
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
6464
)
65-
if (in_channels % groups != 0) and (out_channels % groups != 0):
66-
raise RuntimeError(
67-
"in_channels and out_channels must be divisible by groups"
68-
)
6965
if (
7066
((max(in_channels, out_channels) // groups) < 2)
7167
and (self.kernel_size[0] != self.stride[0])
7268
and (self.kernel_size[1] != self.stride[1])
7369
):
74-
raise RuntimeError("inner conv must have at least 2 channels")
70+
raise ValueError("inner conv must have at least 2 channels")
7571
self.intermediate_channels = max(
7672
in_channels, out_channels // (self.stride[0] * self.stride[1])
7773
)
@@ -207,23 +203,19 @@ def __init__(
207203
if (self.dilation[0] != 1 or self.dilation[1] != 1) and (
208204
self.stride[0] != 1 or self.stride[1] != 1
209205
):
210-
raise RuntimeError(
206+
raise ValueError(
211207
"dilation must be 1 when stride is not 1. The set of orthonal convolutions is empty in this setting."
212208
)
213209
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
214-
raise RuntimeError(
210+
raise ValueError(
215211
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
216212
)
217-
if (in_channels % groups != 0) and (out_channels % groups != 0):
218-
raise RuntimeError(
219-
"in_channels and out_channels must be divisible by groups"
220-
)
221213
if (
222214
((max(in_channels, out_channels) // groups) < 2)
223215
and (self.kernel_size[0] != self.stride[0])
224216
and (self.kernel_size[1] != self.stride[1])
225217
):
226-
raise RuntimeError("inner conv must have at least 2 channels")
218+
raise ValueError("inner conv must have at least 2 channels")
227219
if out_channels * (self.stride[0] * self.stride[1]) >= in_channels:
228220
self.intermediate_channels = max(
229221
in_channels // (self.stride[0] * self.stride[1]), out_channels

orthogonium/layers/conv/AOC/fast_block_ortho_conv.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -390,22 +390,24 @@ def __init__(
390390
)
391391

392392
# raise runtime error if kernel size >= stride
393+
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
394+
raise ValueError(
395+
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
396+
)
393397
if (
394398
(self.stride[0] > 1 or self.stride[1] > 1) and (out_channels > in_channels)
395399
) or (
396400
self.stride[0] > self.kernel_size[0] or self.stride[1] > self.kernel_size[1]
397401
):
398-
raise RuntimeError(
402+
raise ValueError(
399403
"stride > 1 is not supported when out_channels > in_channels, "
400404
"use TODO layer instead"
401405
)
402-
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
403-
raise RuntimeError(
404-
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
405-
)
406-
if (in_channels % groups != 0) and (out_channels % groups != 0):
407-
raise RuntimeError(
408-
"in_channels and out_channels must be divisible by groups"
406+
if (self.dilation[0] != 1 or self.dilation[1] != 1) and (
407+
self.stride[0] != 1 or self.stride[1] != 1
408+
):
409+
raise ValueError(
410+
"dilation must be 1 when stride is not 1. The set of orthonal convolutions is empty in this setting."
409411
)
410412
del self.weight
411413
attach_bcop_weight(
@@ -492,19 +494,15 @@ def __init__(
492494
)
493495
# raise runtime error if kernel size >= stride
494496
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
495-
raise RuntimeError(
497+
raise ValueError(
496498
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
497499
)
498-
if (in_channels % groups != 0) and (out_channels % groups != 0):
499-
raise RuntimeError(
500-
"in_channels and out_channels must be divisible by groups"
501-
)
502500
if (
503501
((max(in_channels, out_channels) // groups) < 2)
504502
and (self.kernel_size[0] != self.stride[0])
505503
and (self.kernel_size[1] != self.stride[1])
506504
):
507-
raise RuntimeError("inner conv must have at least 2 channels")
505+
raise ValueError("inner conv must have at least 2 channels")
508506
if out_channels * (self.stride[0] * self.stride[1]) < in_channels:
509507
# raise warning because this configuration don't yield orthogonal
510508
# convolutions
@@ -514,6 +512,10 @@ def __init__(
514512
"transposed convolutions",
515513
RuntimeWarning,
516514
)
515+
if (self.dilation[0] > 1 or self.dilation[1] > 1) and (
516+
self.stride[0] != 1 or self.stride[1] != 1
517+
):
518+
raise ValueError("dilation must be 1 when stride is not 1")
517519
del self.weight
518520
attach_bcop_weight(
519521
self,

orthogonium/layers/conv/AOC/ortho_conv.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def AdaptiveOrthoConv2d(
3434
3535
"""
3636
if kernel_size < stride:
37-
raise RuntimeError(
37+
raise ValueError(
3838
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
3939
)
4040
if kernel_size == stride:
@@ -83,7 +83,7 @@ def AdaptiveOrthoConvTranspose2d(
8383
`out_channels * (stride**2) > in_channels`.
8484
"""
8585
if kernel_size < stride:
86-
raise RuntimeError(
86+
raise ValueError(
8787
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
8888
)
8989
if kernel_size == stride:

orthogonium/layers/conv/AOC/rko_conv.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ def forward(self, X):
5454
)
5555
X = self.pi(X)
5656
X = self.bjorck(X)
57-
X = X.view(self.out_channels, self.in_channels // self.groups, self.k1, self.k2)
57+
X = X.reshape(
58+
self.out_channels, self.in_channels // self.groups, self.k1, self.k2
59+
)
5860
return X * self.scale
5961

6062
def right_inverse(self, X):
@@ -120,11 +122,10 @@ def __init__(
120122
bias,
121123
padding_mode,
122124
)
123-
if self.dilation[0] > 1 or self.dilation[1] > 1:
124-
raise RuntimeWarning(
125-
"Dilation must be 1 in the RKO convolution."
126-
"Use RkoConvTranspose2d instead."
127-
)
125+
if (self.dilation[0] > 1 or self.dilation[1] > 1) and (
126+
self.stride[0] != 1 or self.stride[1] != 1
127+
):
128+
raise ValueError("dilation must be 1 when stride is not 1")
128129
# torch.nn.init.orthogonal_(self.weight)
129130
self.scale = 1 / math.sqrt(
130131
math.ceil(self.dilation[0] * self.kernel_size[0] / self.stride[0])
@@ -172,7 +173,7 @@ def singular_values(self):
172173
return sv_min, sv_max, stable_rank
173174
elif self.stride[0] > 1 or self.stride[1] > 1:
174175
raise RuntimeError(
175-
"Not able to compute singular values for this " "configuration"
176+
"Not able to compute singular values for this configuration"
176177
)
177178
# Implements interface required by LipschitzModuleL2
178179
sv_min, sv_max, stable_rank = conv_singular_values_numpy(
@@ -220,15 +221,14 @@ def __init__(
220221
)
221222

222223
# raise runtime error if kernel size >= stride
223-
if self.kernel_size[0] > self.stride[0] or self.kernel_size[1] > self.stride[1]:
224-
raise RuntimeError(
225-
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
224+
if self.kernel_size[0] < self.stride[0] or self.kernel_size[1] < self.stride[1]:
225+
raise ValueError(
226+
"kernel size must be smaller than stride. The set of orthogonal convolutions is empty in this setting."
226227
)
227-
if (in_channels % groups != 0) and (out_channels % groups != 0):
228-
raise RuntimeError(
229-
"in_channels and out_channels must be divisible by groups"
230-
)
231-
228+
if (self.dilation[0] > 1 or self.dilation[1] > 1) and (
229+
self.stride[0] != 1 or self.stride[1] != 1
230+
):
231+
raise ValueError("dilation must be 1 when stride is not 1")
232232
if (
233233
self.stride[0] != self.kernel_size[0]
234234
or self.stride[1] != self.kernel_size[1]
@@ -271,7 +271,7 @@ def singular_values(self):
271271
return sv_min, sv_max, stable_rank
272272
elif self.stride[0] > 1 or self.stride[1] > 1:
273273
raise RuntimeError(
274-
"Not able to compute singular values for this " "configuration"
274+
"Not able to compute singular values for this configuration"
275275
)
276276
# Implements interface required by LipschitzModuleL2
277277
sv_min, sv_max, stable_rank = conv_singular_values_numpy(

orthogonium/layers/conv/SLL/sll_layer.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -200,37 +200,32 @@ def __init__(
200200
def forward(self, x):
201201
kernel = self.in_conv.weight
202202
# conv
203+
res = x
203204
if self.padding_mode == "circular":
204-
x = F.pad(
205-
x,
206-
(
207-
self.kernel_size // 2,
208-
self.kernel_size // 2,
209-
self.kernel_size // 2,
210-
self.kernel_size // 2,
211-
),
205+
res = F.pad(
206+
res,
207+
(self.padding,) * 4,
212208
mode="circular",
209+
value=0,
213210
)
214211
res = F.conv2d(
215-
x, kernel, bias=self.in_conv.bias, padding=self.padding, groups=self.groups
212+
res,
213+
kernel,
214+
bias=self.in_conv.bias,
215+
padding=0,
216+
groups=self.groups,
216217
)
217218
# activation
218219
res = self.activation(res)
219220
# conv transpose
220221
if self.padding_mode == "circular":
221222
res = F.pad(
222223
res,
223-
(
224-
self.kernel_size // 2,
225-
self.kernel_size // 2,
226-
self.kernel_size // 2,
227-
self.kernel_size // 2,
228-
),
224+
(self.padding,) * 4,
229225
mode="circular",
226+
value=0,
230227
)
231-
res = 2 * F.conv_transpose2d(
232-
res, kernel, padding=self.padding, groups=self.groups
233-
)
228+
res = 2 * F.conv_transpose2d(res, kernel, padding=0, groups=self.groups)
234229
# residual
235230
out = x - res
236231
return out

orthogonium/layers/conv/adaptiveSOC/fast_skew_ortho_conv.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,17 +230,15 @@ def __init__(
230230

231231
# raise runtime error if kernel size >= stride
232232
if ((stride > 1) and (out_channels > in_channels)) or (stride > kernel_size):
233-
raise RuntimeError(
233+
raise ValueError(
234234
"stride > 1 is not supported when out_channels > in_channels, "
235235
"use TODO layer instead"
236236
)
237237
if kernel_size < stride:
238-
raise RuntimeError(
238+
raise ValueError(
239239
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
240240
)
241241
if (in_channels % groups != 0) and (out_channels % groups != 0):
242-
raise RuntimeError(
243-
"in_channels and out_channels must be divisible by groups"
244242
)
245243
self.padding = padding
246244
self.stride = stride
@@ -340,15 +338,13 @@ def __init__(
340338

341339
# raise runtime error if kernel size >= stride
342340
if kernel_size < stride:
343-
raise RuntimeError(
341+
raise ValueError(
344342
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
345343
)
346344
if (in_channels % groups != 0) and (out_channels % groups != 0):
347-
raise RuntimeError(
348-
"in_channels and out_channels must be divisible by groups"
349345
)
350346
if ((self.max_channels // groups) < 2) and (kernel_size != stride):
351-
raise RuntimeError("inner conv must have at least 2 channels")
347+
raise ValueError("inner conv must have at least 2 channels")
352348
if out_channels * (stride**2) < in_channels:
353349
# raise warning because this configuration don't yield orthogonal
354350
# convolutions

orthogonium/layers/conv/adaptiveSOC/ortho_conv.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def AdaptiveSOCConv2d(
3535
Otherwise, the layer is a BcopRkoConv2d.
3636
"""
3737
if kernel_size < stride:
38-
raise RuntimeError(
38+
raise ValueError(
3939
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
4040
)
4141
if kernel_size == stride:
@@ -84,7 +84,7 @@ def AdaptiveSOCConvTranspose2d(
8484
`out_channels * (stride**2) > in_channels`.
8585
"""
8686
if kernel_size < stride:
87-
raise RuntimeError(
87+
raise ValueError(
8888
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
8989
)
9090
if kernel_size == stride:

orthogonium/layers/conv/adaptiveSOC/soc_x_rko_conv.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,13 @@ def __init__(
6464

6565
# raise runtime error if kernel size >= stride
6666
if kernel_size < stride:
67-
raise RuntimeError(
67+
raise ValueError(
6868
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
6969
)
7070
if (in_channels % groups != 0) and (out_channels % groups != 0):
71-
raise RuntimeError(
72-
"in_channels and out_channels must be divisible by groups"
7371
)
7472
if ((self.max_channels // groups) < 2) and (kernel_size != stride):
75-
raise RuntimeError("inner conv must have at least 2 channels")
73+
raise ValueError("inner conv must have at least 2 channels")
7674
self.padding = padding
7775
self.stride = stride
7876
self.kernel_size = kernel_size
@@ -194,8 +192,6 @@ def __init__(
194192
But unit testing have shown that the convolution is still orthogonal when
195193
`out_channels * (stride**2) > in_channels`.
196194
"""
197-
if dilation != 1:
198-
raise RuntimeError("dilation not supported")
199195
super(SOCRkoConvTranspose2d, self).__init__(
200196
in_channels,
201197
out_channels,
@@ -219,15 +215,13 @@ def __init__(
219215

220216
# raise runtime error if kernel size >= stride
221217
if kernel_size < stride:
222-
raise RuntimeError(
218+
raise ValueError(
223219
"kernel size must be smaller than stride. The set of orthonal convolutions is empty in this setting."
224220
)
225221
if (in_channels % groups != 0) and (out_channels % groups != 0):
226-
raise RuntimeError(
227-
"in_channels and out_channels must be divisible by groups"
228222
)
229223
if ((self.max_channels // groups) < 2) and (kernel_size != stride):
230-
raise RuntimeError("inner conv must have at least 2 channels")
224+
raise ValueError("inner conv must have at least 2 channels")
231225
self.padding = padding
232226
self.stride = stride
233227
self.kernel_size = kernel_size

0 commit comments

Comments
 (0)