2

I can't get a simple convolution to work in nd4j and documentation regarding this specific topic is scarse. What I'm trying to do:

INDArray values = Nd4j.create(new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
INDArray kernel = Nd4j.create(new double[]{0.5,0.5});

INDArray conv = Nd4j.getConvolution().convn(values, kernel, Convolution.Type.VALID);

No matter the values or the convolution type, I always get the same exception (see below). The error seems to occur when nd4j is trying to transform the array of values into a complex array to perform what I think is a Fourier transformation.

I've tried several versions of nd4j (0.9.1 - 0.8.0 - 0.7.0) but to no avail. Can anyone help?

Exception in thread "main" java.lang.UnsupportedOperationException
at org.nd4j.linalg.api.complex.BaseComplexNDArray.putScalar(BaseComplexNDArray.java:1947)
at org.nd4j.linalg.api.complex.BaseComplexNDArray.putScalar(BaseComplexNDArray.java:1804)
at org.nd4j.linalg.api.complex.BaseComplexNDArray.copyFromReal(BaseComplexNDArray.java:545)
at org.nd4j.linalg.api.complex.BaseComplexNDArray.<init>(BaseComplexNDArray.java:159)
at org.nd4j.linalg.api.complex.BaseComplexNDArray.<init>(BaseComplexNDArray.java:167)
at org.nd4j.linalg.cpu.nativecpu.complex.ComplexNDArray.<init>(ComplexNDArray.java:104)
at org.nd4j.linalg.cpu.nativecpu.CpuNDArrayFactory.createComplex(CpuNDArrayFactory.java:166)
at org.nd4j.linalg.factory.Nd4j.createComplex(Nd4j.java:3345)
at org.nd4j.linalg.convolution.DefaultConvolutionInstance.convn(DefaultConvolutionInstance.java:116)
at org.nd4j.linalg.convolution.BaseConvolution.convn(BaseConvolution.java:66)
at com.example.demo.Main.testing(Main.java:41)
at com.example.demo.Main.main(Main.java:34)
Anthony De Smet
  • 2,265
  • 3
  • 17
  • 24
  • Hi, did you ever work it out? – osk Nov 28 '17 at 09:33
  • I implemented the convolution myself and it works, but I didn't use a fast-fourier transform so it's about 10x slower than what you'd normally get, sadly. Still works for me though, small data sets. If you like, I can post the code. – Anthony De Smet Nov 28 '17 at 12:49
  • Oh I see, it's alright. I am going to need as good as possible performance since I'll be using it on big data. – osk Nov 29 '17 at 11:20

1 Answers1

0

It's a bit trickier, as ND4j currently does not support mathematical convolution. You have to craft your own implementation.

    double[] rawData = {12,10,15,12,10,11,15,12,12};
    INDArray data = Nd4j.create(rawData);
    double[] rawFilter = {1.0 / 2, 0, 1.0 / 2};
    INDArray filter = Nd4j.create(rawFilter);        
    Nd4jConv1d convolution = new Nd4jConv1d(1, 1, (int) filter.shape()[1], 1, 0);
    INDArray output = convolution.forward(data, filter);

As seen in: https://github.com/deeplearning4j/deeplearning4j/blob/af7155d61dc810d3e7139f15f98810e0255b2e17/arbiter/arbiter-deeplearning4j/src/test/java/org/deeplearning4j/arbiter/multilayernetwork/MNISTOptimizationTest.java

Note: you need an additional class Nd4jConv1d. Go to the repo to get it

fernandezr
  • 660
  • 6
  • 19