使用 deeplearning4j 对我自己的图像进行异常检测

Do Anomaly detection on my own images use deeplearning4j

我将使用 deeplearning4j 平台上的示例对自己的图像进行异常检测。我像这样更改代码:

    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");
    }

训练时抛出异常:

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)

我的输入数据集似乎有 4 列,而它只需要 2 列,所以问题是如何转换 imagerecorderread 或其他东西以使其正确 运行?

所以首先,你可能想了解什么是张量: http://nd4j.org/tensor

记录 reader returns 一张多维图像,除非您计划在部分训练中使用 CNN,否则您需要将其展平以便与 2d 神经网络一起使用.

如果你看一下异常(同样你真的应该熟悉 ndarrays,它们不是新的并且在每个深度学习库中都有使用):你会看到一个形状: [128, 1, 28, 28]

这是按通道按行 x 列的批量大小。你需要做一个: .setInputType(InputType.convolutional(28,28,1))

这将告诉 dl4j 它需要将 4d 展平为 2d。在这种情况下,它表示有 28 x 28 x 1

的行、列、通道

如果将它添加到配置的底部,它将起作用。

值得注意的是,如果您正在尝试进行异常检测,我们也有变分自动编码器,您可能也想看看。