2015-11-26 22 views
5

概要:数日間の研究の後、私はベクトルをファイルに/から読み書きするための高速かつ効率的な方法を見つけることができませんでした。私が見てきた答えの大部分は、個々の要素をファイルの内外にプッシュ/ポップすることです。要素の数が増えると、これは非常に時間がかかります。また、私はの問題に答える試みを見つけることができませんでした。だから、あなたの解決策が私のの特定のの状況(すなわち、の質問全体を読む)で動くことを確認してください。ベクターをファイルに読み書きする効率的な方法

問題:イメージに関するピクセル情報を含む非常に大きなデータ構造があります。それぞれ784ピクセルの60,000枚の画像があります。各画像は、手書き数字の画像である。したがって、60,000 * 784ピクセルに加えて、ラベルを含める必要があるので、イメージが表す桁を知る必要があります。私が使用しているラベルは、プロジェクト全体の範囲で見ているときに必要なもので、0,1,2、... 9を表す10の可能性のベクトルです。そのうちの1つに '1'/' true '、残りは' 0 '/' false 'です。さらに、このデータ構造は、プロジェクトの残りの部分で線形代数要件が必要なため、アルマジロ線形代数ライブラリで利用される 'Col'構造で情報を格納する必要があります。ですから、ファイルを保存/読み込みする構造は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)); 
} 

ご質問がありましたら、お気軽にお問い合わせ下さい!前もって感謝します。

+0

'void SaveTrainingData(vector >> trainingData)'ベクトルを値渡ししなかった場合、関数呼び出しだけではスピードアップする可能性があります。また、最適化が有効になっているか、最適化されていないバージョンのプログラムを "デバッグ"して実行していますか?また、ディスクI/Oは、いくつかの点で最適化するのは難しいことですが、ディスクのパフォーマンスには多くの問題があります。 – PaulMcKenzie

答えて

0

私はこのアルマジロライブラリのドキュメントを検索しなければならなかったが、それが表示されます。 Colは、連続した密なベクトルクラスです。我々はそうように、ネストされたループを除去するために連続した表現に依存することができる:

// 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)); 
     } 
    } 
} 

列全体の列内の1つの要素からwriteへのコールに減少した頻度がすでにビットを助けることができます。

これは、実際にはメモリにバインドされているのではなく、より多くのI/Oバインドが行われていることを確認するために役立つかもしれません。これらの列のベクトルのすべてのベクトルを含む潜在的なメモリの断片化は少し難解です。

たとえば、内部ベクトルのサイズが常に同じ場合(すべての画像が784ピクセルの場合)、連続したvector<Col>、またはこれを使って、より良い結果を得ることができます。

struct Image 
{ 
    Col pixels[768]; 
}; 
... 
vector<Image> trainingData; 

...などです。 。私は、線形代数が画像担当者にどのように結びついているかはかなり分かりませんでしたが、うまくいけばそれが考えられます。

+0

ありがとう!これは確かに私を助けてくれます。線形代数は後で残りのプロジェクトと結びついているので、ここではあまり関係がありません。プログラムの残りの部分で必要です。 – Rob

+0

ファイルを読む際に追加の入力がありますか? – Rob

+0

@Rob読書は書くことでかなり対称でなければならない - あなたはほとんど同じことをすることができる。私たちができる余分なものはないと思ってください - バイナリデータのかなりまっすぐなI/O。 –

0

私はアルマジロを使用していないが、コル以来、あなたはkループを取り除くと、一度に列全体を書き出す得ることができ、1xNの行列であり、それが直線的に保存する必要があります。

ofile.write((char *)&trainingData[i][j][0], sizeof(double) * trainingData[i][j].size()); 

これでうまくいかない場合は、Colの要素をローカルベクトルにコピーしてからファイルに書き出します(ファイル操作はいくつかの倍音をコピーするよりもはるかに遅くなるため)。

あなたはおそらくもあなたが読むためにありますどのように多くの知っているので、すべての要素を書き込む前に、あなたのベクトルの大きさを書きたい。

+0

ありがとう!私はそれを試してみましょう!また、私は通常、ベクトルのサイズを要素の前にファイルに書きますが、今回は、すべてのベクトルのサイズを事前に知っているので、できるだけ多くの不要なデータを取り除くために、今回は取り除きました。 – Rob

関連する問題