将 Read/Write 向量归档的有效方法
Efficient Way to Read/Write Vectors to File
概述:经过几天的研究,我一直无法找到一种快速、有效的方法来 write/read 矢量 to/from 文件。我看到的大多数答案都涉及 pushing/popping 文件的每个单独元素 in/out。随着元素数量的增加,这非常耗时。此外,我一直无法找到对我的 特定 问题的答案的尝试。因此,请确保您的解决方案适用于我的特定情况(即阅读整个问题)。
我的问题:我有一个非常大的数据结构,其中包含有关图像的像素信息。有 60,000 张图像,每张图像有 784 个像素。每张图片都是一个手写数字的图像。因此,除了 60,000 * 784 像素之外,我还需要包含一个标签,以便我知道图像代表哪个数字。我使用的标签,从整个项目的范围来看是必要的,是一个包含 10 种可能性的向量,代表 0、1、2 ... 9,其中只有一个包含 '1'/'true',其余为'0'/'false'。此外,由于项目其余部分的线性代数要求,此数据结构要求将信息存储在 Armadillo 线性代数库中使用的 'Col' 结构中。因此,我希望 save/read in/from 文件的结构被声明为 std::vector<std::vector<arma::Col<double>>>
.
这是我现在用来保存数据的函数,以提供上下文:
void SaveTrainingData(vector<vector<Col<double>>> trainingData) //format: trainingData[60000][2][784, 10]
{
ofstream ofile("VectorizedTrainingData.dat", ios::binary);
for (int i = 0; i < trainingData.size(); i++)
for (int j = 0; j < trainingData[i].size(); j++)
for (int k = 0; k < trainingData[i][j].size(); k++)
ofile.write((char *)&trainingData[i][j][k], sizeof(double));
}
如果您有任何问题,请随时提问!提前致谢。
我没有用过犰狳,但由于 Col 是一个 1xN 矩阵并且应该线性存储,因此您可以摆脱 k
循环并一次性写出整个列:
ofile.write((char *)&trainingData[i][j][0], sizeof(double) * trainingData[i][j].size());
如果这不起作用,将元素从 Col 复制到本地向量,然后将它们写入文件(因为文件操作比复制一些双打要慢得多)。
您可能还想在写入所有元素之前写出向量的大小,以便知道有多少元素需要读入。
我不得不查找关于这个 Armadillo 库的文档,但看起来 Col
是一个连续的密集向量 class。我们可以依靠连续表示来消除嵌套循环,如下所示:
// format: trainingData[60000][2][784, 10]
void SaveTrainingData(const vector<vector<Col<double>>>& trainingData)
{
ofstream ofile("VectorizedTrainingData.dat", ios::binary);
const int numImages = trainingData.size();
for (int i = 0; i < numImages; i++)
{
const vector<Col<double>>& img = trainingData[i];
const int numCols = img.size();
for (int j = 0; j < numCols; j++)
{
const Col<double>& col = img[j];
ofile.write((char*)&col[0], col.size()*sizeof(double));
}
}
}
从一列中的一个元素到整个列对 write
的调用频率降低可能已经有所帮助。
可能值得对此进行衡量,以确保您实际上更 I/O 受限而不是内存受限。涉及所有这些列向量的向量的潜在内存碎片有点棘手。
例如,如果内部向量的大小始终相同(这似乎是每张图像都是 784 像素的情况),您可能能够通过连续 vector<Col>
,或者这个:
struct Image
{
Col pixels[768];
};
...
vector<Image> trainingData;
...或类似的东西。 .我不太明白线性代数是如何与图像表示联系起来的,但希望这能给出一个想法。
概述:经过几天的研究,我一直无法找到一种快速、有效的方法来 write/read 矢量 to/from 文件。我看到的大多数答案都涉及 pushing/popping 文件的每个单独元素 in/out。随着元素数量的增加,这非常耗时。此外,我一直无法找到对我的 特定 问题的答案的尝试。因此,请确保您的解决方案适用于我的特定情况(即阅读整个问题)。
我的问题:我有一个非常大的数据结构,其中包含有关图像的像素信息。有 60,000 张图像,每张图像有 784 个像素。每张图片都是一个手写数字的图像。因此,除了 60,000 * 784 像素之外,我还需要包含一个标签,以便我知道图像代表哪个数字。我使用的标签,从整个项目的范围来看是必要的,是一个包含 10 种可能性的向量,代表 0、1、2 ... 9,其中只有一个包含 '1'/'true',其余为'0'/'false'。此外,由于项目其余部分的线性代数要求,此数据结构要求将信息存储在 Armadillo 线性代数库中使用的 'Col' 结构中。因此,我希望 save/read in/from 文件的结构被声明为 std::vector<std::vector<arma::Col<double>>>
.
这是我现在用来保存数据的函数,以提供上下文:
void SaveTrainingData(vector<vector<Col<double>>> trainingData) //format: trainingData[60000][2][784, 10]
{
ofstream ofile("VectorizedTrainingData.dat", ios::binary);
for (int i = 0; i < trainingData.size(); i++)
for (int j = 0; j < trainingData[i].size(); j++)
for (int k = 0; k < trainingData[i][j].size(); k++)
ofile.write((char *)&trainingData[i][j][k], sizeof(double));
}
如果您有任何问题,请随时提问!提前致谢。
我没有用过犰狳,但由于 Col 是一个 1xN 矩阵并且应该线性存储,因此您可以摆脱 k
循环并一次性写出整个列:
ofile.write((char *)&trainingData[i][j][0], sizeof(double) * trainingData[i][j].size());
如果这不起作用,将元素从 Col 复制到本地向量,然后将它们写入文件(因为文件操作比复制一些双打要慢得多)。
您可能还想在写入所有元素之前写出向量的大小,以便知道有多少元素需要读入。
我不得不查找关于这个 Armadillo 库的文档,但看起来 Col
是一个连续的密集向量 class。我们可以依靠连续表示来消除嵌套循环,如下所示:
// format: trainingData[60000][2][784, 10]
void SaveTrainingData(const vector<vector<Col<double>>>& trainingData)
{
ofstream ofile("VectorizedTrainingData.dat", ios::binary);
const int numImages = trainingData.size();
for (int i = 0; i < numImages; i++)
{
const vector<Col<double>>& img = trainingData[i];
const int numCols = img.size();
for (int j = 0; j < numCols; j++)
{
const Col<double>& col = img[j];
ofile.write((char*)&col[0], col.size()*sizeof(double));
}
}
}
从一列中的一个元素到整个列对 write
的调用频率降低可能已经有所帮助。
可能值得对此进行衡量,以确保您实际上更 I/O 受限而不是内存受限。涉及所有这些列向量的向量的潜在内存碎片有点棘手。
例如,如果内部向量的大小始终相同(这似乎是每张图像都是 784 像素的情况),您可能能够通过连续 vector<Col>
,或者这个:
struct Image
{
Col pixels[768];
};
...
vector<Image> trainingData;
...或类似的东西。 .我不太明白线性代数是如何与图像表示联系起来的,但希望这能给出一个想法。