0

Im new to deeplearning4J. I already experimented with its word2vec functionality and everything was fine. But now I am little bit confused regarding image classification. I was playing with this example:

https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/convolution/AnimalsClassification.java

I changed the "save" flag to true and my model is stored into model.bin file. Now comes the problematic part (I am sorry if this sounds as silly question, maybe I am missing something really obvious here)

I created separate class called AnimalClassifier and its purpose is to load model from model.bin file, restore neural network from it and then classify single image using restored network. For this single image I created "temp" folder -> dl4j-examples/src/main/resources/animals/temp/ where I put picture of polar bear that was previously used in training process in AnimalsClassification.java (I wanted to be sure that image would be classified correctly - therefore I reused picture from "bear" folder).

This my code trying to classify polar bear:

protected static int height = 100;
    protected static int width = 100;
    protected static int channels = 3;
    protected static int numExamples = 1;
    protected static int numLabels = 1;
    protected static int batchSize = 10;

    protected static long seed = 42;
    protected static Random rng = new Random(seed);
    protected static int listenerFreq = 1;
    protected static int iterations = 1;
    protected static int epochs = 7;
    protected static double splitTrainTest = 0.8;
    protected static int nCores = 2;
    protected static boolean save = true;

    protected static String modelType = "AlexNet"; //

    public static void main(String[] args) throws Exception {

        String basePath = FilenameUtils.concat(System.getProperty("user.dir"), "dl4j-examples/src/main/resources/");
        MultiLayerNetwork multiLayerNetwork = ModelSerializer.restoreMultiLayerNetwork(basePath + "model.bin", true);

        ParentPathLabelGenerator labelMaker = new ParentPathLabelGenerator();
        File mainPath = new File(System.getProperty("user.dir"), "dl4j-examples/src/main/resources/animals/temp/");
        FileSplit fileSplit = new FileSplit(mainPath, NativeImageLoader.ALLOWED_FORMATS, rng);
        BalancedPathFilter pathFilter = new BalancedPathFilter(rng, labelMaker, numExamples, numLabels, batchSize);


        InputSplit[] inputSplit = fileSplit.sample(pathFilter, 1);
        InputSplit analysedData = inputSplit[0];


        ImageRecordReader recordReader = new ImageRecordReader(height, width, channels);
        recordReader.initialize(analysedData);
        DataSetIterator dataIter = new RecordReaderDataSetIterator(recordReader, batchSize, 0, 4);
        while (dataIter.hasNext()) {
            DataSet testDataSet = dataIter.next();

            String expectedResult = testDataSet.getLabelName(0);
            List<String> predict = multiLayerNetwork.predict(testDataSet);
            String modelResult = predict.get(0);
            System.out.println("\nFor example that is labeled " + expectedResult + " the model predicted " + modelResult + "\n\n");
        }
    }

After running this, I get error:

java.lang.UnsupportedOperationException at org.datavec.api.writable.ArrayWritable.toInt(ArrayWritable.java:47) at org.deeplearning4j.datasets.datavec.RecordReaderDataSetIterator.getDataSet(RecordReaderDataSetIterator.java:275) at org.deeplearning4j.datasets.datavec.RecordReaderDataSetIterator.next(RecordReaderDataSetIterator.java:186) at org.deeplearning4j.datasets.datavec.RecordReaderDataSetIterator.next(RecordReaderDataSetIterator.java:389) at org.deeplearning4j.datasets.datavec.RecordReaderDataSetIterator.next(RecordReaderDataSetIterator.java:52) at org.deeplearning4j.examples.convolution.AnimalClassifier.main(AnimalClassifier.java:66) Disconnected from the target VM, address: '127.0.0.1:63967', transport: 'socket' Exception in thread "main" java.lang.IllegalStateException: Label names are not defined on this dataset. Add label names in order to use getLabelName with an id. at org.nd4j.linalg.dataset.DataSet.getLabelName(DataSet.java:1106) at org.deeplearning4j.examples.convolution.AnimalClassifier.main(AnimalClassifier.java:68)

I can see there is a method public void setLabels(INDArray labels) in MultiLayerNetwork.java but I don't get how to use (especially when it takes as argument INDArray).

I am also confused why I have to specify number of possible labels in constructor of RecordReaderDataSetIterator. I would expect that model already knows which labels to use (should not it use labels that were used during training automatically?). I guess, maybe I am loading the picture in completely wrong way...

So to summarize, I would like to achieve simply following:

  1. restore network from model (this is working)
  2. load image to be classified (also working)
  3. classify this image using the same labels that were used during training (bear, deer, duck, turtle) (tricky part)

Thank you in advance for your help or any hints !

Oliver Eder
  • 85
  • 2
  • 10
  • What version are you using? Looking at the current RecordReaderDataSetIterator: https://github.com/deeplearning4j/deeplearning4j/blob/master/deeplearning4j-core/src/main/java/org/deeplearning4j/datasets/datavec/RecordReaderDataSetIterator.java#L275 there is no line 275 Regarding your question on the numLabels: that is legacy and will be fixed: https://github.com/deeplearning4j/deeplearning4j/issues/3216 thanks for pointing that out. – Adam Gibson Apr 08 '17 at 12:22
  • Thank you for your response. The version is 0.8.0. Is there at the moment any simple workaround how to execute step 3 (classify single image on restored network) please? – Oliver Eder Apr 08 '17 at 12:30
  • Generally it's pretty straight forward - can you try adapting this and seeing what you get: https://github.com/deeplearning4j/dl4j-examples/tree/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/dataexamples (look at MNIST save/load same workflow) If you look at this, it looks like your label index is off: https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/dataexamples/MnistImagePipelineExampleLoad.java#L111 It should be 1 not 0. 0 is the array not the int label. – Adam Gibson Apr 08 '17 at 12:36

1 Answers1

0

So summarizing your multiple questions here: A record for images is 2 entries in a collection. The second 1 is the label. The label index is relative to the kind of record you pass in.

The second part of your question: Multiple entries can be apart of a dataset. The list refers to a label for an item at a particular row in the minibatch.

Adam Gibson
  • 3,055
  • 1
  • 10
  • 12