Discussão do artigo "Redes Neurais de Maneira Fácil (Parte 5): Cálculos em Paralelo com o OpenCL"
O artigo é extremamente complicado para alguém que não se dedica ao OpenCL. Tentei entender a essência, li os artigos que você indicou em seu lugar e ..... Não entendi nada, ou melhor, entendi muito parcialmente.
Seu artigo provavelmente é super, mas muito complicado, acho que você precisa considerar os fundamentos do OpenCL e talvez trabalhar com bibliotecas integradas como OpenCL.mqh, porque sem elas não haverá compreensão, como evidenciado pela falta de discussão do artigo. Não entendo seu código porque ele contém referências a muitas bibliotecas das quais não tenho a menor ideia.
A segunda pergunta que não entendo é como usar o OpenCL no modo de otimização. O que acontecerá se várias instâncias do OpenCL estiverem acessando simultaneamente a placa de vídeo ????. Existem vários métodos para acelerar os cálculos de uma mesma coisa no OpenCL. Por exemplo, livrar-se do double em favor do int. etc. .... Há muitas perguntas.
Proponho começar com um exemplo muito simples em um código de programação multithread. Suponhamos que haja UM perceptron com n entradas, respectivamente, precisamos escrever um código simples para calcular as funções de normalização no intervalo [-1,1] e calcular o valor do neurônio por tanh usando OpenCL. E o próprio código em OpenCL deve ser comentado. E considere um Expert Advisor de negociação muito simples com otimização no testador no histórico usando UM indicador, e também um indicador simples, ou seja, fornecendo apenas um valor, como RSI ou CCI. Ou seja, tudo é o mais simplificado possível, sem artifícios, apenas o mais simples possível. No futuro, acho que não será um problema estender isso a muitos perceptrons e escrever seu próprio Expert Advisor.
Obrigado pelo artigo.
O artigo é exatamente o que você precisa. Obrigado ao autor. Entendi os cálculos paralelos em neurônios desde a primeira vez. Só preciso "amadurecer")).
Bem, um não amadureceu, o outro ..... Mas acho que todo mundo quer.
Concordo que o artigo é necessário
Estou me esforçando para entendê-lo.
Talvez você possa escrever o que eu lhe pedi, se for tão fácil para você.Bem, uma não está madura, a outra é ..... e acho que todo mundo quer uma.
Concordo que este é um artigo útil.
Estou me esforçando para entendê-lo.
Talvez você possa escrever o que eu lhe pedi, se for tão fácil para você.Tudo isso é interessante, embora seja improvável que eu o repita, mas fiquei intrigado com a pergunta: por que o aumento de 10 vezes se apenas mais um núcleo estava envolvido no treinamento?
Pelo que entendi, ao treinar no OpenCL, ele faz o cálculo paralelo de vários indicadores ao mesmo tempo.
Tudo isso é interessante, embora seja improvável que possa ser repetido por mim, mas fiquei intrigado com a pergunta - por que um aumento de 10 vezes se apenas mais um núcleo foi usado no treinamento?
O kernel não é um núcleo físico ou lógico, mas um firmware que é executado em todos osnúcleos lógicos de um processador ou placa de vídeo em paralelo.
Aqui estão alguns pontos que não entendo
__kernel void FeedForward(__global double *matrix_w, __global double *matrix_i, __global double *matrix_o, int inputs, int activation) { int i=get_global_id(0); //O que essa linha faz? double sum=0.0; double4 inp, weight; int shift=(inputs+1)*i; //O que essa linha faz? for(int k=0; k<=inputs; k=k+4) { switch(inputs-k) { case 0: inp=(double4)(1,0,0,0); //O que essa linha faz? weight=(double4)(matrix_w[shift+k],0,0,0); break; case 1: inp=(double4)(matrix_i[k],1,0,0); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],0,0); break; case 2: inp=(double4)(matrix_i[k],matrix_i[k+1],1,0); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],0); break; case 3: inp=(double4)(matrix_i[k],matrix_i[k+1],matrix_i[k+2],1); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); break; default: inp=(double4)(matrix_i[k],matrix_i[k+1],matrix_i[k+2],matrix_i[k+3]); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); break; } sum+=dot(inp,weight); //O que essa linha faz? } switch(activation) { case 0: sum=tanh(sum); break; case 1: sum=pow((1+exp(-sum)),-1); break; } matrix_o[i]=sum; }
Acho que é necessário explicá-los para pessoas "distantes", e o principal é que não está claro para mim, no código, onde tudo é inicializado e onde tudo é chamado.
Aqui estão algumas coisas que não entendo
Acho que é necessário explicá-las para pessoas "distantes", e o principal é que eu não entendo no código onde tudo é inicializado e onde tudo é chamado.
Bom dia, Boris.
Você anexou o código do kernel. Como Maxim escreveu acima, ele é um microprograma executado em núcleos de microprocessadores ou placas de vídeo (depende do contexto de inicialização). A questão principal é que vários desses programas são chamados de uma só vez e são executados em paralelo em todos os núcleos. Cada programa trabalha com seus próprios dados.
int i=get_global_id(0); //O que essa linha faz?
Essa linha apenas obtém o número de série do microprograma do pool de cópias em execução paralela. No código, esse número é usado para determinar qual parte dos dados deve ser fornecida para processamento. Nesse caso, ele corresponderá ao número de neurônios na camada.
Além disso, para uma paralelização ainda maior das ações dentro do microprograma, são usadas variáveis vetoriais, que são pequenas matrizes de tamanho fixo. Nesse caso, a dimensão dos vetores é 4, ou seja, matrizes de 4 elementos.
double4 inp, weight;
Mas o tamanho da matriz de entrada nem sempre será um múltiplo de 4. Portanto, para evitar referência incorreta à matriz, usa-se swith e os valores ausentes são preenchidos com "0". Nesse caso, para cada neurônio, a dimensionalidade da matriz de peso é 1 elemento maior do que a dimensionalidade dos elementos de entrada, e esse elemento é usado como um viés bayesiano. Anteriormente, usamos um neurônio adicional para essa finalidade, no qual corrigimos apenas os pesos e não recalculamos o valor de saída, que sempre permaneceu igual a "1". Aqui, eu não adicionei constantemente "1" à matriz de entrada, mas o escrevi diretamente no código, e o tamanho da matriz de entrada não mudou.
inp=(double4)(1,0,0,0); //O que essa linha faz? weight=(double4)(matrix_w[shift+k],0,0,0);
A função ponto retorna o produto escalar de dois vetores, ou seja, no nosso caso, contamos a soma de 4 produtos de valores de entrada por pesos em uma linha.
sum+=dot(inp,weight); //O que essa linha faz?
Umkernel não é um núcleo físico ou lógico, mas um firmware que é executado em todos osnúcleos lógicos de um processador ou placa de vídeo em paralelo
Portanto, não é novidade - havia um núcleo e a carga estava nele, e agora há dois núcleos, a carga é reduzida pela metade.... Provavelmente, as alterações são mais significativas e a comparação não está correta.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Novo artigo Redes Neurais de Maneira Fácil (Parte 5): Cálculos em Paralelo com o OpenCL foi publicado:
Discutimos anteriormente alguns tipos de implementações da rede neural. Nas redes consideradas, as mesmas operações são repetidas para cada neurônio. Uma etapa lógica adicional é utilizar os recursos da computação multithread (paralelismo em nível de threads) fornecidos pela tecnologia moderna em um esforço para acelerar o processo de aprendizagem da rede neural. Uma das possíveis implementações é descrita neste artigo.
Nós selecionamos a tecnologia. Agora, nós precisamos decidir sobre o processo de divisão dos cálculos nas threads. Você se lembra do algoritmo perceptron totalmente conectado durante uma passagem da propagação direta (feed-forward)? O sinal se move sequencialmente da camada de entrada para as camadas ocultas e, em seguida, para a camada de saída. Não adianta alocar uma thread para cada camada, pois os cálculos devem ser executados sequencialmente. O cálculo da camada não pode começar até que seja obtido o resultado da camada anterior. O cálculo de um neurônio individual em uma camada não depende dos resultados do cálculo de outros neurônios nessa camada. Isso significa que nós podemos alocar as threads separadas para cada neurônio e enviar todos os neurônios de uma camada para computar de forma paralela.
Descendo ao nível de operações de um neurônio, nós poderíamos considerar a possibilidade de paralelizar o cálculo do produto dos valores de entrada pelos seus coeficientes de peso. No entanto, a soma adicional dos valores resultantes e o cálculo do valor da função de ativação são combinados em uma única thread. Eu decidi implementar essas operações em um único kernel OpenCL usando as funções vetoriais.
Autor: Dmitriy Gizlyk