Skip to content

Instantly share code, notes, and snippets.

@mpj
Last active October 25, 2019 13:13
Show Gist options
  • Save mpj/d93a4bdcce7b31f7a70ae66bdb34a9f9 to your computer and use it in GitHub Desktop.
Save mpj/d93a4bdcce7b31f7a70ae66bdb34a9f9 to your computer and use it in GitHub Desktop.
Neural Vanilla Workshop
<html>
<!-- http://bit.ly/vanillaneural -->
<head>
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div class="legend legendX">Scariness</div>
<div class="legend legendY">Actual power</div>
<canvas id="mycanvas" width="1000" height="1000"></canvas>
<script>
const someDragons = generateDragons(500)
function generateDragons(numberOfDragonsToGenerate) {
let dragons = []
for (let i = 0; i < numberOfDragonsToGenerate; i++) {
const dragon = {
scariness: randomNumber(0, 1000),
power: randomNumber(0, 1000)
}
dragons.push(dragon)
}
return dragons
}
const initialWeights = {
scariness: randomNumber(-1, 1),
power: randomNumber(-1, 1),
}
let trainedWeights = initialWeights
const trainingSetSize = 20000
const noiseProbability = 0.01
for(const dragon of generateDragons(trainingSetSize)) {
const correctClassification = powerClassification(dragon)
let trainOnClassification = correctClassification
if(Math.random() < noiseProbability) {
trainOnClassification *= -1
}
trainedWeights = train(
trainedWeights, dragon, trainOnClassification)
}
function train (weights, dragon, actualPowerClassification) {
const guessResult = guessPowerClassification(weights, dragon)
const error = actualPowerClassification - guessResult
return {
scariness: weights.scariness + error * dragon.scariness,
power: weights.power + error * dragon.power
}
}
const canvas = document.getElementById('mycanvas')
const context = canvas.getContext('2d')
context.beginPath()
context.moveTo(0, 0)
context.lineTo(1000, 1000)
context.stroke()
for (const dragon of someDragons) {
const x = dragon.scariness
const y = dragon.power
const rectangleHeight = 5
const rectangleWidth = 5
if (guessPowerClassification(trainedWeights, dragon) === 1) {
context.fillStyle = 'black'
} else {
context.fillStyle = 'hotpink'
}
context.fillRect(x, y, rectangleWidth, rectangleHeight)
}
// Legend
// 1 = more powerful than it looks
// -1 = less powerful than it looks
function powerClassification(dragon) {
return (dragon.power > dragon.scariness) ? 1 : -1
}
function guessPowerClassification(weights, dragon) {
const someMathGarble =
dragon.power * weights.power +
dragon.scariness * weights.scariness
return someMathGarble >= 0 ? 1 : -1
}
function randomNumber(lower, higher) {
return Math.random() * (higher - lower) + lower
}
</script>
</body>
</html>
body {
font-family: Helvetica;
padding: 1rem;
}
.legend {
background-color: black;
color: white;
font-weight: bold;
}
.legendX {
padding-left: 30px;
width: 1000px;
height: 20px;
}
.legendY {
writing-mode: vertical-rl;
text-orientation: mixed;
float: left;
height: 1000px;
padding-top: 10px;
}
canvas {
float: left;
margin-bottom: 2rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment