Автоэнкодер для временных рядов символов с помощью deeplearning4j

Я пытаюсь создать и обучить автоэнкодер LSTM последовательностям символов (строкам). Это сделано просто для уменьшения размерности, т. е. для того, чтобы иметь возможность представлять строки до T = 1000 символов в виде векторов фиксированной длины размера N. Ради этого примера пусть N = 10. Каждый символ закодирован горячим способом массивы размера validChars (в моем случае validChars = 77).

Я использую ComputationalGraph, чтобы позже удалить слои декодера и использовать оставшиеся для кодирования. Глядя на dl4j-примеры, я пришел к следующему:

    ComputationGraphConfiguration conf = new NeuralNetConfiguration.Builder()
            .seed(12345)
            .l2(0.0001)
            .weightInit(WeightInit.XAVIER)
            .updater(new Adam(0.005))
            .graphBuilder()
            .addInputs("input")
            .addLayer("encoder1", new LSTM.Builder().nIn(dictSize).nOut(250)
                    .activation(Activation.TANH).build(), "input")
            .addLayer("encoder2", new LSTM.Builder().nIn(250).nOut(10)
                    .activation(Activation.TANH).build(), "encoder1")

            .addVertex("fixed", new PreprocessorVertex(new RnnToFeedForwardPreProcessor()), "encoder2")
            .addVertex("sequenced", new PreprocessorVertex(new FeedForwardToRnnPreProcessor()), "fixed")

            .addLayer("decoder1", new LSTM.Builder().nIn(10).nOut(250)
                    .activation(Activation.TANH).build(), "sequenced")
            .addLayer("decoder2", new LSTM.Builder().nIn(250).nOut(dictSize)
                    .activation(Activation.TANH).build(), "decoder1")

            .addLayer("output", new RnnOutputLayer.Builder()
                    .lossFunction(LossFunctions.LossFunction.MCXENT)
                    .activation(Activation.SOFTMAX).nIn(dictSize).nOut(dictSize).build(), "decoder2")

            .setOutputs("output")
            .backpropType(BackpropType.TruncatedBPTT).tBPTTForwardLength(tbpttLength).tBPTTBackwardLength(tbpttLength)
            .build();

При этом я ожидал, что количество признаков будет следовать по пути: [77,T] -> [250,T] -> [10,T] -> [10] -> [10,T] -> [250, Т] -> [77, Т]

Я обучил эту сеть и удалил часть декодера следующим образом:

    ComputationGraph encoder = new TransferLearning.GraphBuilder(net)
            .setFeatureExtractor("fixed")
            .removeVertexAndConnections("sequenced")
            .removeVertexAndConnections("decoder1")
            .removeVertexAndConnections("decoder2")
            .removeVertexAndConnections("output")
            .addLayer("output", new ActivationLayer.Builder().activation(Activation.IDENTITY).build(), "fixed")
            .setOutputs("output")
            .setInputs("input")
            .build();

Но когда я кодирую строку длиной 1000 с помощью этого кодировщика, он выводит NDArray формы [1000, 10] вместо одномерного вектора длины 10. Моя цель — представить всю последовательность из 1000 символов одним вектором длина 10. Что мне не хватает?


person Gena L    schedule 10.11.2018    source источник


Ответы (1)


На вопрос никто не ответил, нашел ответ в dl4j-примерах. Так что все равно опубликую, вдруг кому пригодится.

Часть между кодировщиком и декодером LSTM должна выглядеть так:

            .addVertex("thoughtVector",
                    new LastTimeStepVertex("encoderInput"), "encoder")
            .addVertex("duplication",
                    new DuplicateToTimeSeriesVertex("decoderInput"), "thoughtVector")
            .addVertex("merge",
                    new MergeVertex(), "decoderInput", "duplication")

Важно, чтобы мы выполняли «многие к одному» с помощью LastTimeStep, а затем — «один ко многим» с помощью DuplicateToTimeSeries. Таким образом, «мысленный вектор» на самом деле представляет собой единое векторное представление всей последовательности.

См. полный пример здесь: https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/recurrent/encdec/EncoderDecoderLSTM.java, но обратите внимание, что пример касается последовательностей на уровне слов. Моя сеть выше работает с последовательностями на уровне символов, но идея та же.

person Gena L    schedule 17.11.2018