Помогите, разобраться в роботе Персептрона. Подаю на тренировку координаты и цвета. Что мне нужно из него получить чтобы генерируемая точка появлялась в одном из восьми областей. Типа должно быть 3 входа и 8 выходов как это понять?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<body onload="points();">
<div style="display: flex; justify-content: center; ">
<canvas id="canvas" width="600px" height="600px" onmousemove="cnvs_getCoordinates(event)" onmouseout="cnvs_clearCoordinates()"
style=" background-color:#131313db; "
></canvas>
</div>
<div style="display: flex; justify-content: center; ">
<input type="button" id="add" value="Сгенерировать точку" onclick="f()">
</div>
<div id="xycoordinates"></div>
<script type="text/javascript">
function cnvs_getCoordinates(e)
{
x=e.clientX;
y=e.clientY;
document.getElementById("xycoordinates").innerHTML="Координаты: ("+ "x:" + x + ","+ "y:" + y + ")";
}
function cnvs_clearCoordinates()
{
document.getElementById("xycoordinates").innerHTML="";
}
var collor = [];
function points() {
var tr=[];
const p = new Perceptron();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.moveTo(300,0);
ctx.lineTo(300,600);
ctx.stroke();
let y_pos=150;
for(let i=0; i<4; i++){
ctx.moveTo(0,y_pos);
ctx.lineTo(600,y_pos);
ctx.stroke();
y_pos+=150;
}
for (var j = 0; j < 8; j++) {
collor[j]='rgb('+getRandomInt(0,255)+', '+getRandomInt(0,255)+', '+getRandomInt(0,255)+')';
}
col = 10;
let arrX = Array();
let arrY = Array();
var colorPoint= Array();
let n =0;
var g = -1;
if (canvas.getContext){
for (var j = 0; j < 8; j++) {
if (j%2!=0) n=1
else {n=0;g++;}
for(var i=0;i<col;i++){
ctx.beginPath();
var x = getRandomInt(299*n,299*(n+1));
var y = getRandomInt(149*g,149*(g+1));
arrX.push(x);
arrY.push(y);
var radius = 3;
var startAngle = 0;
var endAngle = Math.PI+(Math.PI*Math.PI)/2;
ctx.fillStyle = collor[j];
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.fill();
colorPoint.push(j);
}
}
}
var colElmTr = arrX.length;
for (i = 0; i <colElmTr; i++) tr.push([arrX[i],arrY[i],colorPoint[i]]);
for (i = 0; i <colElmTr; i++) {
for (var j = 0; j < 8; j++) {
if (j==tr[i][2]) {
p.train([tr[i]],1);
}
else p.train([tr[i]],0);
}
}
}
function f(){
const p = new Perceptron();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
if (canvas.getContext){
ctx.beginPath();
var x = getRandomInt(0,600);
var y = getRandomInt(0,600);
var radius = 5;
var startAngle = 0;
var endAngle = Math.PI+(Math.PI*Math.PI)/2;
var c = collor[getRandomInt(0,7)];
ctx.fillStyle = c;
p.predict([x,y,c]);
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.fill();
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
class Perceptron {
constructor(bias=1,learningRate=0.1,weights=[]) {
this.bias = bias;
this.learningRate = learningRate;
this.weights = weights;
this.trainingSet = [];
}
// Инициализация весов до 0 и добавление веса смещения
init(inputs,bias=this.bias) {
this.weights = [...inputs.map(i => Math.random()), bias];
}
train(inputs,expected) {
if (!this.weights.length) this.init(inputs);
if (inputs.length != this.weights.length) inputs.push(1); // Добавление смещения
// Сохранение этого в тренировочном наборе
if (!this.trainingSet.find(t => t.inputs.every((inp,i) => inp === inputs[i]))) this.trainingSet.push({inputs,expected});
const actual = this.evaluate(inputs);
if (actual == expected) return true; // правильные веса возвращаются
// В противном случае обновляем каждый вес путем добавления ошибка * скорость
this.weights = this.weights.map((w,i) => w += this.delta(actual, expected,inputs[i]));
return this.weights;//Полученные веса
}
// Вычисляет разницу между фактическим и ожидаемым
delta(actual, expected, input,learningRate=this.learningRate) {
const error = expected - actual;
return error * learningRate * input;
}
// Повторяется до тех пор, пока веса не будут правильно установлены
learn(iterationCallback=()=>{},trainingSet=this.trainingSet) {
let success = false;
while (!success) {
// Функция по выбору, которая будет вызвана после завершения итерации
iterationCallback.call(this);
success = trainingSet.every(t => this.train(t.inputs,t.expected) === true);
}
}
// Входы сумм * веса
weightedSum(inputs=this.inputs,weights=this.weights) {
return inputs.map((inp,i) => inp * weights[i]).reduce((x,y) => x+y,0);
}
//Вычисления с использованием текущих весов
evaluate(inputs) {
return this.activate(this.weightedSum(inputs));
}
//Работа Парцептрона
predict(inputs) {
return this.evaluate([...inputs,1]);
}
//Типа активация
activate(value) {
return value >= 0 ? 1 : 0;
}
}
</script>
</body>
</html>