训练数据结构和访问



我正在用c++编写前馈神经网络的反向传播实现,我正在使用Armadillo库。现在,我正在用方法load加载Armadillo库中matrix类的训练数据。两个问题:

1)这是一个合理的选择存储预格式化(CSV),数字数据适合主存(<2GB)?当然,有比其他方法更好的方法来做到这一点,如果知道这是不是一个好的做法,那就太好了。我的一部分感觉这不是一个很好的选择来持有数据,因为可能有更多的数据结构/框架(像我应该访问一些SQL数据库或其他东西)。另一方面,我觉得数字数据根据定义就是矩阵,所以这应该很好。

2)在我的实现中,我需要对数据集进行采样而不进行替换,我看到了两种方法:要么我可以洗牌数据集的行,要么洗牌一个索引数据集的数组。在Armadillo库中有一个matrix类的shuffle方法,我怀疑被洗牌的是地址而不是行本身。这不就像对索引数组进行改组一样有效吗?

1)是的,这很好,这就是我要做的,但请注意,Armadillo矩阵是列为主的,因此您可能需要转置您加载的CSV。如果你的数据足够大,它不适合主存,你可以考虑编写一个自定义的CSV解析器,以流的方式查看数据(即一次一个点),从而减少你的RAM占用,或者你甚至可以使用mmap()映射一个充满打包双元的文件作为你的矩阵,让内核计算出什么时候需要交换。

2)因为所有矩阵数据都是连续存储的(即double*而不是double**), shuffle()将移动矩阵中的元素。在这种情况下,我通常做的是创建一个索引向量并对其进行洗牌:

uvec indices = linspace<uvec>(0, n, n);
shuffle(indices);
// Now loop over each shuffled point...
for (uword i = 0; i < n; ++i)
{
  // access the point with data.col(indices[i]) and do whatever
}

(上面的代码没有经过测试,但它应该可以工作,或者很容易被改编成可以工作的东西。)

就其价值而言,mlpack (http://www.mlpack.org/)确实有一个使用Armadillo的尚不稳定的神经网络基础设施,它可能值得您花时间检查;下面的链接是直接到相关的源代码,但是在Github和mlpack网站上闲逛应该会发现更好的文档。

https://github.com/mlpack/mlpack/tree/master/src/mlpack/methods/ann

最新更新