如何将 jpeg 图像转换为矩阵秩 2 数组以供模型预测(使用 deeplearning4j 库)

How to convert a jpeg image into a matrix rank 2 array for a model to predict (Using deeplearning4j libraries)

我目前正在使用 deeplearning4j 库创建一个模型来预测图像中的手写数字。我已经创建了模型,现在想对其进行测试,但一直收到此错误

org.deeplearning4j.exception.DL4JInvalidInputException:输入不是矩阵;预期矩阵(等级 2),得到形状为 [81600] 的等级 1 数组。缺少预处理器或错误的输入类型? (图层名称:layer0,图层索引:0,图层类型:DenseLayer)

这是我的代码

package com.read.AI.service;
import org.datavec.image.loader.Java2DNativeImageLoader;
import org.datavec.image.loader.NativeImageLoader;
import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator;
import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.optimize.listeners.ScoreIterationListener;
import org.jetbrains.annotations.NotNull;
import org.nd4j.evaluation.classification.Evaluation;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
import org.nd4j.linalg.dataset.api.preprocessor.ImagePreProcessingScaler;
import org.nd4j.linalg.learning.config.Nadam;
import org.nd4j.linalg.lossfunctions.LossFunctions;
import org.nd4j.linalg.lossfunctions.LossFunctions.LossFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;


//multilayered (MLP) applied to digit classification
//Uses Two input layers and one hidden layer
public class AIService {

    private static final int numRows = 28;
    private static final int numColumns = 28;
    private static final int outputNum = 10;// number of output classes
    private static final int batchSize = 64;// batch size for each epoch
    private static final int rngSeed = 123;// random number seed for reproducibility
    private static final int numEpochs = 15;// number of epochs to perform
    private static final double rate = 0.0015;// learning rate

    public String CreateModel() throws IOException {
        setupModel();
        return "Model Created";
    }

    private static Logger log = LoggerFactory.getLogger(AIService.class);

    public static void setupModel() throws IOException {
        DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize,true,rngSeed);
        DataSetIterator mnistTest = new MnistDataSetIterator(batchSize,true,rngSeed);

        MultiLayerNetwork model = buildModel(numRows, numColumns, outputNum, rngSeed, rate);

        log.info("Train model....");
        model.fit(mnistTrain, numEpochs);

        log.info("Evaluate model....");
        Evaluation eval = model.evaluate(mnistTest);

        log.info(eval.stats());
        log.info("****************modelFinished********************");
        log.info("Testing model on example image....");

        BufferedImage myImage = ImageIO.read(new FileInputStream("C:\Users\Bacon\Documents\GitHub\myTest\handwritten4.jpeg"));
        predictImage(myImage,model);

    }

    @NotNull
    private static MultiLayerNetwork buildModel(int numRows, int numColumns, int outputNum, int rngSeed, double rate) {
        log.info("Build model....");
        MultiLayerConfiguration configuration = setConfigurationForModel(numRows, numColumns, outputNum, rngSeed, rate);

        MultiLayerNetwork model = new MultiLayerNetwork(configuration);
        model.init();
        model.setListeners(new ScoreIterationListener(5));//print the score with every iteration
        return model;
    }

    private static MultiLayerConfiguration setConfigurationForModel(int numRows, int numColumns, int outputNum, int rngSeed, double rate) {
        log.info("Setting up Configuration for Model....");
        return new NeuralNetConfiguration.Builder()
                    .seed(rngSeed)
                    .activation(Activation.RELU)
                    .weightInit(WeightInit.XAVIER)
                    .updater(new Nadam())
                    .l2(rate * 0.005) // Regularize Learning model
                    .list()
                    .layer(new DenseLayer.Builder()
                            .nIn(numRows * numColumns)
                            .nOut(500)
                            .build())
                    .layer(new DenseLayer.Builder()
                            .nIn(500)
                            .nOut(100)
                            .build())
                    .layer(new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD)
                            .activation(Activation.SOFTMAX)
                            .nOut(outputNum)
                            .build())
                    .build();
    }

    private static void predictImage(BufferedImage img, MultiLayerNetwork model) throws IOException {
        Java2DNativeImageLoader loader = new Java2DNativeImageLoader(img.getHeight(), img.getWidth(), 1, true);

        INDArray image = loader.asRowVector(img);

        ImagePreProcessingScaler imageScaler = new ImagePreProcessingScaler();
        imageScaler.transform(image);

        String output = generateOutputWithResult(model, image);
        log.info(output);
    }

    private static String generateOutputWithResult(MultiLayerNetwork model, INDArray image) {
        INDArray output = model.output(image);
        int predictedDigit = model.predict(image)[0];
        double probability = output.getDouble(predictedDigit) * 100;
        log.info("Prediction: {}", output);
        return String.format("Prediction: %s with probability: %.1f%%", predictedDigit, probability);
    }

}

有什么想法吗?谢谢!

所以我只需要将数组重塑为二维数组

public void TestExampleImage() throws IOException {
        MultiLayerNetwork loadedModel = MultiLayerNetwork.load(locationToSave, saveUpdater);
        BufferedImage myImage = ImageIO.read(new FileInputStream("fiveTestImage.png"));

        NativeImageLoader loader = new NativeImageLoader(myImage.getHeight(), myImage.getWidth(), 1);
        ImagePreProcessingScaler imageScaler = new ImagePreProcessingScaler();

        INDArray img = loader.asMatrix(myImage);
        INDArray reshaped = img.reshape(1,784);


        imageScaler.transform(reshaped);


        INDArray output = loadedModel.output(reshaped);
        log.info(output.toString());
}