Modelos de neurônios
Assim que se começa o estudo do micrograd, o Karpathy primeiro fala sobre diferenciação. Ele explica como as redes neurais aprendem utilizando derivadas. Assim, ele começa a construção do núcleo do micrograd, que seria basicamente a classe Value, que encapsula um valor e define funções para as operações e como seria a derivada considerando o aprendizado.
Depois disso, ele começa a construir uma rede neural. Cria-se a classe de cada conceito: neurônio, camada e rede neural. Os pesos são criados com cada número definido com a instanciação de um objeto Value, que implementa a diferenciação automática, para poder então se progagar os valores e se aprender por diferenciação a partir da função de perda.
Bom, um aspecto importante seria compreender o impacto dos distintos modelos de neurônios. Geoff Hinton fala que são modelos idealizados, que simplificam muitos aspectos para poder matematicamente serem concebidos.
O neurônio que discutimos no post O Neurônio como Fundamentação no Aprendizado de Inteligência Artificial seria o neurônio linear. Relembremos.
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)
No micrograd original, temos o hyperbolic tangent neuron, já com o uso da classe Value para autodiferenciação. Segue o neurônio.
class Neuron:
def __init__(self, n_in):
self.w = [Value(random.uniform(-1, 1)) for i in range(n_in)]
self.b = Value(random.uniform(-1, 1))
def __call__(self, x):
z = sum((wi * xi for wi, xi in zip(self.w, x)), self.b)
result = z.tanh()
return result
A distinção para o neurônio linear seria apenas o uso da função tanh para delimitação de valores do resultado para o neurônio.
Estudemos então outros modelos da aula do Geoff Hinton e busquemos pesquisar, discutir e implementar outros modelos de neurônios.
Podemos então testar, no escopo do micrograd, o impacto da escolha do modelo de neurônio.
Desse modo estamos implementando o micrograd 2.0.
Bom, comecemos com o primeiro modelo de neurônio que o Geoff Hinton discute. Seria o binary threshold neuron.
A implementação seria a seguinte.
class BinaryThresholdNeuron:
def __init__(self, n_in):
self.w = [Value(random.uniform(-1, 1)) for i in range(n_in)]
self.b = Value(random.uniform(-1, 1))
def __call__(self, x):
z = sum((wi * xi for wi, xi in zip(self.w, x)), self.b)
result = 1 if z.data >= 0 else 0
return Value(result)
Esse neurônio considera a mesma estrutura com os pesos W e b, mas, ao chegar no resultado z, checa-se se ele seria maior ou igual a zero. Se sim, retorna 1. Caso contrário, retorna 0.
Precisa-se considerar a discussão sobre a autodiferenciação nesse caso.