El presente post es acerca de cómo implementar el algoritmo de Inteligencia Artificial llamado Perceptrón (red neuronal formada por una sola neurona) en JavaScript. Está portado del Python a través del ejemplo y explicación de I am Pablo - Programando una red neuronal simple.
El código acá presente no está optimizado, pero está realizado de tal manera que cualquiera que deba intentar aprenderlo lo pueda realizar (notar los nombres de las variables, constantes y funciones utilizadas).
El código acá presente no está optimizado, pero está realizado de tal manera que cualquiera que deba intentar aprenderlo lo pueda realizar (notar los nombres de las variables, constantes y funciones utilizadas).
// Constructor de la clase Perceptron()
var Perceptron = function Clase( cantDatos, capacidadAprendizaje = 0.1 ) {
this.cantEntradas = cantDatos ;
this.capacidadAprendizaje = capacidadAprendizaje ;
this.pesos = [] ;
for( var cadaDato = 0 ; cadaDato < cantDatos ; cadaDato++ )
this.pesos.push( Math.random() ) ; //
Inicializar pesos al azar (0..1)
}
// Habilidad/Método: Predecir( dar datos
sobre los que predecir valor )
Perceptron.prototype.predecir = function Metodo( datos ) {
var calculo = 0.00 ;
for( var cadaPeso in this.pesos ) { // Para cada peso...
calculo += datos[cadaPeso] * this.pesos[cadaPeso] ; // ...Hacer producto punto
}
return ( calculo > 0 )*1 ; //
Función de activación
}
// Habilidad/Método: Entrenar( dar
valores nuevos, dar valor a tender )
Perceptron.prototype.entrenar = function Metodo( nuevasEntradas, valorATender ) {
var laPrediccion = this.predecir( nuevasEntradas ) ;
var equivocacion = valorATender - laPrediccion ; // Error, diferencia real o equivocación
if( equivocacion != 0 ) { // Si hubo equivocación...
for( var cadaPeso in this.pesos ) {
this.pesos[cadaPeso] += this.capacidadAprendizaje * equivocacion * nuevasEntradas[cadaPeso] ;
// Corregir el error, ampliando el peso
o disminuyendo
}
}
return equivocacion ;
}
const MUJER = 1 ;
const HOMBRE = 0 ;
var datosConQueInferir = [ //
Datos con los que inferir
[ 1.70, 56, MUJER ]
, [ 1.72, 63, HOMBRE ]
, [ 1.60, 50, MUJER ]
, [ 1.70, 63, HOMBRE ]
, [ 1.74, 66, HOMBRE ]
, [ 1.58, 55, MUJER ]
, [ 1.83, 80, HOMBRE ]
, [ 1.82, 70, HOMBRE ]
, [ 1.65, 54, MUJER ]
]
var p = new Perceptron( 3 ) ; //
Creamos el perceptrón
for( var vezRepaso = 0 ; vezRepaso < 200 ; vezRepaso ++ ) { //
REPASAR (200 repasos) ->
// Cada repaso enseña al perceptrón que los valores originales a inferir
// son esa tendencia.
for( var cadaDato in datosConQueInferir ) {
var inferir = datosConQueInferir[cadaDato] ;
var posibleSalida = inferir[2] ;
var dadasEntradas = [ 1, inferir[0], inferir[1] ] ; // No entendí por qué desplaza esto con el primer 1.
p.entrenar( dadasEntradas, posibleSalida ) ;
}
} // <- REPASAR
boton.onclick = function Accion( ) {
var altura = parseFloat( inputAltura.value ) ;
var peso = parseFloat( inputPeso.value ) ;
var nuevaPrediccion = p.predecir( [ 1, altura, peso ] ) ;
mostrar(
"La persona con peso " + peso + " "
+ "y altura " + altura + " "
+ "debe ser" +
( nuevaPrediccion ? "MUJER" : "HOMBRE" )
) ;
}
Alguien le respondió a Pablo por qué ese uno en el entrenamiento/repaso y la predicción individual:
ResponderEliminarLucas Veljacic • 6 months ago
Hola,
Muy útil el blogpost. Me resulto de gran utilidad!
Te dejo un comentario, me parece que esta línea:
if pr.predict([1,h,2]) == 1: print "Mujer"
Debería decir:
if pr.predict([1,h,w]) == 1: print "Mujer"
De esa forma, las entradas del perceptron quedan: 1 (la pseudoentrada para normalizar la operación en un producto escalar), altura, peso.
Saludos!