如何将自定义数据模型与 Deeplearning4j 一起使用?

How can I use a custom data model with Deeplearning4j?

基本问题是尝试使用自定义数据模型创建要在 deeplearning4j 网络中使用的 DataSetIterator。

我尝试使用的数据模型是一个 java class,它包含一堆双打,根据特定股票的报价创建,例如时间戳、开盘价、收盘价、高价, low, volume, 技术指标1, 技术指标2等 我查询了一个互联网资源 example(还有来自同一站点的其他几个指标),它提供了 json 字符串,我将这些字符串转换为我的数据模型以便于访问和存储在 sqlite 数据库中。

现在我有了这些数据模型的列表,我想用它们来训练 LSTM 网络,每个 double 都是一个特征。根据 Deeplearning4j 文档和几个示例,使用训练数据的方法是使用描述的 ETL 过程 here 创建一个 DataSetIterator,然后由网络使用。

我没有找到一种干净的方法来使用任何提供的 RecordReader 转换我的数据模型,而无需先将它们转换为某种其他格式,例如 CSV 或其他文件。我想避免这种情况,因为它会占用大量资源。似乎有更好的方法来处理这个简单的案例。有没有更好的方法我只是想念?

伊桑!

首先,Deeplearning4j 使用 ND4j 作为后端,因此您的数据最终必须转换为 INDArray 对象才能在您的模型中使用。如果您的试验数据是两个双精度数组,inputsArraydesiredOutputsArray,您可以执行以下操作:

INDArray inputs = Nd4j.create(inputsArray, new int[]{numSamples, inputDim});
INDArray desiredOutputs = Nd4j.create(desiredOutputsArray, new int[]{numSamples, outputDim});

然后您可以直接使用这些向量训练您的模型:

for (int epoch = 0; epoch < nEpochs; epoch++)
    model.fit(inputs, desiredOutputs);

或者您可以创建一个 DataSet 对象并将其用于训练:

DataSet ds = new DataSet(inputs, desiredOutputs);
for (int epoch = 0; epoch < nEpochs; epoch++)
    model.fit(ds);

但是创建自定义迭代器是最安全的方法,特别是在较大的集合中,因为它可以让您更好地控制数据并使事情井井有条。

在您的 DataSetIterator 实现中,您必须传递数据,并且在 next() 方法的实现中,您应该 return 包含下一批数据的 DataSet 对象训练数据。它看起来像这样:

public class MyCustomIterator implements DataSetIterator {
    private INDArray inputs, desiredOutputs;
    private int itPosition = 0; // the iterator position in the set.

    public MyCustomIterator(float[] inputsArray,
                            float[] desiredOutputsArray,
                            int numSamples,
                            int inputDim,
                            int outputDim) {
        inputs = Nd4j.create(inputsArray, new int[]{numSamples, inputDim});
        desiredOutputs = Nd4j.create(desiredOutputsArray, new int[]{numSamples, outputDim});
    }

    public DataSet next(int num) {
        // get a view containing the next num samples and desired outs.
        INDArray dsInput = inputs.get(
            NDArrayIndex.interval(itPosition, itPosition + num),
            NDArrayIndex.all());
        INDArray dsDesired = desiredOutputs.get(
            NDArrayIndex.interval(itPosition, itPosition + num),
            NDArrayIndex.all());

        itPosition += num;

        return new DataSet(dsInput, dsDesired);
    }

    // implement the remaining virtual methods...

}

您在上面看到的 NDArrayIndex 方法用于访问 INDArray 的部分内容。那么现在你可以用它来训练了:

MyCustomIterator it = new MyCustomIterator(
    inputs,
    desiredOutputs,
    numSamples,
    inputDim,
    outputDim);

for (int epoch = 0; epoch < nEpochs; epoch++)
    model.fit(it);

This example will be particularly useful to you, since it implements a LSTM network and it has a custom iterator implementation (which can be a guide for implementing the remaining methods). Also, for more information on NDArray, this 很有帮助。它提供了有关创建、修改和访问 NDArray.

部分的详细信息

deeplearning4j 创作者在这里。

除了所有 非常 特殊设置外,您不应该创建数据集迭代器。你应该使用 datavec。我们在很多地方都介绍了这一点,从我们的数据 vec 页面到我们的示例: https://deeplearning4j.konduit.ai/datavec/overview https://github.com/eclipse/deeplearning4j-examples

Datavec 是我们用于进行数据转换的专用库。您为您的用例创建自定义记录阅读器。由于遗留原因,Deeplearning4j 为某些数据集提供了一些“特殊”迭代器。其中许多出现在 datavec 存在之前。我们构建了 datavec 作为一种预处理数据的方式。

现在您可以使用 RecordReaderDataSetIterator、SequenceRecordReaderDataSetIterator(有关更多信息,请参阅我们的 javadoc)及其等效的多数据集。

如果这样做,您就不必担心屏蔽、线程安全或任何其他涉及快速加载数据的问题。

顺便说一句,我很想知道您是从哪里得到创建自己的迭代器的想法的,我们现在在我们的自述文件中有权利不这样做。如果您正在寻找的其他地方不明显,我们很乐意修复它。

编辑: 我已经更新了指向新页面的链接。这个 post 现在已经很老了。 请在此处查看新链接:

https://deeplearning4j.konduit.ai/datavec/overview https://github.com/eclipse/deeplearning4j-examples