try to find the mistake here, I'm stuck

import numpy as np
import random

class Valeur:
  def __init__(self,nombre,parent=[],opération='',label=''):
    self.nombre=nombre
    self.gradient=0.0
    self.parent=parent
    self.opération=opération
    self.label=label
  def __add__(self,autre):
    return Valeur(self.nombre+autre.nombre,[self,autre],'+')
  def __sub__(self,autre):
    return Valeur(self.nombre-autre.nombre,[self,autre],'-')

  def sigmoid(self):
    return Valeur(1/(1+np.exp(-self.nombre)),[self],'Sigmoid')


  def relu(self):
    if(self.nombre>0):
      return self
    else:
      return Valeur(0,[self],'ReLU')

  def __mul__(self,autre):
    return Valeur(self.nombre*autre.nombre,[self,autre],'*')

  def __repr__(self) -> str:
    return str(self.nombre)


  def backward(self,val=1):
    if(val==1):#c'est le résultat final
      self.gradient=1
    if(self.opération=='+'):
      self.parent[0].gradient+=self.gradient
      self.parent[1].gradient+=self.gradient
    elif(self.opération=='*'):
      self.parent[0].gradient+=self.gradient*self.parent[1].nombre
      self.parent[1].gradient+=self.gradient*self.parent[0].nombre
    elif(self.opération=='-'):
      self.parent[0].gradient+=self.gradient
      self.parent[1].gradient+=self.gradient*(-1)

    elif(self.opération=='ReLU'):
      if(self.nombre>0):
        self.parent[0].gradient+=self.gradient
      else:
        self.parent[0].gradient+=self.gradient*0
    elif(self.opération=='Sigmoid'):
      self.parent[0].gradient+=self.gradient*self.nombre*(1-self.nombre)

    for paren in self.parent:
      paren.backward(val=0)



  def gradientflush(self):
    self.gradient=0
    for parent in self.parent:
      parent.gradientflush()


  def optimize(self,learning_rate=0.01):
    if(len(self.parent)==2):
      if(self.parent[0]==self.parent[1]):
        self.parent[0].nombre-=learning_rate*self.parent[0].gradient
        self.parent[0].gradient=0
        self.parent[0].optimize(learning_rate)
        self.parent[1].nombre-=learning_rate*self.parent[1].gradient
        self.parent[1].gradient=0
        self.parent[1].optimize(learning_rate)
      else:
        self.parent[0].nombre-=learning_rate*self.parent[0].gradient
        self.parent[0].gradient=0
        self.parent[0].optimize(learning_rate)
        self.parent[1].nombre-=learning_rate*self.parent[1].gradient
        self.parent[1].gradient=0
        self.parent[1].optimize(learning_rate)
    if(len(self.parent)==1):
      self.parent[0].nombre-=learning_rate*self.parent[0].gradient
      self.parent[0].gradient=0
      self.parent[0].optimize(learning_rate)



class Neuron:
  def __init__(self,nin):
    self.w=[]
    self.b=Valeur(0)
    for i in range(nin):
      self.w.append(Valeur(random.random()))

  def fpass(self,input):
    res=self.b
    for i,j in zip(input,self.w):
      #print(i,j)
      res+=i*j
    return res.relu()
  def noptimize(self,learning_rate=0.01):
    for i in self.w:
      i.nombre+=learning_rate*i.gradient

class Layer:
  def __init__(self,nin,nout):
    self.neurons=[]
    for i in range(nout):
      self.neurons.append(Neuron(nin))

  def lfpass(self,input):
    res=[]
    for i in self.neurons:
      res.append(i.fpass(input))
    return res

  def loptimize(self,learning_rate=0.01):
    for i in self.neurons:
      i.noptimize(learning_rate)

class MLP:
  def __init__(self,layerlist):
    self.layers=layerlist

  def MLPfpass(self,input):
    res=input
    for i in self.layers:
      res=i.lfpass(res)
    return res

  def MLPoptimize(self,learning_rate=0.01):
    for i in self.layers:
      i.loptimize(learning_rate)