Я пытаюсь создать и обучить 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. Чего мне не хватает?