[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
class HopfieldNetwork { neurons: Array<Neuron> = new Array<Neuron>(); .. learn() { for (var i in this.neurons) { this.neurons[i].learnByHebbian(); } } .. } class Neuron { value: number = -1; .. synapses: Array<Synapse> = new Array<Synapse>(); .. learnByHebbian() { for (var i in this.synapses) { this.synapses[i].learnByHebbian(this.value); } } } class Synapse { .. learnByHebbian(destinationValue: number) { this.weight += destinationValue * this.source.value; } }
class HopfieldNetwork { neurons: Array<Neuron> = new Array<Neuron>(); .. update() { for (var i in this.neurons) { this.neurons[i].prepareUpdate(); } for (var i in this.neurons) { this.neurons[i].update(); } } } class Neuron { value: number = -1; previousValue: number = 0; synapses: Array<Synapse> = new Array<Synapse>(); .. prepareUpdate() { this.previousValue = this.value; } update() { this.value = this.transferFunction(sum(this.synapses, s=> s.getOutput())); } private transferFunction(sum: number): number { return (sum > 0) ? 1 : (sum == 0) ? this.previousValue : -1; } } function sum<T>(items : Array < T>, toNumber : (item: T) => number) : number { return items.map(item => toNumber(item)).reduce((a, b) => a + b); } class Synapse { weight: number = 0; source: Neuron = null; .. getOutput(): number { return this.weight * this.source.previousValue; } .. }
function sum<T>(items : Array < T>, toNumber : (item: T) => number) : number { return items.map(item => toNumber(item)).reduce((a, b) => a + b); } class HopfieldNetwork { neurons: Array<Neuron> = new Array<Neuron>(); .. getEnergy(): number { return -sum(this.neurons, n => sum(n.synapses, s => s.weight * s.source.value * n.value)) / 2; } } class Neuron { value: number = -1; .. synapses: Array<Synapse> = new Array<Synapse>(); .. } class Synapse { weight: number = 0; source: Neuron = null; .. }
function sum<T>(items : Array < T>, toNumber : (item: T) => number) : number { return items.map(item => toNumber(item)).reduce((a, b) => a + b); } class HopfieldNetwork { neurons: Array<Neuron> = new Array<Neuron>(); constructor(neuronCount: number) { for (var i = 0; i < neuronCount; i++) { this.neurons.push(new Neuron()); } for (var i in this.neurons) { var neuron = this.neurons[i]; for (var j in this.neurons) { var from = this.neurons[j]; if (neuron == from) { continue; } neuron.synapses.push(new Synapse(from)); } } } learn() { for (var i in this.neurons) { this.neurons[i].learnByHebbian(); } } update() { for (var i in this.neurons) { this.neurons[i].prepareUpdate(); } for (var i in this.neurons) { this.neurons[i].update(); } } getEnergy(): number { return -sum(this.neurons, n => sum(n.synapses, s => s.weight * s.source.value * n.value)) / 2; } } class Neuron { value: number = -1; previousValue: number = 0; synapses: Array<Synapse> = new Array<Synapse>(); tag: any = null; prepareUpdate() { this.previousValue = this.value; } update() { this.value = this.transferFunction(sum(this.synapses, s=> s.getOutput())); } private transferFunction(sum: number): number { return (sum > 0) ? 1 : (sum == 0) ? this.previousValue : -1; } learnByHebbian() { for (var i in this.synapses) { this.synapses[i].learnByHebbian(this.value); } } } class Synapse { weight: number = 0; source: Neuron = null; constructor(source: Neuron) { this.source = source; } getOutput(): number { return this.weight * this.source.previousValue; } learnByHebbian(destinationValue: number) { this.weight += destinationValue * this.source.value; } }app.ts
/// <reference path="hopfieldNetwork.ts"/> class Vector2 { x: number; y: number; static add(a: Vector2, b: Vector2): Vector2 { return { x: a.x + b.x, y: a.y + b.y }; } static mul(a: Vector2, scale: number): Vector2 { return { x: a.x * scale, y: a.y * scale }; } static createFromAngle(angle: number): Vector2 { return { x: Math.sin(angle), y: -Math.cos(angle) }; } } class NeuronView { neuron: Neuron; position: Vector2; isMouseOver: boolean; isMouseDown: boolean; isMouseClicked: boolean; context: CanvasRenderingContext2D; constructor(context: CanvasRenderingContext2D) { this.context = context; } initPath() { this.context.beginPath(); this.context.arc(this.position.x, this.position.y, 20, 0, Math.PI * 2); } update() { this.updateMouseInfo(); if (this.isMouseClicked) { this.neuron.value = -this.neuron.value; } } private updateMouseInfo() { this.initPath(); this.isMouseOver = false; if (context.isPointInPath(mouse.position.x, mouse.position.y)) { this.isMouseOver = true; this.isMouseClicked = mouse.isClicked; this.isMouseDown = mouse.isDown; } } draw() { this.initPath(); this.context.fillStyle = this.getNeuronStyle(); this.context.fill(); this.context.stroke(); } private getNeuronStyle() { if (this.isMouseOver) { if (this.isMouseDown) { return "orange"; } else { return this.neuron.value > 0 ? "rgb(240, 240, 240)" : "rgb(100, 100, 100)"; } } else { return this.neuron.value > 0 ? "white" : "black"; } } static getSynapseStyle(synapse: Synapse) { if (synapse.weight > 0) { return "red"; } else if (synapse.weight == 0) { return "lightGray"; } else { return "blue"; } } drawSynapse(synapse: Synapse) { var sourceNeuron = synapse.source; var sourceView = <NeuronView>sourceNeuron.tag; context.save(); context.beginPath(); context.strokeStyle = NeuronView.getSynapseStyle(synapse); context.lineWidth = Math.abs(synapse.weight); context.moveTo(this.position.x, this.position.y); context.lineTo(sourceView.position.x, sourceView.position.y); context.stroke(); context.restore(); } } var canvas = <HTMLCanvasElement>document.getElementById("hopfieldNetworkDemoCanvas"); var context = canvas.getContext("2d"); var hopfieldNetwork = new HopfieldNetwork(5); var neuronViews = new Array<NeuronView>(); for (var i in hopfieldNetwork.neurons) { var angle = 2 * Math.PI * i / hopfieldNetwork.neurons.length; var neuronPosition = Vector2.add( { x: 200, y: 200 }, Vector2.mul(Vector2.createFromAngle(angle), 150) ); var view = new NeuronView(context); view.neuron = hopfieldNetwork.neurons[i]; view.position = neuronPosition; view.neuron.tag = view; neuronViews.push(view); } class MouseState { position: Vector2 = {x: 10, y :10}; isDown: boolean; previousIsDown: boolean; isClicked: boolean; constructor(element: HTMLElement) { element.onmousemove = function (e) { var offset = element.getBoundingClientRect(); this.position = { x: e.pageX - offset.left, y: e.pageY - offset.top }; }.bind(this); element.onmousedown = function (e) { this.isDown = true; }.bind(this); element.onmouseup = function (e) { this.isDown = false; }.bind(this); } update() { this.isClicked = this.previousIsDown && !this.isDown; this.previousIsDown = this.isDown; } } var mouse = new MouseState(canvas); class LearnedPattern { values: Array<number>; count: number = 0; tag: any; } class LearnedPatternCollection { patterns: Array<LearnedPattern> = new Array<LearnedPattern>(); onPatternCreated; onPatternCountChanged; add(pattern: Array<number>) { if (!this.contains(pattern)) { this.create(pattern); } this.get(pattern).count++; this.onPatternCountChanged(this.get(pattern)); } private contains(pattern: Array<number>) { return this.patterns.some(p => LearnedPatternCollection.areEqual(p.values, pattern)); } private create(pattern: Array<number>) { var newInstance = new LearnedPattern(); newInstance.values = pattern; this.patterns.push(newInstance); this.onPatternCreated(newInstance); } private get(pattern: Array<number>) { for (var i in this.patterns) { if (LearnedPatternCollection.areEqual(this.patterns[i].values, pattern)) { return this.patterns[i]; } } return null; } private static areEqual(p1: Array <number>, p2: Array < number>):boolean{ if (p1.length != p2.length) { return false; } for (var i = 0; i < p1.length; i++) { if (p1[i] != p2[i]) { return false; } } return true; } } var patterns = new LearnedPatternCollection(); patterns.onPatternCreated = function (pattern: LearnedPattern) { var listElement = <HTMLTableRowElement>document.getElementById("learnedPatternList"); var learnedImageCanvas = document.createElement("canvas"); learnedImageCanvas.width = 120; learnedImageCanvas.height = 100; var learnedImageContext = learnedImageCanvas.getContext("2d"); for (var i in pattern.values) { var angle = 2 * Math.PI * i / pattern.values.length; var neuronPosition = Vector2.add( { x: 50, y: 50 }, Vector2.mul(Vector2.createFromAngle(angle), 38) ); learnedImageContext.beginPath(); learnedImageContext.arc(neuronPosition.x, neuronPosition.y, 5, 0, Math.PI * 2); learnedImageContext.fillStyle = pattern.values[i] > 0 ? "white" : "black"; learnedImageContext.fill(); learnedImageContext.stroke(); } var table = <HTMLTableElement>document.createElement("table"); table.border = "1"; table.style.styleFloat = "left"; var cell1 = (<HTMLTableRowElement>table.insertRow(0)).insertCell(0); cell1.appendChild(learnedImageCanvas); var cell2 = (<HTMLTableRowElement>table.insertRow(1)).insertCell(0); cell2.innerHTML = pattern.count + ""; pattern.tag = cell2; listElement.insertCell(0).appendChild(table); } patterns.onPatternCountChanged = function (pattern: LearnedPattern) { var cell = <HTMLTableCellElement>pattern.tag; cell.innerHTML = pattern.count + ""; } document.getElementById("learnButton").onclick = function (e) { hopfieldNetwork.learn(); patterns.add(hopfieldNetwork.neurons.map(n=> n.value)); }; document.getElementById("rememberButton").onclick = function (e) { hopfieldNetwork.update(); }; function update() { mouse.update(); for (var i in neuronViews) { neuronViews[i].update(); } } function updateEnergyText() { document.getElementById("energyText").innerText = "energy : " + hopfieldNetwork.getEnergy(); } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < neuronViews.length; i++) { var neuronView = neuronViews[i]; for (var j in neuronView.neuron.synapses) { var synapse = neuronView.neuron.synapses[j]; neuronView.drawSynapse(synapse); } } for (var i in neuronViews) { neuronViews[i].draw(); } updateEnergyText(); } setInterval(function () { update(); draw(); }, 1000 / 60.0);