Skip to content

Commit

Permalink
Merge pull request #635 from nature-of-code/notion-update-docs
Browse files Browse the repository at this point in the history
[Notion] Update docs with more code comment markups
  • Loading branch information
tuantinghuang committed Jan 7, 2024
2 parents 0e42c6e + 12fb7e9 commit d8f71d7
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 56 deletions.
16 changes: 8 additions & 8 deletions content/10_nn.html
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ <h3 id="the-perceptron-code">The Perceptron Code</h3>
</div>
<p>The constructor can receive an argument indicating the number of inputs (in this case, three: <span data-type="equation">x_0</span>, <span data-type="equation">x_1</span>, and a bias) and size the <code>weights</code> array accordingly, filling it with random values to start:</p>
<div class="snip-above snip-below">
<pre class="codesplit" data-code-language="javascript"> // The argument n determines the number of inputs (including the bias).
<pre class="codesplit" data-code-language="javascript"> // The argument <code>n</code> determines the number of inputs (including the bias).
constructor(n) {
this.weights = [];
for (let i = 0; i &#x3C; n; i++) {
Expand Down Expand Up @@ -321,7 +321,7 @@ <h3 id="the-perceptron-code">The Perceptron Code</h3>
<p>A high learning constant causes the weight to change more drastically. This may help the perceptron arrive at a solution more quickly, but it also increases the risk of overshooting the optimal weights. A small learning constant will adjust the weights more slowly and require more training time, but will allow the network to make small adjustments that could improve overall accuracy.</p>
<p>Assuming the addition of a <code>learningConstant</code> property to the <code>Perceptron</code>class, I can now write a training method for the perceptron following the steps I outlined earlier:</p>
<pre class="codesplit" data-code-language="javascript"> // Step 1: Provide the inputs and known answer.
// These are passed in as arguments to train().
// These are passed in as arguments to <code>train()</code>.
train(inputs, desired) {
// Step 2: Guess according to those inputs.
let guess = this.feedforward(inputs);
Expand Down Expand Up @@ -386,12 +386,12 @@ <h3 id="the-perceptron-code">The Perceptron Code</h3>
<figcaption>Figure 10.8: A graph of <span data-type="equation">y = \frac{1}2x - 1</span></figcaption>
</figure>
<p>I’ll arbitrarily choose that as the equation for my line, and write a function accordingly:</p>
<pre class="codesplit" data-code-language="javascript">// A function to calculate y based on x along a line
<pre class="codesplit" data-code-language="javascript">// A function to calculate <code>y</code> based on <code>x</code> along a line
function f(x) {
return 0.5 * x - 1;
}</pre>
<p>Now there’s the matter of the p5.js canvas defaulting to (0, 0) in the top-left corner with the y-axis pointing down. For this discussion, I’ll assume I’ve built the following into the code to reorient the canvas to match a more traditional Cartesian space:</p>
<pre class="codesplit" data-code-language="javascript">// Move the origin (0, 0) to the center.
<pre class="codesplit" data-code-language="javascript">// Move the origin <code>(0, 0)</code> to the center.
translate(width / 2, height / 2);
// Flip the y-axis orientation (positive points up!).
scale(1, -1);</pre>
Expand Down Expand Up @@ -463,7 +463,7 @@ <h3 id="example-101-the-perceptron">Example 10.1: The Perceptron</h3>
strokeWeight(2);
line(-width / 2, f(-width / 2), width / 2, f(width / 2));

// Get the current (x, y) of the training data.
// Get the current <code>(x, y)</code> of the training data.
let x = training[count][0];
let y = training[count][1];
// What is the desired output?
Expand Down Expand Up @@ -799,7 +799,7 @@ <h3 id="training-the-model">Training the Model</h3>
classifier.normalizeData();</pre>
<p>In this case, the handcoded data was limited to a range of –1 to +1 from the get-go, so calling <code>normalizeData()</code> here is likely redundant. Still, this function call is important to demonstrate. Normalizing your data ahead of time as part of the preprocessing step will absolutely work, but the auto-normalization feature of ml5.js is a big help!</p>
<p>Now for the heart of the machine learning process: actually training the model. Here’s the code:</p>
<pre class="codesplit" data-code-language="javascript">// The train() method initiates the training process.
<pre class="codesplit" data-code-language="javascript">// The <code>train()</code> method initiates the training process.
classifier.train(finishedTraining);

// A callback function for when the training is complete
Expand Down Expand Up @@ -874,7 +874,7 @@ <h3 id="deploying-the-model">Deploying the Model</h3>
]</pre>
<p>In this example output, the model is highly confident (approximately 96.7 percent) that the correct label is <code>"right"</code>, while it has minimal confidence (0.03 percent) in the <code>"left"</code> label. The confidence values are normalized and add up to 100 percent.</p>
<p>All that remains now is to fill out the sketch with code so the model can receive live input from the mouse. The first step is to signal the completion of the training process so the user knows the model is ready. I’ll include a global <code>status</code> variable to track the training process and ultimately display the predicted label on the canvas. The variable is initialized to <code>"training"</code> but updated to <code>"ready"</code> through the <code>finishedTraining()</code> callback:</p>
<pre class="codesplit" data-code-language="javascript">// When the sketch starts, it will show a status of <em>training</em>.
<pre class="codesplit" data-code-language="javascript">// When the sketch starts, it will show a status of <code>training</code>.
let status = "training";

function draw() {
Expand All @@ -884,7 +884,7 @@ <h3 id="deploying-the-model">Deploying the Model</h3>
text(status, width / 2, height / 2);
}

// This is the callback for when training is complete, and the message changes to <em>ready</em>.
// This is the callback for when training is complete, and the message changes to <code>ready</code>.
function finishedTraining() {
status = "ready";
}</pre>
Expand Down
10 changes: 5 additions & 5 deletions content/11_nn_ga.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ <h2 id="coding-flappy-bird">Coding Flappy Bird</h2>
<p>To simplify the code even further, I’ll add the forces directly to the bird’s velocity instead of accumulating them into an <code>acceleration</code> variable. In addition to the usual <code>update()</code>, I’ll include a <code>flap()</code> method for the bird to fly upward. The <code>show()</code> method isn’t included here as it only draws a circle. Here’s the code:</p>
<pre class="codesplit" data-code-language="javascript">class Bird {
constructor() {
// The bird’s position (x will be constant)
// The bird’s position (<code>x</code> will be constant)
this.x = 50
this.y = 120;

Expand Down Expand Up @@ -323,7 +323,7 @@ <h3 id="selection-flappy-bird-fitness">Selection: Flappy Bird Fitness</h3>
}</pre>
<p>I’ll assign the fitness a numeric value that increases by one every cycle through <code>draw()</code>, as long as the bird remains alive. The birds that survive longer should have a higher fitness value. This mechanism mirrors the reinforcement learning technique of rewarding good decisions. In reinforcement learning, however, an agent receives immediate feedback for every decision it makes, allowing it to adjust its policy accordingly. Here, the bird’s fitness is a cumulative measure of its overall success and will be applied only during the selection step of the GA:</p>
<pre class="codesplit" data-code-language="javascript"> update() {
//{!1} Increment the fitness each time through update().
//{!1} Increment the fitness each time through <code>update()</code>.
this.fitness++;
}</pre>
<p>The <code>alive</code> property is a Boolean flag that’s initially set to <code>true</code>. When a bird collides with a pipe, this property is set to <code>false</code>. Only birds that are still alive are updated and drawn to the canvas:</p>
Expand Down Expand Up @@ -658,9 +658,9 @@ <h3 id="example-114-dynamic-neuroevolutionary-steering">Example 11.4: Dynamic Ne
}
}

/* seek() predicts a steering force as described previously. */
/* <code>seek()</code> predicts a steering force as described previously. */

/* update() increments the fitness if the glow is reached as described previously. */
/* <code>update()</code> increments the fitness if the glow is reached as described previously. */

}</pre>
<p>It’s hard to believe, but this book has been a journey well over 10 years in the making. Thank you, dear reader, for sticking with it. I promise it’s not an infinite loop. However meandering it might have seemed, like a random walk, I’m finally using an arrival steering behavior to reach the final piece of the puzzle, an attempt to bring together all my past explorations in my own version of the Ecosystem Project.</p>
Expand Down Expand Up @@ -784,7 +784,7 @@ <h3 id="example-115-a-bloop-with-sensors">Example 11.5: A Bloop with Sensors</h3
}
}

