// const uid = require("cuid");
const Neuron = require("./neuron");
const Connection = require("./connection");
/**
* A `Group` is an abstraction of `Neuron` and a tool for creating and manipulating a group of neurons - with `Group` we can create neural network layers and and build networks faster than neuron-by-neuron construction.
*
* @constructs Group
*
* @param {number} [size]
* @param {number} [bias]
*
* @prop {string} id
* @prop {Neuron[]} neurons
*/
function Group(size, bias) {
// this.id = uid();
this.neurons = size == undefined ? [] : Array.from({ length: size }, function() {
return new Neuron(bias);
});
//================================================
// CORE FUNCTIONS ================================
//================================================
/**
* @param {Group} target
* @param {number[]} [weights]
*
* @example
* //===============================================
* // 2x2 (No Weights) =============================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const group = new Group(2);
* const other = new Group(2);
*
* group.connect(other);
*
* //===============================================
* // 2x2 (Weights) =============================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const group = new Group(2);
* const other = new Group(2);
*
* // group[0] -- weights[0] --> other[0]
* // group[0] -- weights[1] --> other[1]
* // group[1] -- weights[2] --> other[0]
* // group[1] -- weights[3] --> other[1]
* group.connect(other, [0.1, 0.2, 0.3, 0.4]);
*/
this.connect = function(target, weights) {
const self = this;
this.neurons.forEach(function(neuron, a) {
target.neurons.forEach(function(other, b) {
if(weights) neuron.connect(other, weights[self.neurons.length * a + b]);
else neuron.connect(other);
})
})
}
/**
* @param {number[]} [inputs]
*
* @returns {number[]}
*
* @example
* //===============================================
* // One Group (No Hidden Layers) =================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const group = new Group(2);
*
* neuron.activate([0, 0]); // [0, 0]
*
* //===============================================
* // Three Groups (Hidden Layers) =================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const input = new Group(2); // Input Neuron (Layer)
* const hidden = new Group(2,0.1); // Hidden Neuron (Layer)
* const output = new Group(2,0.15); // Output Neuron (Layer)
*
* input.connect(hidden, [0.2,0.25,0.3,0.35]); // Connects input layer to hidden layer
* hidden.connect(output, [0.4,0.45,0.5,0.55]); // Connects hidden layer to output layer
*
* input.activate([0,0]); // [0,0]
* hidden.activate(); // [0.###, 0.###]
* output.activate(); // [0.###, 0.###]
*
*/
this.activate = function(inputs) {
return this.neurons.map(function(neuron, index) {
if(inputs) return neuron.activate(inputs[index]);
else return neuron.activate();
})
}
/**
* @param {number[]} [targets]
* @param {number} [rate=0.3]
*
* @returns {number[]}
*
* @example
* //===============================================
* // One Group (No Hidden Layers) =================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const group = new Group(2);
*
* neuron.activate([0, 0]); // [0, 0]
* neuron.propagate([0, 1]); // [0, -1]
*
* //===============================================
* // Three Groups (Hidden Layers) =================
* //===============================================
* const { Group } = require("@liquidcarrot/nn")
*
* const input = new Group(2); // Input Neuron (Layer)
* const hidden = new Group(2,0.1); // Hidden Neuron (Layer)
* const output = new Group(2,0.15); // Output Neuron (Layer)
*
* input.connect(hidden, [0.2,0.25,0.3,0.35]); // Connects input layer to hidden layer
* hidden.connect(output, [0.4,0.45,0.5,0.55]); // Connects hidden layer to output layer
*
* input.activate([0,0]); // [0,0]
* hidden.activate(); // [0.###, 0.###]
* output.activate(); // [0.###, 0.###]
*
* output.propagate([0, 1]); // [0, -1]
* hidden.propagate(); // [0.###, 0.###]
* input.propagate(); // [0.###, 0.###]
*/
this.propagate = function(targets, rate=0.3) {
return this.neurons.map(function(neuron, index) {
if(targets) return neuron.propagate(targets[index]);
else return neuron.propagate();
})
}
//================================================
// END CORE FUNCTIONS ============================
//================================================
//================================================
// UTILITY FUNCTIONS =============================
//================================================
//Code here...
//================================================
// END UTILITY FUNCTIONS =========================
//================================================
}
Group.connect = function(from, to) {
const connections = [];
for(let f = 0; f < from.length; f++) {
for(let t = 0; t < to.length; t++) {
connections.push(new Connection(from[f], to[t]));
}
}
return connections;
}
module.exports = Group;