Languages
[Edit]
EN

JavaScript - distance neural network

7 points
Created by:
crystal
632

In this short article, we would like to show how to implement distance network in JavaScript.

Practical example:

// ONLINE-RUNNER:browser;

// Common utils:

function detectArrayHeight(array) {
    if (array == null) {
        return 0;
    }
    return array.length;
}
	
function detectArrayWidth(array) {
    if (array == null || array.length == 0) {
        return 0;
    }
    var tmp = array[0];
    if (tmp == null) {
        return 0;
    }
    return tmp.length;
}


// Distance neuron:

// -- utils

function createDistanceNeuron(inputsCount, distance, createWeight) {
    var weights = Array(inputsCount);
    for (var i = 0; i < weights.length; ++i) {
        weights[i] = createWeight(i);
    }
    return new DistanceNeuron(weights, distance);
}

function createZeroedNeuron(inputsCount, distance) {
    return createDistanceNeuron(inputsCount, distance, function() {
        return 0.0;
    });
}

function createRandomNeuron(inputsCount, distance) {
    return createDistanceNeuron(inputsCount, distance, function() {
        return Math.random();
    });
}

// -- distances

// Source: https://dirask.com/posts/JavaScript-Chebyshev-Distance-function-p5q6Rp
//
function calculateChebyshevDistance(a, b) {
    if (a.length === 0 || a.length !== b.length) {
      	return NaN;
    }
    var max = Math.abs(a[0] - b[0]);
    for (var i = 1; i < a.length; ++i) {
        var tmp = Math.abs(a[i] - b[i]);
        if (tmp > max) {
            max = tmp;
        }
    }
    return max;
}

function calculateEuclideanDistance(a, b) {
    if (a.length === 0 || a.length !== b.length) {
      	return NaN;
    }
	var sum = 0.0;
	for (var i = 0; i < a.length; ++i) {
		var tmp = a[i] - b[i];
		sum += tmp * tmp;
	}
	return Math.sqrt(sum);
}

// Source: https://dirask.com/posts/JavaScript-Rectilinear-Distance-function-1XgJgj
//
function calculateRectilinearDistance(a, b) {
    if (a.length === 0 || a.length !== b.length) {
      	return NaN;
    }
    var sum = 0.0;
    for (var i = 0; i < a.length; ++i) {
        sum += Math.abs(a[ i ] - b[i]);
    }
    return sum;
}

// -- neuron

function DistanceNeuron(weights, distance) {
	this.getWeights = function() {
		return weights;
	};
	this.getDistance = function() {
		return distance;
	};
	this.randomize$1 = function() {
		this.randomize$2(0.0, 1.0);
	};
	this.randomize$2 = function(min, max) {
		var range = max - min;
        for (var i = 0; i < weights.length; ++i) {
            weights[i] = min + range * Math.random();
        }
	};
	this.compute = function(inputs) {
		return distance.call(null, weights, inputs);
    };
}


// Distance network:

// -- utils

function createDistanceNetwork(inputsCount, width, height, createNeuron) {
    var neurons = Array(height);
    for (var i = 0; i < neurons.length; ++i) {
        var tmp = Array(width);
        for (var j = 0; j < tmp.length; ++j) {
            tmp[j] = createNeuron(i, j);
        }
        neurons[i] = tmp;
    }
    return new DistanceNetwork(inputsCount, neurons);
}

function createZeroedNetwork(inputsCount, width, height, distance) {
    return createDistanceNetwork(inputsCount, width, height, function() {
        return createZeroedNeuron(inputsCount, distance);
    });
}

function createRandomNetwork(inputsCount, width, height, distance) {
    return createDistanceNetwork(inputsCount, width, height, function() {
        return createRandomNeuron(inputsCount, distance);
    });
}

// -- network

