Автоэнкодер для персонажа Time-Series с deeplearning4j - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь создать и обучить LSTM Autoencoder для последовательностей символов (строк). Это просто для уменьшения размерности, т. Е. Чтобы иметь возможность представлять строки длиной до 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, T] -> [77, T]

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

    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. Чего мне не хватает?

1 Ответ

0 голосов
/ 17 ноября 2018

Никто не ответил на вопрос, я нашел ответ в 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,, но обратите внимание, что пример имеет дело с последовательностями на уровне слов. Моя сеть выше работает с последовательностями уровня персонажа, но идея та же самая.

...