Está en la página 1de 18

UNIVERSIDAD AUTÓNOMA DE NUEVO LEÓN

FACULTAD DE INGENIERÍA
MECÁNICA Y ELECTRÍCA

PERCEPCION

ACTIVIDAD 1
COMPUERTA AND

Semestre: ENERO- AGOSTO 2020

Nombre del alumno: Alexis Nael Briseño Galván

Matrícula: 1838172

Carrera: Mecatrónica Semestre: 8°

Mayo del 2020 San Nicolás de los Garza, Nuevo León

1
INTRODUCCIÓN
Para esta tarea se utilizo un sitio web online llamado p5.js (https://p5js.org/), en la cual se pueden
subir archivos web como JavaScript, HTML, CSS, video, sonido, etc.
Realmente, p5.js es una librería la cual sirve como herramienta muy didáctica porque es posible
mostrar la ejecución de un programa de una manera muy visual haciendo uso de sketches.

CONTENIDO
El editor web contiene sketches, en el cual se pueden dibujar puntos, elipses, rectángulos,
etc. Para editar y ejecutar el código se necesita el siguiente editor de texto y el navegador
web:

El editor consta de los siguientes archivos:

2
CÓDIGO DEL ARCHIVO MATRIX.JS
A grandes rasgos este archivo JavaScript contiene las operaciones necesarias para realizar
con matrices.
class Matrix {
constructor(rows, cols) {
this.rows = rows;
this.cols = cols;
this.data = Array(this.rows).fill().map(() => Array(this.cols).fill(0));
}

copy() {
let m = new Matrix(this.rows, this.cols);
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
m.data[i][j] = this.data[i][j];
}
}
return m;
}

static fromArray(arr) {
return new Matrix(arr.length, 1).map((e, i) => arr[i]);
}

static subtract(a, b) {
if (a.rows !== b.rows || a.cols !== b.cols) {
console.log('Columns and Rows of A must match Columns and Rows of B.');
return;
}

// Return a new Matrix a-b


return new Matrix(a.rows, a.cols)
.map((_, i, j) => a.data[i][j] - b.data[i][j]);
3
}

toArray() {
let arr = [];
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
arr.push(this.data[i][j]);
}
}
return arr;
}

randomize() {
return this.map(e => Math.random() * 2 - 1);
}

add(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.cols !== n.cols) {
console.log('Columns and Rows of A must match Columns and Rows of B.');
return;
}
return this.map((e, i, j) => e + n.data[i][j]);
} else {
return this.map(e => e + n);
}
}

static transpose(matrix) {
return new Matrix(matrix.cols, matrix.rows)
.map((_, i, j) => matrix.data[j][i]);
}

static multiply(a, b) {
// Matrix product
if (a.cols !== b.rows) {
console.log('Columns of A must match rows of B.');
return;
}

return new Matrix(a.rows, b.cols)


.map((e, i, j) => {
// Dot product of values in col
let sum = 0;
for (let k = 0; k < a.cols; k++) {
sum += a.data[i][k] * b.data[k][j];
}
return sum;
4
});
}

multiply(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.cols !== n.cols) {
console.log('Columns and Rows of A must match Columns and Rows of B.');
return;
}

// hadamard product
return this.map((e, i, j) => e * n.data[i][j]);
} else {
// Scalar product
return this.map(e => e * n);
}
}

map(func) {
// Apply a function to every element of matrix
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
let val = this.data[i][j];
this.data[i][j] = func(val, i, j);
}
}
return this;
}

static map(matrix, func) {


// Apply a function to every element of matrix
return new Matrix(matrix.rows, matrix.cols)
.map((e, i, j) => func(matrix.data[i][j], i, j));
}

print() {
console.table(this.data);
return this;
}

serialize() {
return JSON.stringify(this);
}

static deserialize(data) {
if (typeof data == 'string') {
data = JSON.parse(data);
}
5
let matrix = new Matrix(data.rows, data.cols);
matrix.data = data.data;
return matrix;
}
}

if (typeof module !== 'undefined') {


module.exports = Matrix;
}

6
CÓDIGO DEL ARCHIVO NN.JS
Este archivo contiene los métodos, propiedades, operaciones, funciones, necesarias que la
red neuronal ocupa para poder funcionar:
// Other techniques for learning
class ActivationFunction {
constructor(func, dfunc) {
this.func = func;
this.dfunc = dfunc;
}
}

let sigmoid = new ActivationFunction(


x => 1 / (1 + Math.exp(-x)),
y => y * (1 - y)
);

let tanh = new ActivationFunction(


x => Math.tanh(x),
y => 1 - (y * y)
);

