일부 신경 네트워크 학습 속도를 높이기 위해 특정 레이어의 경우 각 뉴런에 대한 계산이 서로 독립적이기 때문에 몇 가지 멀티 스레딩을 시도했습니다.backpropagation 알고리즘을위한 멀티 스레딩
I이 사용 된 본래의 기능은 기본적인 역 전파 알고리즘 그물 델타의 평가이다 :
δ = 유도체 * Σ (중량 * 이전 δ)
void backpropagation (Autoencoder* AE)
{
int i, j, k;
for(i = AE->numLayer-2; i >= 0; i--)
{
for(j = 0; j < AE->layer[i].size; j++)
{
register double sum = 0.0;
for(k = 0; k < AE->layer[i+1].size; k++)
{
sum += AE->layer[i+1].neuron[k].weight[j] * AE->layer[i+1].neuron[k].delta;
}
AE->layer[i].neuron[j].delta = AE->layer[i].neuron[j].derivative * sum;
}
}
}
Autoencoder 인 신경망을 포함하는 구조. 약간 느리면 충분히 잘 작동합니다. 먼저이 기능을 시도하는 것이 좋습니다.
수정 기능
은 다음과 같습니다 : 새로운 스레드void backpropagationmultithread (Autoencoder* AE, unsigned int ncore, pthread_t* pth)
{
int i, j;
unsigned int neuronpercore, extra;
sem_t semaphore;
argThread* args[ncore];
for(i = AE->numLayer-2; i >= 0; i--)
{
neuronpercore = AE->layer[i].size/ncore;
extra = neuronpercore + (AE->layer[i].size % ncore);
sem_init(&semaphore, 0, -ncore);
for(j = 0; j < ncore; j++)
{
args[j] = malloc(sizeof(argThread));
args[j]->layer = i;
args[j]->AE = AE;
args[j]->sem = &semaphore;
args[j]->startat = neuronpercore * j;
args[j]->nneurons = (j!=ncore-1)?neuronpercore:extra;
pthread_create(&pth[j], NULL, backpropagationthread, (void*)args[j]);
}
sem_wait(&semaphore);
for(j = 0; j < ncore; j++)
{
pthread_cancel(pth[j]);
}
}
}
그리고 기능을 :
void* backpropagationthread (void* arg)
{
argThread* args = (argThread*) arg;
unsigned int j,k,layer = args->layer, start = args->startat, end = args->startat + args->nneurons;
Autoencoder* AE = args->AE;
for(j = start; j < end; j++)
{
register double sum = 0.0;
for(k = 0; k < AE->layer[layer+1].size; k++)
{
sum += AE->layer[layer+1].neuron[k].weight[j] * AE->layer[layer+1].neuron[k].delta;
}
AE->layer[layer].neuron[j].delta = AE->layer[layer].neuron[j].derivative * sum;
}
sem_post(args->sem);
free(arg);
return NULL;
}
argThread 스레드에 전달되는 모든 인수를 포함 조금 구조 , ncore CPU 코어 수. 아이디어는 각각의 층을 대략 같은 수의 뉴런으로 분할하여 각 스레드가 개별적으로 처리하도록했습니다 (배수가 아닌 경우 모든 여분의 뉴런이있는 마지막 층).
새 기능은 어느 정도 작동하고 훨씬 빠르지 만 특정 임계 값이 더 이상 수렴하지 않으면 이전 기능이 수행 된 곳에서 작동하지 않으며 그 동작이 변경되는 이유를 찾을 수 없습니다. 어떤 뉴런이나 무게를 놓치고 있습니까?
좋아, 난 내가 Windows에서 년 동안 만 최근 다시의 pthreads에 비둘기 인정하지만, 왜()'를 -ing 오히려 pthread_join을'보다 핸들을 스레드에 취소 요청을 보내는? – WhozCraig
일단 완료되면 쓰레드를 어떻게 처리해야하는지 잘 모르겠습니다. 나는 그 부분을 없애려고했지만 실제로는 변화가 없었다. – Slereah