"New Neural "は、MetaTrader 5プラットフォーム用のオープンソース・ニューラルネットワークエンジンプロジェクトです。 - ページ 59

 

皆さん、もしGPUに手を出すなら、次のようなことを考えてみてください。1回の反復が他の反復に依存しないような学習アルゴリズムの並列化は容易である。例えば、1世代で数百のネットワークを計算しても互いに依存しない遺伝的なもの、マンハッタン(全解のダム列挙)、委員会での独立したネットワークの最適化などです。しかし、そのようなアルゴリズムは少ない。勾配降下法に基づく方法は、1つの反復が他の反復に依存するため、並列化がより困難になる。 その場合、同じ層のニューロンの計算を並列スレッドに分割する必要があるが、これは必ずしも容易なことではない。

 

...そして、遺伝学はネットワークの一部ではなく、外部のアルゴリズムとして独立したものです。

ここの人たちはネットワークを並行させたがるんです。

 
一方が他方を排除するものではありません。
 
TheXpert:

...そして、遺伝学はネットワークの一部ではなく、外部のアルゴリズムとして独立したものです。

ここにいる人たちは、ネットワークの並列化を望んでいます。

最初はうまくいくものを書いて、それを並列化する。KUDavのコードは、さまざまな配列に割り当てるメモリの量を把握し、これらの配列をメモリからロード、アンロードするコマンドを書き、スレッドを同期させるなど、エラーの可能性があるためデバッグに長い時間がかかるのです。ここでは、クダコードの断片(全体の1/20)を紹介します。なお、どのコマンドもネットワーク学習 アルゴリズム自体には直接関係しない。私には全部中国語なんですけどね。

#define SHARED_BUFFER_SIZE 512

#define MAX_DATA_SIZE 227

#define MAX_FILTER_33_SIZE 73

#define MAX_MASK_23_SIZE 27

#define MAX_MASK_34_SIZE 27

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

__constant__ float M33_Filter[ MAX_FILTER_33_SIZE ][ MAX_FILTER_33_SIZE ];

__constant__ float M23_Mask [ MAX_MASK_23_SIZE ][ MAX_MASK_23_SIZE ];

__constant__ float M34_Mask [ MAX_MASK_34_SIZE ][ MAX_MASK_34_SIZE ];

__shared__ float SharedBuf[ SHARED_BUFFER_SIZE ];

#define ALLIGN 32

#define ROUND_UP( val ) ( ( ( ( val ) + ALLIGN - 1 ) / ALLIGN ) * ALLIGN )

__host__ __device__ int Get2DIndex( int dataSize, int row, int col )

{

int dataSizeP = ROUND_UP( dataSize );

int idx = row * dataSizeP + col;

//assert( idx >= 0 && idx < dataSize * dataSizeP );

return idx;

}

__host__ __device__ float Get2D( float *data, int dataSize, int row, int col )

{

int idx = Get2DIndex( dataSize, row, col );

return data[ idx ];

}

__host__ __device__ void Set2D( float *data, int dataSize, int row, int col, float val )

{

int idx = Get2DIndex( dataSize, row, col );

data[ idx ] = val;

}

__host__ __device__ int Get4DIndex( int dataSize, int filtSize, int row, int col, int rowF, int colF )

{

int dataSizeP = ROUND_UP( dataSize );

int filtSizeP = ROUND_UP( filtSize );

int idx;

idx = row;

idx = idx * filtSizeP + rowF;

idx = idx * filtSizeP + colF;

idx = idx * dataSizeP + col;

//assert( idx >= 0 && idx < dataSize * dataSizeP * filtSizeP * filtSizeP );

return idx;

}

__host__ __device__ float Get4D( float *filt, int dataSize, int filtSize, int row, int col, int rowF, int colF )

{

int idx = Get4DIndex( dataSize, filtSize, row, col, rowF, colF );

return filt[ idx ];

}

__host__ __device__ void Set4D( float *filt, int dataSize, int filtSize, int row, int col, int rowF, int colF, float val )

{

int idx = Get4DIndex( dataSize, filtSize, row, col, rowF, colF );

filt[ idx ] = val;

}

__global__ void Calc_1_kernel( float* o2, float* i3, float* fi3, float* o3, float* o3tmp, float *w23, int n2, int n3, int n23, int h23, int ntot23, float a3 )

