Discussão do artigo "Redes Neurais de Maneira Fácil" - página 3

 
Maxim Dmitrievsky:


o que são os "5 porquês" e o que as 4 camadas têm a ver com isso? Pesquisei, uma árvore de decisão simples responderá a essa pergunta. O aproximador universal é o NS de 2 camadas, que responderá a qualquer número de "porquês" :) As outras camadas são usadas principalmente para o pré-processamento de dados em projetos complexos. Por exemplo, para compactar uma imagem a partir de um grande número de pixels e depois reconhecê-la.


"Os 5 porquês" é uma técnica para determinar a causalidade na Wikipédia. O artigo mostra, por exemplo, como essencialmente uma rede neural é projetada para encontrar uma relação causal entre movimentos de preços passados e a direção futura do movimento de preços.

 
Andrey Azatskiy:
somente o sinal de entrada também deve estar nesse intervalo. Por sinal de entrada, quero dizer exatamente o sinal de entrada para o neurônio, não para a função em discussão.

Teoricamente, o sinal de entrada para o neurônio pode ser qualquer um. Sua influência é corrigida por um coeficiente de ponderação. Se o sinal de entrada for muito pequeno, mas tiver um impacto significativo na solução geral, seu coeficiente de peso será aumentado no processo de aprendizado. Se o sinal for de grande importância, mas sua influência no resultado for insignificante, seu coeficiente de peso será reduzido a "0" (falha na comunicação entre os neurônios).

[Excluído]  
Dmitriy Gizlyk:

"Os 5 porquês" é uma técnica para determinar a causalidade na Wikipédia. O artigo é dado como exemplo como essencialmente uma rede neural projetada para encontrar uma relação causal entre movimentos de preços passados e a direção futura do movimento de preços.

Eu simplesmente não entendi a correlação entre o número de perguntas e as camadas. A entrada é um número de atributos, cada um dos quais deve ser respondido (grosso modo). A saída é um resultado resumido. Uma camada oculta pode ser suficiente, não necessariamente 4. Acredita-se que um NS com 2 camadas ocultas possa se aproximar de qualquer função. Isso é apenas para referência.

 

E para desenvolver o tópico, uma pergunta sobre a arquitetura do NS. Do que ele depende?

 
Maxim Dmitrievsky:

Eu simplesmente não entendi a correlação entre o número de perguntas e as camadas. A entrada é um número de atributos, cada um dos quais deve ser respondido (grosso modo). A saída é um resultado resumido. Uma camada oculta pode ser suficiente, não necessariamente 4. Acredita-se que um NS com 2 camadas ocultas possa se aproximar de qualquer função. Isso é apenas para referência.

A técnica dos 5 Porquês é baseada em perguntas sequenciais, em que cada pergunta responde ao motivo da pergunta anterior. Por exemplo, observamos um gráfico e um gráfico de preço crescente e construímos perguntas (as perguntas são respondidas de forma abstrata para explicar a técnica):
1. Onde negociar - Comprar
2. Por que comprar? - Porque é uma tendência de alta
3. Por que uma tendência de alta? - A MA50 está subindo
4. Por que a MA50 está subindo? - O preço médio de fechamento de 50 candles com um deslocamento de 1 é menor do que o preço médio de fechamento dos últimos 50 candles.

etc.
Como as perguntas são sequenciais e têm uma relação de causa e efeito, criamos camadas para observar essa relação. Se usarmos apenas duas camadas, a relação de causa e efeito será perdida, a rede neural analisará várias opções independentes e escolherá a melhor.

 
Denis Kirichenko:

E para desenvolver o tópico, uma pergunta sobre a arquitetura do NS. Do que ele depende?

Da compreensão que o arquiteto tem do processo. O artigo apresenta a versão mais simples de uma rede neural e não considera arquiteturas convolucionais e outras.

[Excluído]  
Dmitriy Gizlyk:

A técnica dos 5 Porquês baseia-se em perguntas sequenciais em que cada pergunta responde ao motivo da pergunta anterior. Por exemplo, analisamos um gráfico e um gráfico de preço crescente e construímos perguntas (as perguntas são respondidas de forma abstrata para explicar a técnica):
1. Onde negociar - Comprar
2. Por que comprar? - Porque é uma tendência de alta
3. Por que uma tendência de alta? - A MA50 está subindo
4. Por que a MA50 está subindo? - O preço médio de fechamento de 50 candles com um deslocamento de 1 é menor do que o preço médio de fechamento dos últimos 50 candles.

etc.
Como as perguntas são sequenciais e têm uma relação de causa e efeito, criamos camadas para observar essa relação. Se usarmos apenas duas camadas, a relação de causa e efeito será perdida, a rede neural analisará várias opções independentes e escolherá a melhor.

Não faz diferença a ordem em que fazemos essas perguntas, o resultado será o mesmo. Não há necessidade de separar por camadas.

 
Dmitriy Gizlyk:

Boa noite, Peter.
O neurônio interno consiste em duas funções:
1. Primeiro, calculamos a soma de todos os sinais de entrada levando em conta seus coeficientes de ponderação. Ou seja, pegamos o valor em cada entrada do neurônio e o multiplicamos pelo fator de ponderação correspondente. E somamos os valores dos produtos obtidos.


Assim, obtemos um determinado valor que é alimentado na entrada da função de ativação.

