既存の「ホストのみ」のバックプロパゲーションの実装を CUDA に移植する必要があります。ここではアルゴリズムの性質は問題ではないと思うので、その仕組みについてはあまり説明しません。私が重要だと思うのは、3次元すべてが動的に割り当てられる3次元配列を使用していることです。私はCUDA 5.0でVS2010を使用しています。そして私のデバイスは2.1です。元のホストオンリー コードはここからダウンロードできます → http://files.getwebb.org/view-cre62u4d.html
コードの要点:
- adult.data のパターンは、「pattern.h」にあるデータ構造を使用してメモリにロードされます。
- いくつかの多次元配列が割り当てられます
- 直前に割り当てられた配列を使用して、アルゴリズムがパターンに対して実行されます。
コードを実行したい場合は、kernel.cu の先頭にある PATH 定数を変更することを忘れないでください。また、「2」層、「5」ニューロン、および「0.00001」の学習率を使用することをお勧めします。ご覧のとおり、これは完全に機能します。「MSE」は改善しています。このアルゴリズムが何をしているのかわからない人のために、パターンに存在する 14 の変数に基づいて目標値を予測する方法を学習すると簡単に言っておきましょう。「MSE」が減少します。これは、各「エポック」後にアルゴリズムがミスを減らすことを意味します。
このコードをデバイスで実行するのに非常に長い時間を費やしました。そして、私はまだ成功していません。最後の試みは、配列を初期化してアルゴリズムを実行するコードを大きなカーネルにコピーするだけで行われました。これは再び失敗しました。このコードはそこからダウンロードできます → http://files.getwebb.org/view-cre62u4c.html
正確には、元のホストオンリー コードとの違いは次のとおりです。
- アルゴリズムで使用する f() と fder() は、デバイス 関数になります。
- パラメーターはハードコーディングされています: 2 層、5 ニューロン、学習率 0.00001
- 「w」配列は、rand() ではなく、固定値 (0.5) を使用して初期化されます
- データ構造はデバイスのメモリに割り当てられ、データはホストのメモリ内の adult.data からロードされた後、デバイスのメモリに送信されます
コードをカーネルで実行するために必要な最小限の変更を行ったと思います。「kernel_check_learningData」カーネルは、デバイスのメモリにロードされたパターンに関するいくつかの情報を表示し、ホストからデバイスにパターンを送信する次のコードが機能したことを証明します。
Data data;
Data* dev_data;
int* dev_t;
double* dev_x;
...
input_adult(PathFile, &data);
...
cudaMalloc((void**)&dev_data, sizeof(Data));
cudaMalloc((void**)&dev_t, data.N * sizeof(int));
cudaMalloc((void**)&dev_x, data.N * data.n * sizeof(double));
// Filling the device with t and x's data.
cudaMemcpy(dev_t, data.t, data.N * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(dev_x, data.x, data.N * data.n * sizeof(double), cudaMemcpyHostToDevice);
// Updating t and x pointers into devices Data structure.
cudaMemcpy(&dev_data->t, &dev_t, sizeof(int*), cudaMemcpyHostToDevice);
cudaMemcpy(&dev_data->x, &dev_x, sizeof(double*), cudaMemcpyHostToDevice);
// Copying N and n.
cudaMemcpy(&dev_data->N, &data.N, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(&dev_data->n, &data.n, sizeof(int), cudaMemcpyHostToDevice);
「w」配列を読み取るときに、順方向フェーズの開始時に明らかに失敗します。私はそれについての説明を見つけることができません。
2 つの可能性があります。
- デバイスのメモリにパターンを送信するコードは、適切に動作しているように見えるにもかかわらず、バグがあり、フォワードフェーズを開始するときにさらにバグを引き起こします。
- CUDA API が正常に動作していません!
私は非常に長い間、自分の間違いを必死に探しています。それで、コミュニティが私に助けを提供してくれるのではないかと思いました。
ありがとう。