//{!4} Call the sense() method for each sensor.
//{!4} Call the <code>sense()</code> method for each sensor.
sense(food) {
for (let sensor of this.sensors) {
sensor.sense(this.position, food);
Expand Down
76 changes: 38 additions & 38 deletions content/examples/06_libraries/6_5_compound_bodies_error/lollipop.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,48 +25,48 @@ class Lollipop {

// Drawing the lollipop
show() {
if (mouseIsPressed) {
// The angle comes from the compound body
let angle = this.body.angle;
// if (mouseIsPressed) {
// // The angle comes from the compound body
// let angle = this.body.angle;

//{!2} Get the position for each part
let position1 = this.part1.position;
let position2 = this.part2.position;
// //{!2} Get the position for each part
// let position1 = this.part1.position;
// let position2 = this.part2.position;

fill(127);
stroke(0);
strokeWeight(1);
// fill(127);
// stroke(0);
// strokeWeight(1);

// Translate and rotate the rectangle (part1)
push();
translate(position1.x, position1.y);
rotate(angle);
rectMode(CENTER);
rect(0, 0, this.w, this.h);
pop();
// // Translate and rotate the rectangle (part1)
// push();
// translate(position1.x, position1.y);
// rotate(angle);
// rectMode(CENTER);
// rect(0, 0, this.w, this.h);
// pop();

// Translate and rotate the circle (part2)
push();
translate(position2.x, position2.y);
rotate(angle);
fill(200);
circle(0, 0, this.r * 2);
pop();
} else {
let position = this.body.position;
let angle = this.body.angle;
rectMode(CENTER);
fill(127);
stroke(0);
strokeWeight(1);
push();
translate(position.x, position.y);
rotate(angle);
rect(0, 0, this.w, this.h);
fill(200);
circle(this.w / 2, 0, this.r * 2);
pop();
}
// // Translate and rotate the circle (part2)
// push();
// translate(position2.x, position2.y);
// rotate(angle);
// fill(200);
// circle(0, 0, this.r * 2);
// pop();
// } else {
let position = this.body.position;
let angle = this.body.angle;
rectMode(CENTER);
fill(127);
stroke(0);
strokeWeight(1);
push();
translate(position.x, position.y);
rotate(angle);
rect(0, 0, this.w, this.h);
fill(200);
circle(this.w / 2, 0, this.r * 2);
pop();
// }
}

checkEdge() {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
// TODO: Why is body.pos different from part1.pos?
// Why is there body.angle but no part1.angle?

const { Engine, Bodies, Composite, Body, Vector } = Matter;

const { Engine, Bodies, Composite, Body, Vector } = Matter;

// A reference to the matter physics engine
let engine;
Expand All @@ -27,7 +26,7 @@ function setup() {
boundaries.push(
new Boundary((3 * width) / 4, height - 50, width / 2 - 50, 10)
);

for (let i = 0; i < 100; i++) {
let lolli = new Lollipop(random(width), 0);
lollipops.push(lolli);
Expand All @@ -40,8 +39,6 @@ function draw() {
// Update the engine!
Engine.update(engine);



// Iterate over the boxes backwards
for (let i = lollipops.length - 1; i >= 0; i--) {
lollipops[i].show();
Expand Down

0 comments on commit d8f71d7

Please sign in to comment.