"New Neural"은 MetaTrader 5 플랫폼용 신경망 엔진의 오픈 소스 프로젝트입니다. - 페이지 59

 

사람들이 GPU를 엉망으로 만들기로 결정했다면 다음을 고려하십시오. 한 반복이 다른 반복에 의존하지 않는 학습 알고리즘을 병렬화하는 것은 쉽습니다. 예를 들어, 한 세대에 수백 개의 네트워크를 계산하는 것이 서로 의존하지 않는 유전, 맨하탄(모든 솔루션의 무딘 열거) 또는 위원회의 독립 네트워크 최적화. 그러나 그러한 알고리즘은 거의 없습니다. 경사 하강법은 한 반복이 다른 반복에 의존하기 때문에 병렬화하기가 더 어렵습니다. 이러한 경우 동일한 레이어에 있는 뉴런의 계산을 병렬 스트림으로 분할해야 하는데, 이것이 항상 사소한 것은 아닙니다.

 

... 그리고 유전학은 네트워크의 필수적인 부분이 아니라 별도의 외부 알고리즘입니다.

여기에서 네트워크의 사람들은 병렬화를 원합니다.

 
방해하지 않습니다.
 
더엑스퍼트 :

... 그리고 유전학은 네트워크의 필수적인 부분이 아니라 별도의 외부 알고리즘입니다.

여기에서 네트워크의 사람들은 병렬화를 원합니다.

처음에는 작동하는 것을 작성한 다음 병렬화하십시오. 가능한 오류로 인해 코드가 오랫동안 디버그되는 위치: 여기에서 다른 어레이에 할당할 메모리 양을 알아야 하고, 메모리에서 이러한 어레이를 로드 및 언로드하기 위한 명령 작성, 스레드 동기화 등을 해야 합니다. 다음은 kud의 코드(전체 코드의 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를 엉망으로 만들기로 결정했다면 다음을 고려하십시오. 한 반복이 다른 반복에 의존하지 않는 학습 알고리즘을 병렬화하는 것은 쉽습니다. 예를 들어, 한 세대에 수백 개의 네트워크를 계산하는 것이 서로 의존하지 않는 유전, 맨하탄(모든 솔루션의 무딘 열거) 또는 위원회의 독립 네트워크 최적화. 그러나 그러한 알고리즘은 거의 없습니다. 경사 하강법은 한 반복이 다른 반복에 의존하기 때문에 병렬화하기가 더 어렵습니다. 이러한 경우 동일한 레이어에 있는 뉴런의 계산을 병렬 스트림으로 분할해야 하며, 이는 항상 사소한 것은 아닙니다.

GPU에서는 간단한 계산, 한 주기 내에서 간단한 계산만 병렬로 수행할 수 있으므로 GPU에서 다른 FF 유전학 계산을 구현하는 것은 매우 어려울 것입니다(효과적인지 의심스럽습니다).

GPU에서 가속의 특성은 한 번의 반복 내에서 출력에서 입력의 독립성과 작업의 균일성에 있습니다(위에서 gpwr 언급). 위에서 우리가 종합적으로 추론한 레이어의 정의와 매우 유사하지 않습니까? 이것이 내가 주요 작업 개체로 레이어를 선택하고 레이어에 첨부된 정보 개체로만 뉴런 개체를 제안한 이유입니다.

 
gpwr :

처음에는 작동하는 것을 작성한 다음 병렬화하십시오. 가능한 오류로 인해 코드가 오랫동안 디버그되는 위치: 여기에서 다른 어레이에 할당할 메모리 양을 알아야 하고, 메모리에서 이러한 어레이를 로드 및 언로드하기 위한 명령 작성, 스레드 동기화 등을 해야 합니다. 다음은 kudovsky 코드(전체 코드의 1/20)입니다. 단일 명령은 네트워크 학습 알고리즘 자체와 직접적인 관계가 없습니다. 나에게 그것은 모두 중국인이다.

...

그래서 아무도 반대하지 않습니다. 우리는 순차 코드를 작성하고 디버그할 것입니다. 저는 코드의 일부 섹션을 병렬화할 가능성만 옹호합니다. 이러한 섹션은 "GPU"를 추가하여 함수 이름을 지정하거나 주기 시작 부분에 주석으로 표시하여 즉시 표시할 수 있습니다. 여기 사람들이 알 수 있도록 그래프를 사용할 가능성이 있습니다. 프로세서.

 
gpwr :

처음에는 작동하는 것을 작성한 다음 병렬화하십시오. 가능한 오류로 인해 코드가 오랫동안 디버그되는 위치: 여기에서 다른 어레이에 할당할 메모리 양을 알아야 하고, 메모리에서 이러한 어레이를 로드 및 언로드하기 위한 명령 작성, 스레드 동기화 등을 해야 합니다. 다음은 kud의 코드(전체 코드의 1/20)입니다. 단일 명령은 네트워크 학습 알고리즘 자체와 직접적인 관계가 없습니다. 나에게 그것은 모두 중국인이다.

CUDA는 OPP를 완벽하게 지원합니다.

다음은 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 redko syuda zahodit'. Esli est' voprosi ili interes k sovmestnim razrabotkam, pishite na moy yahoo email (ukazan v profile).

EngiNeuro 프로젝트에 행운을 빕니다!

 

학습 알고리즘 에 대한 예를 제공하기 위한 옵션:

  • 조각으로
  • 무작위 그룹
  • 슬라이딩 그룹
  • 한번에

잊지 않으셨나요?


나는 프로젝트의 골격을 준비했고, 며칠 동안 그것을 해결하고 토론을 위해 게시 할 것입니다 ...
 
우크라이나 :

학습 알고리즘에 대한 예를 제공하기 위한 옵션:

  • 조각으로
  • 무작위 그룹
  • 슬라이딩 그룹
  • 한번에

잊지 않으셨나요?


나는 프로젝트의 골격을 준비했고, 며칠 동안 그것을 해결하고 토론을 위해 게시 할 것입니다 ...

그건 그렇고 - 이해합니다.

그리고 다른 옵션은 이해하지 못했습니다. 한 번에 모든 예제 교육을 신청하려면 어떻게 해야 합니까? - 아니면 바보?