function DistanceNetwork(inputsCount, neurons) {
	var width = detectArrayWidth(neurons);
	var height = detectArrayHeight(neurons);
    var outputsCount = width * height;

	this.getInputsCount = function() {
		return inputsCount;
	};
  
  	this.getOutputsCount = function() {
		return outputsCount;
	};

	this.getWidth = function() {
		return width;
	};

	this.getHeight = function() {
		return height;
	};

	this.getNeurons = function() {
		return neurons;
	};

	this.getNeuron$1 = function(position) {
		return this.getNeuron$2(position.x, position.y);
	};
	
	this.getNeuron$2 = function(positionX, positionY) {
		var tmp = neurons[positionY];
        if (tmp) {
            return tmp[positionX];
        }
		return null;
	};
	
  	this.randomize$1 = function() {
		for (var y = 0; y < height; ++y) {
			var tmp = neurons[y];
			for (var x = 0; x < width; ++x) {
				tmp[x].random$1();
            }
		}
	};

	this.randomize$2 = function(min, max) {
		for (var y = 0; y < height; ++y) {
			var tmp = neurons[y];
			for (var x = 0; x < width; ++x) {
				tmp[x].randomize$2(min, max);
            }
		}
	};

	// Computes neurons outputs.
	//
	this.compute$1 = function(inputs) {
        var index = -1;
        var outputs = new Array(outputsCount);
		for (var y = 0; y < height; ++y) {
			var tmp = neurons[y];
			for (var x = 0; x < width; ++x) {
				outputs[++index] = tmp[x].compute(inputs);
            }
		}
		return outputs;
	}

  	// Computes neurons outputs for each data row.
	//
	this.compute$2 = function(data) {
		var result = Array(data.length);
		for (var i = 0; i < data.length; ++i) {
			result[i] = this.compute$1(data[i]);
        }
		return result;
	}

	// Searches for the winning neuron and returns his position.
    // Winning neuron is neuron that has weights closest to the inputs values (smallest distance).
	//
	this.search$1 = function(inputs) {
		var positionX = -1;
		var positionY = -1;
        var index = -1;
		var value = +Infinity;
        var outputs = new Array(outputsCount);
		for (var y = 0; y < height; ++y) {
			var tmp = neurons[y];
			for (var x = 0; x < width; ++x) {
				var output = tmp[x].compute(inputs);
				if (output < value) {
					positionX = x;
					positionY = y;
					value = output;
				}
				outputs[++index] = output;
			}
		}
		if (positionX == -1) {
			return null;
        }
		return {
            x: positionX,
            y: positionY,
            value: value
         };
	}
	
    // Searches for the winning neuron of each data row and returns their positions.
	//
	this.search$2 = function(data) {
		var result = Array(data.length);
		for (var i = 0; i < data.length; ++i) {
			result[i] = this.search$1(data[i]);
        }
		return result;
	}
}


// Usage example:

var inputsCount = 4;
var networkWidth = 2;
var netowrkHeight = 2;

// Available dinstance functions:
//
//   - calculateChebyshevDistance
//   - calculateRectilinearDistance
//   - calculateEuclideanDistance
//
var network = createRandomNetwork(inputsCount, networkWidth, netowrkHeight, calculateEuclideanDistance);

var inputs = [1, 2, 3, 4];
var outputs = network.compute$1(inputs);
var winner = network.search$1(inputs);  // winning neuron

console.log(outputs);       // Example values: [4.748160, 5.262563, 4.421735, 5.239144]

console.log(winner.x);      // Example value: 0
console.log(winner.y);      // Example value: 1
console.log(winner.value);  // Example value: 4.421735

Hint: in real problem it is good to work with normalized data (input data).

 

See also

  1. JavaScript - distance neuron

  2. JavaScript - Chebyshev Distance function

  3. JavaScript - Rectilinear Distance function

  4. JavaScript - Kohonen Neural Network (WTA Learning)

  5. JavaScript - Kohonen Neural Network (WTM Learning)

Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join