简体   繁体   中英

How to configure DL4j for local images

I'm trying to use DeepLearning4j to categorize 32x32 images in numbers from 0-9. I've looked up a number of examples and tutorials, but always run into some exception when fitting the dataset to a network.

Im currently trying to use a ImageRecordReader with ParentPathLabelGenerator and RecordReaderDataSetIterator.

The images seem to load fine but i always run into a DL4JInvalidInputException when fitting.

        File parentDir = new File(dataPath);
        FileSplit filesInDir = new FileSplit(parentDir, NativeImageLoader.ALLOWED_FORMATS);
        ParentPathLabelGenerator labelMaker = new ParentPathLabelGenerator();

        BalancedPathFilter pathFilter = new BalancedPathFilter(new Random(), labelMaker, 100);
        InputSplit[] filesInDirSplit = filesInDir.sample(pathFilter, 80, 20);
        InputSplit trainData = filesInDirSplit[0];
        InputSplit testData = filesInDirSplit[1];

        ImageRecordReader recordReader = new ImageRecordReader(numRows, numColumns, 3, labelMaker);
        recordReader.initialize(trainData);

        DataSetIterator dataIter = new RecordReaderDataSetIterator(recordReader, 1, 1, outputNum);

When using DenseLayer:

Exception in thread "main" org.deeplearning4j.exception.DL4JInvalidInputException: Input that is not a matrix; expected matrix (rank 2), got rank 4 array with shape [1, 3, 32, 32]. Missing preprocessor or wrong input type? (layer name: layer0, layer index: 0, layer type: DenseLayer)

When using ConvolutionLayer the error occures at the OutputLayer:

Exception in thread "main" org.deeplearning4j.exception.DL4JInvalidInputException: Input that is not a matrix; expected matrix (rank 2), got rank 4 array with shape [1, 1000, 28, 28]. Missing preprocessor or wrong input type? (layer name: layer1, layer index: 1, layer type: OutputLayer)

Is my attempt at loading the images incorrect or is my network misconfigured?

Configuration:

MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
                .list()
                .layer(0, new ConvolutionLayer.Builder()
                        .nIn(3) // Number of input datapoints.
                        .nOut(1000) // Number of output datapoints.
                        .activation(Activation.RELU) // Activation function.
                        .weightInit(WeightInit.XAVIER) // Weight initialization.
                        .build())
                .layer(1, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
                        .nIn(1000)
                        .nOut(outputNum)
                        .activation(Activation.SOFTMAX)
                        .weightInit(WeightInit.XAVIER)
                        .build())
                .build();

The easiest way is to use the .setInputType configuration option when defining the network. It will set up all the necessary pre-processors for you, and it will calculate all the correct .nIn values too.

Take another look at this example https://github.com/eclipse/deeplearning4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/convolution/mnist/MnistClassifier.java#L156

When you use the .setInputType way of setting up your network, you don't have to set any .nIn values at all - you still can, as is evident in the example I've linked, but usually there is no good reason to do so.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM