如何在Deeplearning4j中使用自定义数据模型?

问题描述 投票:1回答:2

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

我正在尝试使用的数据模型是一个java类,它包含一堆双精度数,由特定股票的报价创建,例如时间戳,开盘价,收盘价,最高价,最低价,成交量,技术指标1,技术指标2,我查询了一个互联网资源,example,(也是来自同一网站的其他几个指标)提供了我转换成我的数据模型的json字符串,以便于访问和存储在sqlite数据库中。

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

我没有看到使用任何提供的RecordReader转换我的数据模型的简洁方法,而没有先将它们转换为其他格式,如CSV或其他文件。我想避免这种情况,因为它会占用大量资源。似乎有更好的方法来做这个简单的案例。我错过了更好的方法吗?

java deep-learning lstm deeplearning4j
2个回答
3
投票

阮经天!

首先,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()方法的实现中,您应该返回包含下一批训练数据的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对您特别有用,因为它实现了LSTM网络,并且它具有自定义迭代器实现(可以作为实现其余方法的指南)。另外,有关NDArray的更多信息,this很有帮助。它提供了有关创建,修改和访问NDArray部分的详细信息。


1
投票

deeplearning4j创建者在这里。

您不应该在任何非常特殊的设置中创建数据集迭代器。你应该使用datavec。我们在很多地方介绍了这一点,从我们的数据vec页面到我们的示例:https://deeplearning4j.org/datavec https://github.com/deeplearning4j/dl4j-examples

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

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

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

顺便说一句,我很想知道你在哪里创建自己的迭代器,我们现在在我们的自述文件中没有这样做。如果你看到的另一个地方并不明显,我们很乐意解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.