Browse Source

Add weights chart, learning rate adjust.

master
Yorick van Pelt 5 years ago
parent
commit
d56c303c6d
  1. 5
      LemmingSim.html
  2. 53
      lemming_sim_student.js

5
LemmingSim.html

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<script language="JavaScript" src="matter.js"></script>
<script language="JavaScript" src="pathseg.js"></script>
<script language="JavaScript" src="decomp.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
</head>
<body onload="init();">
<object id="robotbodySVG" type="image/svg+xml" data="robotbody.svg" width=0 ></object>
@ -51,12 +52,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<tr><th colspan="2">Experiments</th></tr>
<tr><td><label for="robotAmnt">Robot Count</label></td><td><input id="robotAmnt" type="number" value="1" min="0" max="3" /></td></tr>
<tr><td><label for="ffwdtimes">nr of experiments</label></td><td><input id="ffwdtimes" type="number" value="10" min="1" max="20" /></td></tr>
<tr><td><label for="wanderRate">robot wander rate</label></td><td><input id="wanderRate" type="number" value="0.0002" step="0.0001"></td></tr>
<tr><td><label for="learningRate">robot learning rate</label></td><td><input id="learningRate" type="number" value="0.01" step="0.001"></td></tr>
<tr><td><label for="forgetRate">robot forgetting rate</label></td><td><input id="forgetRate" type="number" value="0.01" step="0.001"></td></tr>
<tr><td><label for="boxFric">box friction</label></td><td><input id="boxFric" type="number" value="0.001" step="0.0005" min=0></td></tr>
<tr><td><label for="boxX">Boxes:</label></td><td><input id="boxX" type="number" value="4" min=1 max=10>x<input id="boxY" type="number" value="4" min=1 max=10></td></tr>
<tr><td><input type="button" value="Restart Slow" onclick="initSimulation(); sim.start()" /><input type="button" value="toggle pause" onclick="sim.toggle()"></td><td><input type="button" value="run experiments" onclick="runExperiments()" /><input type="button" value="clear" onclick="resultsTable.clear()" /></td></tr>
<tr><td></td></tr>
</tbody></table>
<table id="results"></table>
<canvas id="weightschart" width="400" height="400"></canvas>
</body>
</html>

53
lemming_sim_student.js

@ -61,8 +61,6 @@ class HebbDidaBot extends Robot {
constructor(props) {
const angle = Math.PI/3.5
super(Object.assign({
learningRate: 0.001,
forgettingRate: 0.001,
sensors: [
new CollisionSensor('collL', {
attachAngle: -angle
@ -106,7 +104,7 @@ class HebbDidaBot extends Robot {
const collact = [+collL, +collR]
const collisionlayer = feedforward(this.weights, percact, collact)
const motorLayer = feedforward(motorweights, collisionlayer, [0,0])
this.weights = hebb(this.weights, this.info.learningRate, this.info.forgettingRate, percact, collisionlayer)
this.weights = hebb(this.weights, simInfo.learningRate, simInfo.forgetRate, percact, collisionlayer)
const [left, right] = motorLayer.map(threshold(0.5))
// output: 2 neurons. if left is activated, turn left. if right is activated, turn right.
// if both, go backwards. otherwise: forward
@ -300,6 +298,7 @@ class Simulation {
Matter.Events.on(this.engine, 'tick', this.step.bind(this));
this.bay = new Bay()
}
destroy() {
this.stop()
@ -405,7 +404,8 @@ function initSimulation() {
sim.destroy()
}
simInfo.boxFric = +document.getElementById("boxFric").value
simInfo.wanderRate = +document.getElementById("wanderRate").value
simInfo.learningRate = +document.getElementById("learningRate").value
simInfo.forgetRate = +document.getElementById("forgetRate").value
sim = new Simulation()
sim.init()
let noRobots = +document.getElementById('robotAmnt').value
@ -474,17 +474,19 @@ function countclusters(sim) {
// automatically run the experiments based on the values from the html
async function experimentRunner(stopCondition) {
initSimulation()
resultsTable.clearChart()
while((stopCondition ? !stopCondition(sim) : true) && sim.curSteps < simInfo.maxSteps) {
sim.runSteps(500)
resultsTable.addWeightsPoint(sim.curSteps, sim.robots[0].weights)
// take a break for the gui to stay responsive
await promiseTimeout(50)
}
// save data
const clusters = countclusters(sim)
const rv = {
perc_in_clusters: (clusters.reduce((p,c) => c > 2 ? p+c : p, 0) / sum(clusters)) * 100,
steps: sim.curSteps,
//done: stopCondition(sim),
//redblocks: redblocksatwall(sim),
clusters: countclusters(sim),
robots: sim.robots.length
}
@ -503,19 +505,50 @@ async function runExperiments() {
class ResultsTable {
constructor(elem) {
this.elem = elem
this.canvas = document.getElementById('weightschart')
this.chart = new Chart(this.canvas.getContext('2d'), {
type: 'line',
data: {
labels: [],
datasets: [
]
},
options: {
responsive: false
},
})
}
addWeightsPoint(step, weights) {
this.chart.data.labels.push(step)
this.chart.data.datasets[0].data.push(weights[0][0])
this.chart.data.datasets[1].data.push(weights[0][1])
this.chart.data.datasets[2].data.push(weights[1][0])
this.chart.data.datasets[3].data.push(weights[1][1])
this.chart.update()
}
clear() {
this.elem.innerHTML = "<tr><th colspan=4>Experiment Results</th></tr>"
const tr = document.createElement('tr')
const headers = ["robots", "steps", "clusters"]
const headers = ["robots", "steps", "clusters", "cluster%"]
headers.forEach(txt => {
tr.appendChild(document.createElement('th')).appendChild(document.createTextNode(txt))
})
this.elem.appendChild(tr)
}
add({steps, clusters, robots}) {
this.clearChart()
}
clearChart() {
this.chart.data.labels = []
this.chart.data.datasets = [
{label: "w00", data: [], fill: false, borderColor: 'red', backgroundColor: 'red'},
{label: "w01", data: [], fill: false, borderColor: 'blue', backgroundColor: 'blue'},
{label: "w10", data: [], fill: false, borderColor: 'green', backgroundColor: 'green'},
{label: "w11", data: [], fill: false, borderColor: 'yellow', backgroundColor: 'yellow'},
]
this.chart.update()
}
add({steps, clusters, robots, perc_in_clusters}) {
const tr = document.createElement('tr')
;[robots, steps, clusters.toString()].forEach(txt => {
;[robots, steps, clusters.toString(), perc_in_clusters].forEach(txt => {
tr.appendChild(document.createElement('td')).appendChild(document.createTextNode(txt))
})
this.elem.appendChild(tr)

Loading…
Cancel
Save