Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] O que faz essas funções do numpy junto com list compreension ?

import numpy as np

class Network(object):

    def __init__(self, sizes):
        """The list ``sizes`` contains the number of neurons in the
        respective layers of the network.  For example, if the list
        was [2, 3, 1] then it would be a three-layer network, with the
        first layer containing 2 neurons, the second layer 3 neurons,
        and the third layer 1 neuron.  The biases and weights for the
        network are initialized randomly, using a Gaussian
        distribution with mean 0, and variance 1.  Note that the first
        layer is assumed to be an input layer, and by convention we
        won't set any biases for those neurons, since biases are only
        ever used in computing the outputs from later layers."""
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
        self.weights = [np.random.randn(y, x)
                        for x, y in zip(sizes[:-1], sizes[1:])]
                        
minharede = Network([2, 3, 1]);

Esse é um código de uma rede neural MLP que extrai do site: http://neuralnetworksanddeeplearning.com/chap1.html, ai eu copiei pra cá e adicionei a chamada de "minharede = Network([2, 3, 1]);" pra perguntar sobre esse exemplo que não entendi.

Eu tenho tentado entender a logica por traz desse código, mais acho bem dificil. Tenho bastante dificuldade com list compreension e com funções matriciais do numpy. Por isso gostaria de perguntar especificamente o que esse código faz e também se possivel, queria descobrir como eu poderia obter o mesmo resultado porém sem utilizar numpy e sem usar list compreension.

Tenho umas duvidas:

1 - O que faz a linha "self.biases = [np.random.randn(y, 1) for y in sizes[1:]]" ?

2 - O que faz a outra linha "self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]" ?

3 - Qual deverá ser a estrutura resultante de cada uma dessas duas linhas ?

4 - Qual seria um código equivalente para obter exatamente o mesmo resultado dessas duas linhas, porém sem precisar usar list compreension e sem o numpy. Do zero em python, apenas utilizando os comandos nativos do propio python?

Isso me ajudaria a entender melhor o código e o que essas linhas de códigos realmente fazem.

2 respostas
solução!

Olá, William! Como vai?

Vou tentar esclarecer suas dúvidas sobre o código da rede neural MLP que você trouxe.

  1. O que faz a linha "self.biases = [np.random.randn(y, 1) for y in sizes[1:]]"? Essa linha está criando uma lista de matrizes de viés (biases) para cada camada da rede neural, exceto a camada de entrada. Cada matriz de viés é inicializada com valores aleatórios seguindo uma distribuição normal (gaussiana) com média 0 e variância 1. A função np.random.randn(y, 1) gera uma matriz y x 1 com esses valores aleatórios. O sizes[1:] significa que estamos pegando todas as camadas exceto a primeira (camada de entrada), que não possui viés.

  2. O que faz a linha "self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]"? Esta linha cria uma lista de matrizes de pesos (weights) para cada conexão entre as camadas da rede. A função np.random.randn(y, x) gera uma matriz com y linhas e x colunas, onde os valores também seguem uma distribuição normal com média 0 e variância 1. O uso de zip(sizes[:-1], sizes[1:]) serve para obter pares de tamanhos das camadas adjacentes, onde x é o número de neurônios na camada anterior e y é o número na camada seguinte.

  3. Qual deverá ser a estrutura resultante de cada uma dessas duas linhas?

    • self.biases: Será uma lista de matrizes, onde cada matriz tem dimensões correspondentes ao número de neurônios da camada (exceto a primeira) e 1 coluna.
    • self.weights: Será uma lista de matrizes, onde cada matriz tem dimensões que correspondem ao número de neurônios na camada anterior (linhas) e o número de neurônios na camada seguinte (colunas).
  4. Qual seria um código equivalente para obter exatamente o mesmo resultado dessas duas linhas, porém sem precisar usar list compreension e sem o numpy? Aqui está uma maneira de fazer isso usando apenas Python puro:

    import random
    
    class Network(object):
        def __init__(self, sizes):
            self.num_layers = len(sizes)
            self.sizes = sizes
            self.biases = []
            self.weights = []
            
            # Inicializando biases
            for y in sizes[1:]:
                bias_layer = []
                for i in range(y):
                    bias_layer.append([random.gauss(0, 1)])
                self.biases.append(bias_layer)
            
            # Inicializando weights
            for x, y in zip(sizes[:-1], sizes[1:]):
                weight_matrix = []
                for i in range(y):
                    weight_row = []
                    for j in range(x):
                        weight_row.append(random.gauss(0, 1))
                    weight_matrix.append(weight_row)
                self.weights.append(weight_matrix)
    
    minharede = Network([2, 3, 1])
    

    Neste código, substituímos np.random.randn por random.gauss(0, 1), que gera números aleatórios com média 0 e desvio padrão 1, similar à função do NumPy. As listas são preenchidas usando laços for tradicionais em vez de compreensões de lista.

Espero que essas explicações tenham ajudado a esclarecer suas dúvidas sobre o funcionamento desse código!

Grande abraço e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Obrigado Armando por responder.