Я пытаюсь реализовать модель предиктора Seq2Seq в DL4J. В конечном итоге я хочу использовать временной ряд точек данных INPUT_SIZE для прогнозирования следующих временных рядов точек данных OUTPUT_SIZE с использованием модели этого типа. Каждая точка данных имеет numFeatures функции. Теперь у DL4J есть пример кода, объясняющий, как реализовать очень простую модель Seq2Seq. Я добился некоторого прогресса, распространив их пример на свои нужды; приведенная ниже модель компилируется, но прогнозы, которые она делает, бессмысленны.
ComputationGraphConfiguration configuration = new
NeuralNetConfiguration.Builder()
.weightInit(WeightInit.XAVIER)
.updater(new Adam(0.25))
.seed(42)
.graphBuilder()
.addInputs("in_data", "last_in")
.setInputTypes(InputType.recurrent(numFeatures), InputType.recurrent(numFeatures))
//The inputs to the encoder will have size = minibatch x featuresize x timesteps
//Note that the network only knows of the feature vector size. It does not know how many time steps unless it sees an instance of the data
.addLayer("encoder", new LSTM.Builder().nIn(numFeatures).nOut(hiddenLayerWidth).activation(Activation.LEAKYRELU).build(), "in_data")
//Create a vertex indicating the very last time step of the encoder layer needs to be directed to other places in the comp graph
.addVertex("lastTimeStep", new LastTimeStepVertex("in_data"), "encoder")
//Create a vertex that allows the duplication of 2d input to a 3d input
//In this case the last time step of the encoder layer (viz. 2d) is duplicated to the length of the timeseries "sumOut" which is an input to the comp graph
//Refer to the javadoc for more detail
.addVertex("duplicateTimeStep", new DuplicateToTimeSeriesVertex("last_in"), "lastTimeStep")
//The inputs to the decoder will have size = size of output of last timestep of encoder (numHiddenNodes) + size of the other input to the comp graph,sumOut (feature vector size)
.addLayer("decoder", new LSTM.Builder().nIn(numFeatures + hiddenLayerWidth).nOut(hiddenLayerWidth).activation(Activation.LEAKYRELU).build(), "last_in","duplicateTimeStep")
.addLayer("output", new RnnOutputLayer.Builder().nIn(hiddenLayerWidth).nOut(numFeatures).activation(Activation.LEAKYRELU).lossFunction(LossFunctions.LossFunction.MSE).build(), "decoder")
.setOutputs("output")
.build();
ComputationGraph net = new ComputationGraph(configuration);
net.init();
net.setListeners(new ScoreIterationListener(1));
То, как я структурирую свои входные/помеченные данные, заключается в том, что я разделяю входные данные между первыми наблюдениями временного ряда INPUT_SIZE - 1 (соответствующими входным данным in_data в ComputationGraph), а затем наблюдениями последнего временного ряда (соответствующими входным данным lastIn). Метки — это один временной шаг в будущем; чтобы делать прогнозы, я просто звоню net.output()OUTPUT_SIZE раз, чтобы получить все прогнозы, которые я хочу. Чтобы лучше это увидеть, вот как я инициализирую свой ввод/метки:
INDArray[] input = new INDArray[] {Nd4j.zeros(batchSize, numFeatures, INPUT_SIZE - 1), Nd4j.zeros(batchSize, numFeatures, 1)};
INDArray[] labels = new INDArray[] {Nd4j.zeros(batchSize, numFeatures, 1)};
Я считаю, что моя ошибка связана с ошибкой в архитектуре моего вычислительного графа, а не в том, как я подготавливаю свои данные/делаю прогнозы/что-то еще, поскольку я делал другие мини-проекты с более простой архитектурой и не имел никаких проблем.
Мои данные нормализованы, чтобы иметь среднее значение 0 и стандартное значение. отклонение равно 1. Таким образом, большинство записей должно быть около 0, однако большинство прогнозов, которые я получаю, представляют собой значения с абсолютным значением, намного превышающим ноль (порядка 10–100 с). Это явно не правильно. Я работал над этим в течение некоторого времени и не смог найти проблему; любые предложения о том, как исправить это, будут высоко оценены.
Другие ресурсы, которые я использовал: Пример модели Seq2Seq можно найти здесь, начиная со строки 88. Документацию по ComputationGraph можно найти здесь; Я внимательно прочитал это, чтобы увидеть, смогу ли я найти ошибку безрезультатно.




вы определили ошибку?