{

int numBlocks = gridDim.x;

int numThreads = blockDim.x;

int blockId = blockIdx.x;

int threadId = threadIdx.x;

///* DEBUG */for( int blockId = 0; blockId < numBlocks; ++blockId )

{

for( int i = blockId; i < n3; i += numBlocks )

{

///* DEBUG */for( int threadId = 0; threadId < numThreads; ++threadId )

{

// clear output

for( int j = threadId; j < n3; j += numThreads )

{

Set2D( fi3, n3, i, j, 0 );

}

}

__syncthreads();

// process 'n23' rows

for( int dx = 0; dx < n23; ++dx )

{

int x;

if( n2 == n3 )

{

x = i + dx - h23;

if( x < 0 ) x += n2;

if( x >= n2 ) x -= n2;

}

else

{

x = i + dx;

}

///* DEBUG */for( int threadId = 0; threadId < numThreads; ++threadId )

{

// read one row of input data to shared memory ( row 'x' )

int dj;

if( n2 == n3 )

{

dj = h23;

}

else

{

dj = 0;

}

for( int jj = threadId; jj < n2; jj += numThreads )

{

float o2Val = Get2D( o2, n2, x, jj );

SharedBuf[ jj + dj ] = o2Val;

}

if( n2 == n3 )

{

for( int dj = threadId; dj < h23; dj += numThreads )

{

SharedBuf[ dj ] = SharedBuf[ n2 + dj ];

}

for( int dj = threadId; dj < h23 + 1; dj += numThreads )

{

SharedBuf[ n2 + h23 + dj ] = SharedBuf[ h23 + dj ];

}

}

}

__syncthreads();

///* DEBUG */for( int threadId = 0; threadId < numThreads; ++threadId )

{

// filter one row

for( int j = threadId; j < n3; j += numThreads )

{

float fi3Val = Get2D( fi3, n3, i, j );

for( int dy = 0; dy < n23; ++dy )

{

float w23Val = Get4D( w23, n3, n23, i, j, dx, dy );

float o2Val = SharedBuf[ j + dy ];

fi3Val += o2Val * w23Val;

}

Set2D( fi3, n3, i, j, fi3Val );

}

}

__syncthreads();

}

__syncthreads();

 
gpwr

皆さん、もしGPUに手を出すなら、次のようなことを考えてみてください。1回の反復が他の反復に依存しないような学習アルゴリズムの並列化は容易である。例えば、1世代で数百のネットワークを計算しても互いに依存しない遺伝的なもの、マンハッタン(全解のダム列挙)、委員会での独立したネットワークの最適化などです。しかし、そのようなアルゴリズムはほとんどない。勾配降下法に基づく方法は、1つの反復が他の反復に依存するため、並列化が難しくなります。 その場合、同じ層のニューロンの計算を並列スレッドに分割する必要がありますが、これは必ずしも簡単なことではありません。

GPUでは、単純な計算、1サイクル内の単純な計算しか並列化できないので、遺伝学の異なるフェーズの計算をGPUで実装することは非常に難しい(効果があるかどうかも疑問)です。

GPUによる高速化の本質は、同一イテレーション内での入力と出力の独立性と、(前述のgpwrが 指摘する)演算の均一性にある。それは、上で同僚が導き出したレイヤーの定義と非常に似ているのではないでしょうか?だから、レイヤーをメインの作業オブジェクトとして、ニューロンオブジェクトはレイヤーに付随する情報エンティティとしてのみ区別することを提案したのです。

 
gpwr

最初はうまくいくものを書いて、それを並列化する。KUDAWのコードは、さまざまな配列に割り当てるメモリの量を把握し、これらの配列をメモリからロードおよびアンロードするコマンドを記述し、スレッドを同期させるなど、エラーの可能性があるためデバッグに長い時間がかかります。ここでは、クダコードの断片(全体の1/20)を紹介します。なお、どのコマンドもネットワーク学習アルゴリズム自体には直接関係しない。私には全部中国語なんですけどね。

...

このような断片は、「GPU」という付録で関数名をつけて一度にマークしたり、ループの最初にコメントをつけてマークしたりすることができます。グラフプロセッサーの可能性を知ってもらうために、ここで紹介します。

 
gpwr:

最初はうまくいくものを書いて、それを並列化する。KUDAVのコードは、さまざまな配列に割り当てるメモリ量を把握し、これらの配列をメモリからロードおよびアンロードするコマンドを記述し、スレッドを同期させるなど、エラーの可能性があるためデバッグに長い時間がかかります。ここでは、クダコードの断片(全体の1/20)を紹介します。なお、どのコマンドもネットワーク学習アルゴリズム自体には直接関係しない。私には全部中国語なんですけどね。

CUDAはSRFを最大限にサポートします。

以下は,hyp.tangent のコードの一部です.

#ifndef LAYER_TANH_H
#define LAYER_TANH_H

#ifndef CUDA
        #include <map>
        #include <boost/regex.hpp>
        extern std::map<std::string,int> mapObjects;
#endif
//---------------------------------------------------------------------------//
//                               CLayerTanh                                  //
//---------------------------------------------------------------------------//

namespace
#ifdef CUDA
        cuda
#else
        host
#endif
{

class CLayerTanh : public CLayerWSum
{
public:

#ifdef CUDA     
        __device__ static void run ( CLayer* layer )
        {
                CLayerTanh* L = static_cast<CLayerTanh*>(layer);
                if ( threadIdx.x < L->neuronCount )
                {
                        CLayerWSum::run(layer);
                        float * v = L->getNeuronPtr (threadIdx.x);
                        *v = tanh(*v);
                };
        }
#endif

};

} // namespace

#endif // LAYER_TANH

OpenCLの専門家がここにいるのは良いことです。技術に関する実質的な対話と議論は、プロジェクト 全体に利益をもたらすでしょう。

ニューラルネットワークは、あらゆる技術(MQL5、C++、OpenCL、CUDA)を使って実装され、ユーザーは自分の好みとハードウェア能力に応じて選択できるようになると確信しています。

 

Rebyata, ya budu seldom syuda zahodit'.このサイトへのアクセスは、YahooのEメール(プロフィール)をご利用ください。

EngiNeuroプロジェクト、頑張ってください。

 

学習アルゴリズムに サンプルを提出するためのオプション。

  • ひとつひとつ丁寧に
  • ランダムグループにおいて
  • スライディンググループ
  • 一挙に公開

忘れ物はないですか?


プロジェクトの 枠組みを用意したから、2、3日中に議論にかけようかな...。
 
ウラン です。

学習アルゴリズムにサンプルを提出するためのオプション。

  • ひとつひとつ丁寧に
  • ランダムグループ。
  • スライディンググループにて。
  • 一度に全部。

何か忘れていませんか?


プロジェクトの骨格を準備し、2、3日で揺さぶりをかけ、議論にかける......。

一人一人、なるほどね。

それ以外の選択肢は......よくわからないですね。すべての事例を一度に提出し、学習するにはどうすればよいですか?- それとも私が馬鹿なのでしょうか?