2. A função de ativação converte a soma recebida em um sinal de saída normalizado. Ela pode ser uma função lógica simples ou várias funções sigmoides. As últimas são mais comuns, pois têm uma transição de mudança de estado mais suave.

A comunicação entre os neurônios é organizada como uma transferência direta do valor de saída de um neurônio para a entrada de um neurônio subsequente. Nesse caso, referindo-se ao ponto 1, o valor que chega à entrada de um neurônio é levado em consideração de acordo com seu coeficiente de peso.

Obrigado. O artigo e as referências me ajudaram a entender a essência do propósito das redes neurais - encontrar e processar um invariante dentro do espaço de variação de um conjunto de dados - e o método mais simples de implementação técnica, que ainda não compreendi definitivamente. Mas as explicações são muito lúcidas.
 
Maxim Dmitrievsky:

Não há diferença na ordem em que essas perguntas são feitas, o resultado será o mesmo. Não há necessidade de camadas aqui.

As perguntas são feitas condicionalmente. A técnica é usada para encontrar as causas básicas de um evento. A conexão entre a primeira e a última pergunta nem sempre é imediatamente óbvia.
Entretanto, esse exemplo do artigo é dado para demonstrar a conexão entre a abordagem de análise de causa raiz e a arquitetura de rede.
 
Реter Konow:
Muito obrigado. O artigo e as referências me ajudaram a entender a essência do propósito das redes neurais - a definição e o processamento do invariante incorporado no conjunto de dados e o método mais simples de implementação técnica, que ainda não entendi definitivamente. Mas as explicações são muito claras.

Se quiser entender a estrutura do MLP, na minha opinião, é melhor dar uma olhada neste código:

#danila_zaytcev mlp 2018


import random

import math



class mlp:


    class activefunc:

        def __init__(self, func, derive):

            self.func = func

            self.derive = derive


    def __init__(self, structure,  af,  learnRate,  moment,  epohs):

        self.leanRate = learnRate

        self.af = af

        self.moment = moment

        self.epohs = epohs


        self.layerCount = len(structure) - 1

        self.weightCount = [None] * self.layerCount

        self.neuronsCount = [None] * self.layerCount

        self.Out = [None] * self.layerCount

        self.Err = [None] * self.layerCount

        self.Drv = [None] * self.layerCount

        self.Inputs = [None] * self.layerCount

        self.Weigthts = [None] * self.layerCount


        for l in range(self.layerCount):

            nLen = structure[l + 1]

            wLen = structure[l] + 1

            self.weightCount[l] = wLen

            self.neuronsCount[l] = nLen


            self.Out[l] = [0.0] * nLen

            self.Err[l] = [0.0] * nLen

            self.Drv[l] = [0.0] * nLen

            self.Weigthts[l] = [None] * nLen


            for n in range(nLen):

                self.Weigthts[l][n] = [None] * wLen

                for w in range(wLen):

                    self.Weigthts[l][n][w] = (random.random() * 2 - 1) / wLen



    def forward(self,  input):

        for l in range(self.layerCount):

            self.Inputs[l] = input

            for n in range(self.neuronsCount[l]):

                wcount = self.weightCount[l] - 1

                out = 0.0

                for w in range(wcount):

                    out += self.Weigthts[l][n][w] * input[w]


                out += self.Weigthts[l][n][wcount]

                out = self.af.func(out)

                self.Out[l][n] = out

                self.Drv[l][n] = self.af.derive(out)


            input = self.Out[l];



    def backward(self, output):

        last = self.layerCount - 1

        for n in range( self.neuronsCount[last]):

            self.Err[last][n] *= self.moment

            self.Err[last][n] += (output[n] - self.Out[last][n])*self.Drv[last][n] * (1.0 - self.moment)


        for l in range(last - 1, -1,-1):

            for n in range( self.neuronsCount[l]):

                backProp = 0

                for w in range(self.neuronsCount[l + 1]):

                    backProp += self.Weigthts[l + 1][w][n] * self.Err[l + 1][w]


                self.Err[l][n] = backProp * self.Drv[l][n]



    def update(self):

        for l in range(self.layerCount):

            for n in  range(self.neuronsCount[l]):

                G = self.Err[l][n] * self.leanRate

                for w in  range(self.weightCount[l] - 1):

                    self.Weigthts[l][n][w] += self.Inputs[l][w] * G

                self.Weigthts[l][n][self.weightCount[l] - 1] += G



    def learn(self, inputs, outputs):

        for e in  range(self.epohs):

            for i in range(len(inputs)):

                index = random.randint(0, len(inputs) - 1)

                self.forward(inputs[index])

                self.backward(outputs[index])

                self.update()



    def compute(self, vector):

        self.forward(vector)

        return self.Out[self.layerCount - 1]



def test_mlp():


    inputs = [[1.0,1.0],[-1.0,-1.0],[1.0,-1.0],[-1.0,1.0]]

    outputs = [[1.0],[1.0],[-1.0],[-1.0]]


    af = mlp.activefunc(math.tanh, lambda y: 1.0 - y ** 2)

    ml = mlp([2,2,1],af,0.01,0.1,10000)

    ml.learn(inputs,outputs)


    for i in inputs:

        print(str(i) + " = " + str(ml.compute(i)))

Ele é cinco vezes menor, garante o que você precisa e está em Python, que é muito mais fácil de entender.

Mas o autor do artigo é bom, é claro, é legal escrever MLP você mesmo :)