我正在尝试在字符序列(字符串)上创建和训练LSTM自动编码器。这仅是为了降维,即能够将最多T = 1000个字符的字符串表示为大小为N的固定长度矢量。为方便起见,令N =10。每个字符由大小为validChars的数组(在我的情况下为validChars = 77)。
我正在使用ComputationalGraph以便以后可以删除解码器层并将剩余的用于编码。通过查看dl4j-examples,我得出了以下结论:
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的字符串进行编码时,它会输出形状为[1000,10]的NDArray,而不是长度为10的一维向量。我的目的是用一个长度为10的向量。我想念什么?
答案 0 :(得分:0)
没人回答这个问题,我在dl4j-examples中找到了答案。因此,无论如何都会发布它,以防对某人有所帮助。
编码器和解码器LSTM之间的部分应如下所示:
.addVertex("thoughtVector",
new LastTimeStepVertex("encoderInput"), "encoder")
.addVertex("duplication",
new DuplicateToTimeSeriesVertex("decoderInput"), "thoughtVector")
.addVertex("merge",
new MergeVertex(), "decoderInput", "duplication")
重要的是,我们使用LastTimeStep进行多对一,然后使用DuplicateToTimeSeries进行一对多。这种方式“ thoughtVector”实际上是整个序列的单个向量表示。
在此处查看完整示例:https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/recurrent/encdec/EncoderDecoderLSTM.java,但请注意,该示例涉及单词级序列。我上面的网络适用于字符级序列,但是思想是相同的。