Perceptrón (Inteligencia Artificial) con JavaScript

Ufff! Sí, más de un año desde el último post y, viendo las estadísticas del blog (Claramente) la gente que lo consulta es casi nula. Pero, los que me han seguido sabrán que mudé toda la creación de contenido a mi canal de YouTube: https://youtube.com/user/lacosagorda

En el canal subo un video (Como mínimo) por semana así que todo sigue activo. De cualquier manera, vuelvo por acá y no es que vaya a decir lo que suelo y luego me muerdo a mi mismo porque no puedo cumplirlo. Sí, lo que voy a decir es que iré dejando por acá esas cosas que hago de vez en cuando por puro gusto y que, por algún motivo, no he puesto en videos.

Como ya saben, me gusta explorar más allá de las herramientas que podamos usar. No quiero quedarme con el hecho de poder saber usar tal o cual framework: Quiero hacerlo por mí mismo (Aunque luego use un framework).

En fin, como el mundo de la inteligencia artificial está más movido que nunca y todo el mundo quiere usar este u otro framework, me puse en la tarea de comenzar a crear (Y entender) uno de los conceptos más comunes dentro del mundo de la IA: Cómo crear mi propia red neuronal que pueda aprender por su cuenta y sepa “predecir” determinados resultados en base a entrenamiento.

Así que, para poder iniciar, había que arrancar con la unidad más básica que se usa en este tipo de redes, junto a la función más comunmente usada. Estos son el “perceptrón” y la función “sigmoide”.

Por supuesto, no voy a entrar en detalle sobre cada uno de estas cosas porque (Y queda dicho para todos los siguientes posts que vengan), no quiero escribir tanto detallando cada una de estas ideas, las cuales requieren muchas páginas (Pero muchas). Si hace falta más información siempre se podrá acudir a una búsqueda en Google 🙂

En fin, un perceptrón; en este caso para operaciones tipo OR; nos sirve para poder categorizar entre dos tipos de elementos. La función sigmoide, por otro lado, le ayuda al perceptrón para marcar el umbral de activación para una operación dada en dicho perceptrón.

Básicamente obtendremos un 1 o un 0 si la operación se acerca al valor calculado/esperado. (De nuevo, estoy tratando de explicarlo lo más simple posible para no escribir toneladas de texto)

En definitiva, les dejo el “perceptrón“:

var perceptron = (function() {

    var neuro = function() {
        
        this._seed = 1;
        this._threshold = 1;
        this._bias = 1;
        this._learnRate = 0.1;
        this._weights = [];
        this._neuralData = [];
    };

    neuro.prototype._random = function() {
        var x = Math.sin(this._seed++) * 10000;
        return x - Math.floor(x);
    };

    neuro.prototype._multiply = function (inputs) {
        var result = 0;

        for (var i = 0; i < inputs.length; i++) {
            result += inputs[i] * this._weights[i];
        }

        result += this._threshold * this._weights[this._weights.length - 1];

        return result;
    },

    neuro.prototype._sigmoid = function(x) {
        return 1 / (1 + Math.pow(Math.E, -x));
    };

    neuro.prototype._retrain = function() {
        var neuralDataLength = this._neuralData.length;
        var hasSuccess = true;

        for (var i = 0; i < neuralDataLength; i++) {
            var trainData = this._neuralData.shift();

            hasSuccess = this.train(trainData.input, trainData.target) && hasSuccess;
        }

        return hasSuccess;
    };

    neuro.prototype.exercise = function(iterations) {
        var i = 0;

        while (i++ < iterations) {
            var trainResult = this._retrain();

            if (trainResult === true) {
                console.log('Retraining ended after ' + i + ' attempts');
                break;
            }
        }
    };

    neuro.prototype.train = function (inputs, expected) {
        
        while (this._weights.length < inputs.length) {
            this._weights.push(this._random());
        }

        //neuron bias
        if (this._weights.length === inputs.length) {
            this._weights.push(this._bias);
        }

        var preceptionResult = this.process(inputs); //this.percieve(inputs);
        this._neuralData.push({input: inputs, target: expected, prev: preceptionResult})

        if (preceptionResult !== expected) {
            for (var i = 0; i < this._weights.length; i++) { var input = (i == inputs.length) ? this._threshold : inputs[i]; var adjustment = (expected - preceptionResult) * this._learnRate * input; this._weights[i] += adjustment; if (isNaN(this._weights[i])) throw new Error('Weight out of boundaries'); } return false; } return true; }; neuro.prototype.process = function (inputs) { return Number(this._sigmoid(this._multiply(inputs, this._weights)) > 0.5);
    };

    return new neuro();
}());

Para poder utilizar este objeto lo primero que deberemos hacer es entrenar nuestro perceptrón:

perceptron.train([0, 0], 0);
perceptron.train([0, 1], 0);
perceptron.train([1, 0], 0);

El primer parámetro en la función “train” es un vector con los diferentes (En este caso) valores que representan un modelo válido y el segundo, el resultado. Esto es, si tenemos los elementos del primero parámetro, esperamos como resultado el segundo parámetro. Para el primer caso, si tenemos un “0, 0”, esperamos “0” como respuesta.

perceptron.exercise(10000);

El siguiente paso es entrenar intensivamente el perceptrón con los datos enviados. Esto simplemente aplicará la función interna N cantidad de veces hasta encontrar un valor aproximado que pudiese dar los resultados esperados.

Una vez entrenado, ya podemos “preguntarle”:

console.log(perceptron.process([1, 1]));

En este caso, el resultado será “1”. Que, en base al modelo que hemos armado, es lo que esperamos.

Anuncios

Un comentario sobre “Perceptrón (Inteligencia Artificial) con JavaScript

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.