Модель Seq2Seq (DL4J), делающая абсурдные предсказания

Я пытаюсь реализовать модель предиктора 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 можно найти здесь; Я внимательно прочитал это, чтобы увидеть, смогу ли я найти ошибку безрезультатно.

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

Ilya Yevlampiev 24.04.2020 09:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
1
334
0

Другие вопросы по теме

ValueError: Ввод 0 плотного слоя несовместим со слоем: ожидаемый min_ndim=2, найденный ndim=1. Получена полная форма: [Нет]
Категориальные метки с использованием перекрестной потери энтропии, точность не меняется | глубокое обучение
AttributeError: объект «DataFrame» не имеет атрибута «аллах1__27»
Как создать образ докера для Sagemaker, который не является частью оценщика amazon, чтобы создать конечную точку?
Недопустимый синтаксис в коде, написанном на питоне на бэкэнде тензорного потока
Как сохранить и загрузить процесс Гаусса для производства
Когда разбивать данные на обучающий и тестовый наборы данных
Как добавить столбцы меток кластера обратно в исходный фрейм данных-python для контролируемого обучения
Как построить тепловую карту на основе результатов GradientBoost?
Как я могу контролировать, сколько функций требуется моему алгоритму для определенной точности?