1

일부 신경 네트워크 학습 속도를 높이기 위해 특정 레이어의 경우 각 뉴런에 대한 계산이 서로 독립적이기 때문에 몇 가지 멀티 스레딩을 시도했습니다.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 코어 수. 아이디어는 각각의 층을 대략 같은 수의 뉴런으로 분할하여 각 스레드가 개별적으로 처리하도록했습니다 (배수가 아닌 경우 모든 여분의 뉴런이있는 마지막 층).

새 기능은 어느 정도 작동하고 훨씬 빠르지 만 특정 임계 값이 더 이상 수렴하지 않으면 이전 기능이 수행 된 곳에서 작동하지 않으며 그 동작이 변경되는 이유를 찾을 수 없습니다. 어떤 뉴런이나 무게를 놓치고 있습니까?

+0

좋아, 난 내가 Windows에서 년 동안 만 최근 다시의 pthreads에 비둘기 인정하지만, 왜()'를 -ing 오히려 pthread_join을'보다 핸들을 스레드에 취소 요청을 보내는? – WhozCraig

+0

일단 완료되면 쓰레드를 어떻게 처리해야하는지 잘 모르겠습니다. 나는 그 부분을 없애려고했지만 실제로는 변화가 없었다. – Slereah

답변

0

얼마 전에 Encog에 대한 다중 스레드 백 프로 시저 알고리즘을 구현했습니다. Java로 작성했지만 C로 구현 한 경우 pthread보다는 OpenMP를 사용했습니다. 내 C 구현을 여기서 볼 수 있습니다.

https://github.com/encog/encog-c

는 또한 멀티 스레드에서 역 전파을 수행하기위한 나의 접근 방식에 대한 기사를 썼다. 내 기사를 볼 수 있습니다.

http://www.heatonresearch.com/encog/mprop/compare.html

뿐만 아니라, 스택 오버플로 이것에 대해 다른 몇 가지 질문이 있습니다. 대부분 내 알고리즘을 참조하는 것 같습니다.

Multithreaded backpropagation How can I apply multithreading to the backpropagation neural network training?