Repository: kymatio/kymatio

Issue:
Unexpected crush with J=1 
Hi, 

I faced the following problem: I get unexpected and unexplained crush when J=1 regardless of other parameters values. Please, find the code and the error message below. 

Here's the code:

```
data = torch.Tensor(np.random.rand(128,3,32,32))
print("shape before scattering: {}".format(data.shape))

scatModel = Scattering2D(J=1,L=8, shape = (32,32), max_order=2)
a = scatModel(data)

print("shape after scattering: {}".format(a.shape))
```

And the error message: 

> shape before scattering: torch.Size([128, 3, 32, 32])
> Traceback (most recent call last):
>   File "/user/HS221/dm00314/PycharmProjects/ScatterNetsTestFramework/venv/mixingMallatTest.py", line 24, in <module>
>     a = scatModel(data)
>   File "/user/HS221/dm00314/PycharmProjects/ScatterNetsTestFramework/venv/lib/python3.5/site-packages/kymatio-0.2.0.dev0-py3.5.egg/kymatio/scattering2d/scattering2d.py", line 235, in __call__
>   File "/user/HS221/dm00314/PycharmProjects/ScatterNetsTestFramework/venv/lib/python3.5/site-packages/kymatio-0.2.0.dev0-py3.5.egg/kymatio/scattering2d/scattering2d.py", line 202, in forward
> KeyError: 0

Is it me or something is wrong?

Thank you, 
Dmitry


Discussion:
Hi Dmitry,

Thanks for opening this issue. Indeed, the value J=1 can't work currently. If J=1 is used, then no second-order coefficient will be included. I'm not sure it makes sens to set this value as valid.

@janden @lostanlen @eickenberg any thoughts? Should it be a legal value?
@edouardoyallon, thank you for the reply

But this is exactly what I'm trying to do here. I only need 1 order of coefficients which then will be worked on and reused.

Is there any hacky way I can enable J=1?


So, if you impose maxorder=1 and if you modify this line: https://github.com/kymatio/kymatio/blob/master/kymatio/scattering2d/filter_bank.py#L49 such that the resolution 0 of the filterbank is built, then that should work.
Actually, after looking more carefully, nothing forbids to do J=1 there. Feel free to propose a PR!

Resolving patch:
diff --git a/kymatio/scattering2d/filter_bank.py b/kymatio/scattering2d/filter_bank.py
--- a/kymatio/scattering2d/filter_bank.py
+++ b/kymatio/scattering2d/filter_bank.py
@@ -46,7 +46,7 @@ def filter_bank(M, N, J, L=8):
             psi_signal_fourier = fft2(psi_signal)
             # drop the imaginary part, it is zero anyway
             psi_signal_fourier = np.real(psi_signal_fourier)
-            for res in range(min(j + 1, J - 1)):
+            for res in range(min(j + 1, max(J - 1, 1))):
                 psi_signal_fourier_res = periodize_filter_fft(
                     psi_signal_fourier, res)
                 # add a trailing singleton dimension to mark it as non-complex
@@ -54,6 +54,7 @@ def filter_bank(M, N, J, L=8):
                 psi[res] = psi_signal_fourier_res
                 # Normalization to avoid doing it with the FFT.
                 psi[res] /= M*N// 2**(2*j)
+
             filters['psi'].append(psi)
 
     filters['phi'] = {}


Test patch:
diff --git a/kymatio/scattering2d/tests/test_scattering2d.py b/kymatio/scattering2d/tests/test_scattering2d.py
--- a/kymatio/scattering2d/tests/test_scattering2d.py
+++ b/kymatio/scattering2d/tests/test_scattering2d.py
@@ -318,8 +318,8 @@ def test_scattering2d_errors():
 
 # Check that several input size works
 def test_input_size_agnostic():
-    for N in [31,32,33]:
-        for J in [2,4]:
+    for N in [31, 32, 33]:
+        for J in [1, 2, 4]:
             scattering = Scattering2D(J, shape=(N, N))
             x = torch.zeros(3,3,N,N)