0

I going to do Anomaly detection on my own images by using the example on deeplearning4j platform. And I change the code like this:

    int rngSeed=123;
    Random rnd = new Random(rngSeed);
    int width=28;
    int height=28;
    int batchSize = 128;
    MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
            .seed(12345)
            .iterations(1)
            .weightInit(WeightInit.XAVIER) 
            .updater(Updater.ADAGRAD)
            .activation(Activation.RELU)
            .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
            .learningRate(0.05)
            .regularization(true).l2(0.0001)
            .list()
            .layer(0, new DenseLayer.Builder().nIn(784).nOut(250)
                    .build())
            .layer(1, new DenseLayer.Builder().nIn(250).nOut(10)
                    .build())
            .layer(2, new DenseLayer.Builder().nIn(10).nOut(250)
                    .build())
            .layer(3, new OutputLayer.Builder().nIn(250).nOut(784)
                    .lossFunction(LossFunctions.LossFunction.MSE)
                    .build())
            .pretrain(false).backprop(true)
            .build();

    MultiLayerNetwork net = new MultiLayerNetwork(conf);
    net.setListeners(Collections.singletonList((IterationListener) new ScoreIterationListener(1)));
    File trainData = new File("mnist_png/training");
    FileSplit fsTrain = new FileSplit(trainData, NativeImageLoader.ALLOWED_FORMATS, rnd);

    ImageRecordReader recorderReader = new ImageRecordReader(height, width);
    recorderReader.initialize(fsTrain);


    DataSetIterator dataIt = new RecordReaderDataSetIterator(recorderReader, batchSize);
    List<INDArray> featuresTrain = new ArrayList<>();
    while(dataIt.hasNext()){
        DataSet ds = dataIt.next();
        featuresTrain.add(ds.getFeatureMatrix());
    }


    System.out.println("************ training **************");
    int nEpochs = 30;
    for( int epoch=0; epoch<nEpochs; epoch++ ){
        for(INDArray data : featuresTrain){
            net.fit(data,data);
        }
        System.out.println("Epoch " + epoch + " complete");
    }

And it threw an exception while training:

Exception in thread "main" org.deeplearning4j.exception.DL4JInvalidInputException: Input that is not a matrix; expected matrix (rank 2), got rank 4 array with shape [128, 1, 28, 28]
    at org.deeplearning4j.nn.layers.BaseLayer.preOutput(BaseLayer.java:363)
    at org.deeplearning4j.nn.layers.BaseLayer.activate(BaseLayer.java:384)
    at org.deeplearning4j.nn.layers.BaseLayer.activate(BaseLayer.java:405)
    at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.activationFromPrevLayer(MultiLayerNetwork.java:590)
    at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.feedForwardToLayer(MultiLayerNetwork.java:713)
    at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.computeGradientAndScore(MultiLayerNetwork.java:1821)
    at org.deeplearning4j.optimize.solvers.BaseOptimizer.gradientAndScore(BaseOptimizer.java:151)
    at org.deeplearning4j.optimize.solvers.StochasticGradientDescent.optimize(StochasticGradientDescent.java:54)
    at org.deeplearning4j.optimize.Solver.optimize(Solver.java:51)
    at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:1443)
    at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:1408)
    at org.deeplearning4j.examples.dataExamples.AnomalyTest.main(AnomalyTest.java:86)

It seem that my input dataset has 4 columns while it need just 2 columes, so the question is how to convert imagerecorderread or something else to make it running properly?

Jerome tan
  • 155
  • 1
  • 1
  • 10

1 Answers1

1

So first of all, you may want to understand what a tensor is: http://nd4j.org/tensor

The record reader returns a multi dimensional image, you need to flatten it in order for it to be used with a 2d neural net unless you plan on using CNNs for part of your training.

If you take a look at the exception (again you really should be familiar with ndarrays, they aren't new and are used in every deep learning library): you'll see a shape of: [128, 1, 28, 28]

That is batch size by channels by rows x columns. You need to do a: .setInputType(InputType.convolutional(28,28,1))

This will tell dl4j that it needs to flatten the 4d to a 2d. In this case it indicates that there's a rows,columns,channels of 28 x 28 x 1

If you add this to the bottom of your config it will work.

Of note if you are trying to do anomaly detection is we also have variational autoencoders you may want to look in to as well.

Adam Gibson
  • 3,055
  • 1
  • 10
  • 12
  • It threw a new exception: – Jerome tan Jan 10 '17 at 04:49
  • Exception in thread "main" java.lang.IllegalStateException: Mis matched lengths: [28] != [100352] at org.nd4j.linalg.util.LinAlgExceptions.assertSameLength(LinAlgExceptions.java:40) – Jerome tan Jan 10 '17 at 04:49
  • This was an edge case with 4d and the 2d labels. Please file an issue: https://github.com/deeplearning4j/deeplearning4j/issues For now just do the reshaping yourself. This is a pretty trivial fix. – Adam Gibson Jan 10 '17 at 05:04