UNPKG

lysergic

Version:

Synaptic's neural network compiler

217 lines 8.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const activations_1 = require("./ast/activations"); class Topology { constructor(options) { this.heap = null; this.biasUnit = null; this.inputsOf = []; this.unitParameters = []; this.projectedBy = []; this.gatersOf = []; this.gatedBy = []; this.inputsOfGatedBy = []; this.projectionSet = []; this.gateSet = []; this.inputSet = []; this.connections = []; this.gates = []; this.layers = []; this.activationFunction = []; this.units = 0; const { heap } = options; this.heap = heap; this.biasUnit = this.addUnit({ bias: false }); this.heap.setVariable('state', this.biasUnit, 1); this.heap.setVariable('activation', this.biasUnit, 1); } normalize2D(key) { let arr = this[key]; if (!(arr instanceof Array)) { this[key] = []; return; } else { for (let i in arr) { this[key][i] = this[key][i] || []; } } } normalize3D(key) { let arr = this[key]; if (!(arr instanceof Array)) { this[key] = []; return; } else { for (let i in arr) { let subArr = arr[i]; if (!(subArr instanceof Array)) { subArr[i] = []; } else { for (let i in subArr) { subArr[i] = subArr[i] || []; } } } } } normalize() { this.normalize2D('inputsOf'); this.normalize2D('projectedBy'); this.normalize2D('gatersOf'); this.normalize2D('gatedBy'); this.normalize3D('inputsOfGatedBy'); this.normalize2D('projectionSet'); this.normalize2D('gateSet'); this.normalize2D('inputSet'); this.normalize2D('layers'); } addUnit(options = {}) { const { bias = true, activationFunction = activations_1.ActivationTypes.LOGISTIC_SIGMOID, l1 = 0, l2 = 0, parameters = [] } = options; const unit = this.units++; this.inputsOf[unit] = []; this.projectedBy[unit] = []; this.gatersOf[unit] = []; this.gatedBy[unit] = []; this.inputsOfGatedBy[unit] = []; this.inputSet[unit] = []; this.projectionSet[unit] = []; this.gateSet[unit] = []; this.unitParameters[unit] = { l1, l2, parameters }; this.activationFunction[unit] = activationFunction; this.heap.setVariable('state', unit, 0); this.heap.setVariable('activation', unit, 0); this.heap.setVariable('derivative', unit, 0); this.heap.setVariable('gain', unit, unit, 1); this.heap.setVariable('elegibilityTrace', unit, unit, 0); this.heap.setVariable('errorResponsibility', unit, 0); this.heap.setVariable('projectedErrorResponsibility', unit, 0); this.heap.setVariable('gatedErrorResponsibility', unit, 0); if (bias) { this.addConnection(this.biasUnit, unit, 1); } return unit; } addConnection(from, to, weight) { if (this.connections.some(connection => connection.from === from && connection.to === to)) { return; } this.connections.push({ from, to }); const isSelfConnection = (from === to); this.heap.setVariable('gain', to, from, 1); this.heap.setVariable('gradient', to, from, 0); this.heap.setVariable('weight', to, from, isSelfConnection ? 1 : weight); this.heap.setVariable('elegibilityTrace', to, from, 0); this.track(to); this.track(from); } addGate(from, to, gater) { const alreadyGated = this.gates.some(gate => gate.from === from && gate.to === to); const isBias = from === this.biasUnit; if (alreadyGated || isBias) { return; } this.gates.push({ from, to, gater }); this.track(to); this.track(from); this.track(gater); } addLayer(size = 0, options) { const layer = []; for (let i = 0; i < size; i++) { const unit = this.addUnit(options); layer.push(unit); } this.layers.push(layer); return layer; } track(unit) { this.inputsOf[unit] = distinct(this.connections .filter(connection => connection.to === unit) .map(connection => connection.from)); this.projectedBy[unit] = distinct(this.connections .filter(connection => connection.from === unit) .map(connection => connection.to)); this.gatersOf[unit] = distinct(this.gates .filter(gate => gate.to === unit) .map(gate => gate.gater)); this.gatedBy[unit] = distinct(this.gates .filter(gate => gate.gater === unit) .map(gate => gate.to)); this.inputsOf[unit].forEach(i => { this.gatedBy[unit].forEach(k => { this.heap.setVariable('extendedElegibilityTrace', unit, i, k, 0); }); }); this.projectedBy[unit].forEach(j => { this.gatedBy[j].forEach(k => { this.heap.setVariable('extendedElegibilityTrace', j, unit, k, 0); }); }); this.gatersOf[unit].forEach(j => { this.inputsOf[j].forEach(i => { this.heap.setVariable('extendedElegibilityTrace', j, i, unit, 0); }); }); this.inputsOf[unit].forEach(i => { this.gatersOf[unit].forEach(j => { this.inputsOfGatedBy[unit][j] = distinct(this.inputsOfGatedBy[unit][j], this.gates .filter(gate => gate.gater === j && gate.to === unit && gate.from === i) .map(gate => gate.from)); }); }); this.gatedBy[unit].forEach(k => { this.inputsOf[k].forEach(i => { this.inputsOfGatedBy[k][unit] = distinct(this.inputsOfGatedBy[k][unit], this.gates .filter(gate => gate.gater === unit && gate.to === k && gate.from === i) .map(gate => gate.from)); }); }); this.gatedBy[unit].forEach(k => { if (this.gates.some(gate => gate.to === k && gate.from === k && gate.gater === unit)) { this.heap.setVariable('derivativeTerm', k, unit, 1); } }); this.gatersOf[unit].forEach(j => { if (this.gates.some(gate => gate.to === unit && gate.from === unit && gate.gater === j)) { this.heap.setVariable('derivativeTerm', unit, j, 1); } }); this.inputSet[unit] = this.inputsOf[unit].filter(input => input !== unit); this.projectionSet[unit] = this.projectedBy[unit].filter(projected => projected > unit); this.gateSet[unit] = this.gatedBy[unit].filter(gated => gated > unit); } toJSON() { return { biasUnit: this.biasUnit, inputsOf: this.inputsOf, projectedBy: this.projectedBy, gatersOf: this.gatersOf, gatedBy: this.gatedBy, inputsOfGatedBy: this.inputsOfGatedBy, projectionSet: this.projectionSet, gateSet: this.gateSet, inputSet: this.inputSet, connections: this.connections, gates: this.gates, layers: this.layers }; } } exports.Topology = Topology; function distinct(...arrays) { const concated = arrays.reduce((concated, array) => concated.concat(array || []), []); let o = {}, a = [], i; for (i = 0; i < concated.length; o[concated[i++]] = 1) ; for (i in o) a.push(+i); return a; } //# sourceMappingURL=Topology.js.map