Я экспортировал обученную нейронную сеть LSTM из в этом примере из Matlab в ONNX. Затем я пытаюсь запустить эту сеть с ONNX Runtime C#. Однако, похоже, что я делаю что-то не так, и сеть не помнит своего состояния на предыдущем шаге.
Сеть должна реагировать на входные последовательности следующими выходными данными:
Ввод: [0,258881980200294]; Выход: [0.311363101005554]
Вход: [1.354147904050896]; Выход: [1.241550326347351]
Вход: [0.258881980200294, 1.354147904050896]; Вывод: [0.311363101005554, 1.391810059547424]
Первые два примера - это последовательности, состоящие только из одного элемента. Последний пример - это последовательность двух элементов. Эти выходы рассчитаны в Matlab. Я сбрасываю сеть в Matlab между выполнением ее с каждой новой последовательностью.
Затем я пытаюсь запустить ту же сеть, используя ONNX Runtime. Это мой C# код:
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using System;
using System.Collections;
using System.Collections.Generic;
namespace OnnxTest
{
public sealed class OnnxRuntimeTest
{
public OnnxRuntimeTest(ILogger logger)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
private const string modelPath = @"E:\Documents\MATLAB\NeuralNetworkExport\onnx_lstm_medic.onnx";
private readonly ILogger logger;
public void Run()
{
using (var session = new InferenceSession(modelPath))
{
// Input values from the example above:
var input1 = GenerateInputValue(0.258881980200294f);
var input2 = GenerateInputValue(1.35414790405090f);
// I create a container to push the first value:
var container = new List<NamedOnnxValue>() { input1 };
//Run the inference
using (var results = session.Run(container))
{
// dump the results
foreach (var r in results)
{
logger.Log(string.Format("Output for {0}", r.Name));
logger.Log(r.AsTensor<float>().GetArrayString());
// Outputs 0,3113631 - as expected
}
}
// The same code to push the second value:
var container2 = new List<NamedOnnxValue>() { input2 };
using (var results = session.Run(container2))
{
// dump the results
foreach (var r in results)
{
logger.Log(string.Format("Output for {0}", r.Name));
logger.Log(r.AsTensor<float>().GetArrayString());
// Outputs 1,24155 - as though this is the first input value
}
}
}
}
private NamedOnnxValue GenerateInputValue(float inputValue)
{
float[] inputData = new float[] { inputValue };
int[] dimensions = new int[] { 1, 1, 1 };
var tensor = new DenseTensor<float>(inputData, dimensions);
return NamedOnnxValue.CreateFromTensor("sequenceinput", tensor);
}
Как видите, второй сеанс запускается с результатом 1,24155 вместо ожидаемого значения (1,391810059547424), как если бы сеть все еще находилась в исходном состоянии. Похоже, я не сохраняю состояние LSTM-сети, но не могу найти, как это сделать в документации.
Итак, кто-нибудь знает, как заставить LSTM сохранять свое состояние?