Implementação da famosa rede neural MLP
Quando estudamos redes neurais, um termo bastante difundido é o MLP. Ele significa o acrônimo para Multi-Layer Perceptron. Seria um Perceptron de Múltiplas Camadas.
Seguindo com o nosso estudo seria a junção de muitas camadas, que, assim, formam uma rede neural.
Implementemos de novo o neurônio.
class Neuron:
def __init__(self, n_in):
self.w = [random.uniform(-1, 1) for _ in range(n_in)]
self.b = random.uniform(-1, 1)
def __call__(self, x):
return sum(wi * xi for wi, xi in zip(self.w, x), self.b)
Simples.
Os neurônios juntos formam uma camada, a próxima abstração. Implementemos.
class Layer:
def __init__(self, n_in, n_res):
self.neurons = [Neuron(n_in) for _ in range(n_res)]
def __call__(self, x):
results = [n(x) for n in self.neurons]
return results
Muito simples. Depois podemos discutir alguns detalhes, mas o conceito seria esse.
O neurônio com os parâmetros que realizam a soma ponderada e a camada apenas como uma lista de neurônios e assim, somas ponderadas se realizam nela.
Bom, com esses dois conceitos, conseguimos agora implementar a rede neural MLP.
Seguindo a mesma lógica e pela estrutura de uma rede neural, ela vai então agora usar o conceito de camada. Vejamos o código, depois discutimos.
class MLP:
def __init__(self, n_in, n_res):
sz = [n_in] + n_res
self.layers = [Layer(sz[i], sz[i+1]) for i in range(n_res)]
def __call__(self, x):
for layer in self.layers:
x = layer(x)
return x
Bom, alguns detalhes específicos da MLP.
Observem que a MLP seria formada por camadas, então a entrada continua a mesma, para o nosso exemplo x como [2.0, 4.0], então o n_in seria ainda o 2. Mas, agora, distinto da camada, que recebia apenas um número, que significava número de neurônios, agora temos dentro da MLP as camadas. Como a rede possui uma estrutura sequencial, a composição de camadas se dá com o resultado como entrada para outra, excepto para a primeira camada, que possui como entrada o dado de entrada em si.
Então, desse jeito, a MLP recebe uma lista de números, que indicam quantos neurônios tem em cada camada.
Vejamos o exemplo.
x = [2.0, 3.0]
n = MLP(2, [2, 4, 1])
n(x)
No exemplo, temos o x com tamanho 2, então, o primeiro parâmetro instanciando a MLP seria 2. O segundo parâmetro, como observamos, seria uma lista.
A lista [2, 4, 1] indica que a rede neural possui 3 camadas. A primeira com 2 neurônios, a segunda com 4 neurônios e a última camada com 1 neurônio. O resultado final então seria apenas um número.
Na implementação, cada camada se cria considerando o par. Olhem que criamos uma lista sz e iteramos por ela na criação de cada Layer para a obtenção de self.layers. Itera-se com os pares na ordem. Então a primeira camada possui entrada 2, tamanho da entrada de dados e resposta 2 com os 2 neurônios. A segunda camada recebe então o resultado 2 e responde com 4 neurônios. A terceira camada, por fim, recebe 4 números, cada um dos 4 neurônios, e responde com um número, do seu único neurônio.
E assim tem-se a rede neural de modo simples.