"新神经 "是MetaTrader 5平台的一个开源神经网络引擎项目。 - 页 59

 

伙计们,如果你决定要用GPU捣乱,请考虑以下几点。将一个迭代独立于另一个迭代的学习算法并行化是很容易的。例如,遗传,在一代中计算数百个网络并不相互依赖,曼哈顿(所有解决方案的哑巴列举),或委员会中独立网络的优化。但这样的算法是少数。基于梯度下降的方法将更难并行化,因为一个迭代依赖于另一个迭代。 在这种情况下,有必要将同一层的神经元的计算分成并行线程,这并不总是微不足道的。

 

...而遗传学不是网络的一部分,而是一个独立的外部算法。

这里的人们想要平行网络。

 
一个并不排除另一个。
 
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捣乱,请考虑以下几点。将一个迭代独立于另一个迭代的学习算法并行化是很容易的。例如,遗传,在一代中计算数百个网络并不相互依赖,曼哈顿(所有解决方案的哑巴列举),或委员会中独立网络的优化。但这样的算法是少数。基于梯度下降的方法将更难并行化,因为一个迭代依赖于另一个迭代。 在这种情况下,你需要将同一层的神经元的计算分成并行线程,这并不总是微不足道的。

在GPU上,我们只能够并行计算,在一个周期内进行简单的计算,所以在GPU上实现遗传学不同阶段的计算将是非常困难的(我怀疑这将是有效的)。

GPU加速的本质在于同一迭代中输入和输出的独立性以及操作的统一性(正如上文gpwr 指出的)。这不是和我们上面合议的层的定义非常相似吗。这就是为什么我建议将层区分为主要的工作对象,而将神经元对象仅作为附属于层的一个信息实体。

 
gpwr:

编写一些一开始能用的东西,然后再把它并行化。由于可能出现的错误,KUDAV的代码需要很长的时间来调试:你需要知道为不同的数组分配多少内存,编写命令从内存中加载和卸载这些数组,同步线程等等。这里是库达代码的一个片段(整个代码的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'.如果您对我们的服务感兴趣,请发送电子邮件到我的雅虎邮箱(在个人主页上)。

祝你在EngiNeuro项目上取得好成绩!

 

向学习算法 提交实例的选项。

  • 一个接一个
  • 在随机组中
  • 滑动组
  • 一下子就好了

你没有忘记什么吗?


我已经准备了一个项目 框架,过几天我就把它拿出来讨论...
 
Urain

向学习算法提交实例的选项。

  • 一个接一个
  • 随机分组。
  • 在滑动组中。
  • 一下子就好了。

你是不是忘记了什么?


准备了项目的框架,几天的时间就把事情抖落出来,并把它拿出来讨论......

一次一个--我明白了。

而其余的选项--我不明白。我怎样才能一次提交所有的例子来研究?- 还是我是哑巴?