Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Camadas de Perceptron | Rede Neural do Zero
Introdução às Redes Neurais

bookCamadas de Perceptron

Perceptron é o nome da rede neural mais simples, composta por apenas um neurônio. No entanto, para resolver problemas mais complexos, será criado um modelo chamado perceptron multicamadas (MLP). Um perceptron multicamadas consiste em uma ou mais camadas ocultas. A estrutura de um perceptron multicamadas é a seguinte:

  1. Uma camada de entrada: recebe os dados de entrada;
  2. Camadas ocultas: processam os dados e extraem padrões.
  3. Camada de saída: produz a previsão ou classificação final.

Em geral, cada camada é composta por vários neurônios, e a saída de uma camada torna-se a entrada para a próxima camada.

Pesos e Bias das Camadas

Antes de implementar uma camada, é importante compreender como armazenar os pesos e bias de cada neurônio nela. No capítulo anterior, foi apresentado como armazenar os pesos de um único neurônio como um vetor e seu bias como um escalar (número único).

Como uma camada é composta por vários neurônios, é natural representar os pesos como uma matriz, onde cada linha corresponde aos pesos de um neurônio específico. Consequentemente, os bias podem ser representados como um vetor, cujo comprimento é igual ao número de neurônios.

Dada uma camada com 33 entradas e 22 neurônios, seus pesos serão armazenados em uma matriz 2×32 \times 3 WW e seus bias serão armazenados em um vetor 2×12 \times 1 bb, conforme mostrado a seguir:

W=[W11W12W13W21W22W23]b=[b1b2]W = \begin{bmatrix} W_{11} & W_{12} & W_{13}\\ W_{21} & W_{22} & W_{23} \end{bmatrix} \qquad b = \begin{bmatrix} b_1\\ b_2 \end{bmatrix}

Aqui, o elemento WijW_{ij} representa o peso da jj-ésima entrada para o ii-ésimo neurônio, portanto, a primeira linha contém os pesos do primeiro neurônio e a segunda linha contém os pesos do segundo neurônio. O elemento bib_i representa o bias do ii-ésimo neurônio (dois neurônios – dois bias).

Propagação Direta

Realizar a propagação direta para cada camada significa ativar cada um de seus neurônios ao calcular a soma ponderada das entradas, adicionar o viés e aplicar a função de ativação.

Anteriormente, para um único neurônio, a soma ponderada das entradas foi implementada por meio do produto escalar entre o vetor de entrada e o vetor de pesos, somando o viés.

Como cada linha da matriz de pesos contém o vetor de pesos de um neurônio específico, tudo o que precisa ser feito agora é simplesmente realizar um produto escalar entre cada linha da matriz e o vetor de entrada. Felizmente, isso é exatamente o que a multiplicação de matrizes faz:

Para adicionar os vieses às saídas dos respectivos neurônios, um vetor de vieses também deve ser somado:

Por fim, a função de ativação é aplicada ao resultado — sigmoid ou ReLU, neste caso. A fórmula resultante para a propagação direta na camada é a seguinte:

a=activation(Wx+b)a = activation(Wx + b)

onde aa é o vetor de ativações (saídas) dos neurônios.

Classe Layer

Os blocos fundamentais do perceptron são suas camadas, portanto, faz sentido criar uma classe Layer separada. Seus atributos incluem:

  • inputs: um vetor de entradas (n_inputs é o número de entradas);
  • outputs: um vetor de valores de saída brutos (antes de aplicar a função de ativação) dos neurônios (n_neurons é o número de neurônios);
  • weights: uma matriz de pesos;
  • biases: um vetor de bias;
  • activation_function: a função de ativação utilizada na camada.

Assim como na implementação de um único neurônio, weights e biases serão inicializados com valores aleatórios entre -1 e 1 extraídos de uma distribuição uniforme.

class Layer:
    def __init__(self, n_inputs, n_neurons, activation_function):
        self.inputs = np.zeros((n_inputs, 1))
        self.outputs = np.zeros((n_neurons, 1))
        self.weights = ...
        self.biases = ...
        self.activation = activation_function

Os atributos inputs e outputs serão utilizados posteriormente na retropropagação, portanto faz sentido inicializá-los como arrays de zeros do NumPy.

Note
Nota

Inicializar inputs e outputs como arrays do NumPy preenchidos com zeros previne erros ao realizar cálculos na propagação direta e reversa. Isso também garante consistência entre as camadas, permitindo operações matriciais sem a necessidade de verificações adicionais.

Propagação direta pode ser implementada no método forward(), onde os outputs são calculados com base no vetor inputs utilizando NumPy, seguindo a fórmula acima:

def forward(self, inputs):
    self.inputs = np.array(inputs).reshape(-1, 1)
    # Raw outputs
    self.outputs = ...
    # Applying the activation function
    return ...
Note
Nota

Redimensionar inputs para um vetor coluna garante a multiplicação de matrizes correta com a matriz de pesos durante a propagação direta. Isso evita incompatibilidades de formato e permite cálculos contínuos em todas as camadas.

1. O que torna um perceptron multicamadas (MLP) mais poderoso do que um perceptron simples?

2. Por que aplicamos este código antes de multiplicar inputs pela matriz de pesos?

question mark

O que torna um perceptron multicamadas (MLP) mais poderoso do que um perceptron simples?

Select the correct answer

question mark

Por que aplicamos este código antes de multiplicar inputs pela matriz de pesos?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 3

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Awesome!

Completion rate improved to 4

bookCamadas de Perceptron

Deslize para mostrar o menu

Perceptron é o nome da rede neural mais simples, composta por apenas um neurônio. No entanto, para resolver problemas mais complexos, será criado um modelo chamado perceptron multicamadas (MLP). Um perceptron multicamadas consiste em uma ou mais camadas ocultas. A estrutura de um perceptron multicamadas é a seguinte:

  1. Uma camada de entrada: recebe os dados de entrada;
  2. Camadas ocultas: processam os dados e extraem padrões.
  3. Camada de saída: produz a previsão ou classificação final.

Em geral, cada camada é composta por vários neurônios, e a saída de uma camada torna-se a entrada para a próxima camada.

Pesos e Bias das Camadas

Antes de implementar uma camada, é importante compreender como armazenar os pesos e bias de cada neurônio nela. No capítulo anterior, foi apresentado como armazenar os pesos de um único neurônio como um vetor e seu bias como um escalar (número único).

Como uma camada é composta por vários neurônios, é natural representar os pesos como uma matriz, onde cada linha corresponde aos pesos de um neurônio específico. Consequentemente, os bias podem ser representados como um vetor, cujo comprimento é igual ao número de neurônios.

Dada uma camada com 33 entradas e 22 neurônios, seus pesos serão armazenados em uma matriz 2×32 \times 3 WW e seus bias serão armazenados em um vetor 2×12 \times 1 bb, conforme mostrado a seguir:

W=[W11W12W13W21W22W23]b=[b1b2]W = \begin{bmatrix} W_{11} & W_{12} & W_{13}\\ W_{21} & W_{22} & W_{23} \end{bmatrix} \qquad b = \begin{bmatrix} b_1\\ b_2 \end{bmatrix}

Aqui, o elemento WijW_{ij} representa o peso da jj-ésima entrada para o ii-ésimo neurônio, portanto, a primeira linha contém os pesos do primeiro neurônio e a segunda linha contém os pesos do segundo neurônio. O elemento bib_i representa o bias do ii-ésimo neurônio (dois neurônios – dois bias).

Propagação Direta

Realizar a propagação direta para cada camada significa ativar cada um de seus neurônios ao calcular a soma ponderada das entradas, adicionar o viés e aplicar a função de ativação.

Anteriormente, para um único neurônio, a soma ponderada das entradas foi implementada por meio do produto escalar entre o vetor de entrada e o vetor de pesos, somando o viés.

Como cada linha da matriz de pesos contém o vetor de pesos de um neurônio específico, tudo o que precisa ser feito agora é simplesmente realizar um produto escalar entre cada linha da matriz e o vetor de entrada. Felizmente, isso é exatamente o que a multiplicação de matrizes faz:

Para adicionar os vieses às saídas dos respectivos neurônios, um vetor de vieses também deve ser somado:

Por fim, a função de ativação é aplicada ao resultado — sigmoid ou ReLU, neste caso. A fórmula resultante para a propagação direta na camada é a seguinte:

a=activation(Wx+b)a = activation(Wx + b)

onde aa é o vetor de ativações (saídas) dos neurônios.

Classe Layer

Os blocos fundamentais do perceptron são suas camadas, portanto, faz sentido criar uma classe Layer separada. Seus atributos incluem:

  • inputs: um vetor de entradas (n_inputs é o número de entradas);
  • outputs: um vetor de valores de saída brutos (antes de aplicar a função de ativação) dos neurônios (n_neurons é o número de neurônios);
  • weights: uma matriz de pesos;
  • biases: um vetor de bias;
  • activation_function: a função de ativação utilizada na camada.

Assim como na implementação de um único neurônio, weights e biases serão inicializados com valores aleatórios entre -1 e 1 extraídos de uma distribuição uniforme.

class Layer:
    def __init__(self, n_inputs, n_neurons, activation_function):
        self.inputs = np.zeros((n_inputs, 1))
        self.outputs = np.zeros((n_neurons, 1))
        self.weights = ...
        self.biases = ...
        self.activation = activation_function

Os atributos inputs e outputs serão utilizados posteriormente na retropropagação, portanto faz sentido inicializá-los como arrays de zeros do NumPy.

Note
Nota

Inicializar inputs e outputs como arrays do NumPy preenchidos com zeros previne erros ao realizar cálculos na propagação direta e reversa. Isso também garante consistência entre as camadas, permitindo operações matriciais sem a necessidade de verificações adicionais.

Propagação direta pode ser implementada no método forward(), onde os outputs são calculados com base no vetor inputs utilizando NumPy, seguindo a fórmula acima:

def forward(self, inputs):
    self.inputs = np.array(inputs).reshape(-1, 1)
    # Raw outputs
    self.outputs = ...
    # Applying the activation function
    return ...
Note
Nota

Redimensionar inputs para um vetor coluna garante a multiplicação de matrizes correta com a matriz de pesos durante a propagação direta. Isso evita incompatibilidades de formato e permite cálculos contínuos em todas as camadas.

1. O que torna um perceptron multicamadas (MLP) mais poderoso do que um perceptron simples?

2. Por que aplicamos este código antes de multiplicar inputs pela matriz de pesos?

question mark

O que torna um perceptron multicamadas (MLP) mais poderoso do que um perceptron simples?

Select the correct answer

question mark

Por que aplicamos este código antes de multiplicar inputs pela matriz de pesos?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 3
some-alt