class NeuralNetwork {
/*
* if first argument is a NeuralNetwork the constructor clones it
* USAGE: cloned_nn = new NeuralNetwork(to_clone_nn);
*/
constructor(in_nodes, hid_nodes, out_nodes) {
if (in_nodes instanceof NeuralNetwork) {
let a = in_nodes;
this.input_nodes = a.input_nodes;
this.hidden_nodes = a.hidden_nodes;
this.output_nodes = a.output_nodes;

this.weights_ih = a.weights_ih.copy();
this.weights_ho = a.weights_ho.copy();

this.bias_h = a.bias_h.copy();
this.bias_o = a.bias_o.copy();
} else {
this.input_nodes = in_nodes;
this.hidden_nodes = hid_nodes;
this.output_nodes = out_nodes;

this.weights_ih = new Matrix(this.hidden_nodes, this.input_nodes);


this.weights_ho = new Matrix(this.output_nodes, this.hidden_nodes);
7
this.weights_ih.randomize();
this.weights_ho.randomize();

this.bias_h = new Matrix(this.hidden_nodes, 1);


this.bias_o = new Matrix(this.output_nodes, 1);
this.bias_h.randomize();
this.bias_o.randomize();
}

this.setLearningRate();
this.setActivationFunction();
}

predict(input_array) {

// Generating the Hidden Outputs


let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(this.activation_function.func);

// Generating the output's output!


let output = Matrix.multiply(this.weights_ho, hidden);
output.add(this.bias_o);
output.map(this.activation_function.func);

// Sending back to the caller!


return output.toArray();
}

setLearningRate(learning_rate = 0.1) {
this.learning_rate = learning_rate;
}

setActivationFunction(func = sigmoid) {
this.activation_function = func;
}

train(input_array, target_array) {
// Generating the Hidden Outputs
let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(this.activation_function.func);

// Generating the output's output!


8
let outputs = Matrix.multiply(this.weights_ho, hidden);
outputs.add(this.bias_o);
outputs.map(this.activation_function.func);

// Convert array to matrix object


let targets = Matrix.fromArray(target_array);

// Calculate the error


// ERROR = TARGETS - OUTPUTS
let output_errors = Matrix.subtract(targets, outputs);

// let gradient = outputs * (1 - outputs);


// Calculate gradient
let gradients = Matrix.map(outputs, this.activation_function.dfunc);
gradients.multiply(output_errors);
gradients.multiply(this.learning_rate);

// Calculate deltas
let hidden_T = Matrix.transpose(hidden);
let weight_ho_deltas = Matrix.multiply(gradients, hidden_T);

// Adjust the weights by deltas


this.weights_ho.add(weight_ho_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_o.add(gradients);

// Calculate the hidden layer errors


let who_t = Matrix.transpose(this.weights_ho);
let hidden_errors = Matrix.multiply(who_t, output_errors);

// Calculate hidden gradient


let hidden_gradient = Matrix.map(hidden, this.activation_function.dfunc);
hidden_gradient.multiply(hidden_errors);
hidden_gradient.multiply(this.learning_rate);

// Calcuate input->hidden deltas


let inputs_T = Matrix.transpose(inputs);
let weight_ih_deltas = Matrix.multiply(hidden_gradient, inputs_T);

this.weights_ih.add(weight_ih_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_h.add(hidden_gradient);

// outputs.print();
// targets.print();
// error.print();
}

9
serialize() {
return JSON.stringify(this);
}

static deserialize(data) {
if (typeof data == 'string') {
data = JSON.parse(data);
}
let nn = new NeuralNetwork(data.input_nodes, data.hidden_nodes, data.output_nodes);
nn.weights_ih = Matrix.deserialize(data.weights_ih);
nn.weights_ho = Matrix.deserialize(data.weights_ho);
nn.bias_h = Matrix.deserialize(data.bias_h);
nn.bias_o = Matrix.deserialize(data.bias_o);
nn.learning_rate = data.learning_rate;
return nn;
}

// Adding function for neuro-evolution


copy() {
return new NeuralNetwork(this);
}

// Accept an arbitrary function for mutation


mutate(func) {
this.weights_ih.map(func);
this.weights_ho.map(func);
this.bias_h.map(func);
this.bias_o.map(func);
}
}

10
CÓDIGO DEL ARCHIVO SKETCH.JS
El archivo sketch.js contiene la parte mas importante del proyecto. La variable training_data
contiene la matriz “AND”, ya que de acuerdo con las entradas se tiene una salida; si se
quisiera cambiar de compuerta, solamente se requiere de cambiar las salidas. Se crea un
objeto de red neuronal y luego se realizan las operaciones necesarias para poder inferir los
resultados. Se tiene como base un cuadrado, se explicarán los valores y la relación:
Se maneja por coordenadas, por ejemplo (x, y) cada sketch. El valor de las entradas será un
valor en x y otro en y. Por lo tanto la red neuronal debe dirigir su respuesta a la esquina
inferior derecha.
Posición 0,0: Este es el punto de origen del sketch.

Posición 400,0: En esta posición, se encuentra en 1 en el eje x, y en 0 y en el eje y.

11
Posición 400,400: En esta posición es en donde la red neuronal tratara de ajustarse para
mostrar el resultado

Posición 400,0: En esta posición se encuentra en 1 en y, y 0 en x.

let nn;
let lr_slider;

let training_data = [{
inputs: [0, 0],
outputs: [0]
},
{
inputs: [0, 1],
outputs: [0]
},
{
inputs: [1, 0],
outputs: [0]
},
12
{
inputs: [1, 1],
outputs: [1]
}
];

function setup() {
createCanvas(400, 400);
nn = new NeuralNetwork(2, 4, 1);
lr_slider = createSlider(0.01, 0.5, 0.1, 0.01);

function draw() {
background(0);

for (let i = 0; i < 10; i++) {


let data = random(training_data);
nn.train(data.inputs, data.outputs);
}

nn.setLearningRate(lr_slider.value());

let resolution = 10;


let cols = width / resolution;
let rows = height / resolution;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x1 = i / cols;
let x2 = j / rows;
let inputs = [x1, x2];
let y = nn.predict(inputs);
noStroke();
fill(y * 255);
rect(i * resolution, j * resolution, resolution, resolution);
}
}
}

CONTENIDO DEL ARCHIVO INDEX.HTML


En este archivo se contiene la estructura básica del HTML, así como las librerías a utilizar.

13
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />

</head>
<body>
<script src="sketch.js"></script>
<script src="nn.js"></script>
<script src="matrix.js"></script>
</body>

</html>

14
Para iniciar la simulación se presiona aquí:

En las siguientes imágenes se verá como poco a poco la red neuronal se va acercando al
valor de una compuerta AND, que seria 400,400.

15
16
17
REFERENCIAS
https://www.youtube.com/watch?v=f9vaiHoq-Fk

18

También podría gustarte