1
2
if speed < 4.0:
print("Walking")
1
2
3
4
if speed < 4.0:
print("Walking")
else:
print("Running")
1
2
3
4
5
6
if speed < 4.0:
print("Walking")
elif speed < 12.0:
print("Running")
else
print("Biking")
low speed + long distance or short distance + along road + few stops = walking low speed + long distance + on a field + regular stops = golfing low or high speed + long distance + enclosed area = soccer loss ml-paradigm.ipynb notebook from the tinyml Git repo (python/notebooks). tinyml as the kernel for the notebook.w and b to observe the loss value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import math
import matplotlib.pyplot as plt
import numpy as np
w = 3
b = -1
x = [-1, 0, 1, 2, 3, 4]
y = [-3, -1, 1, 3, 5, 7]
myY = []
for thisX in x:
thisY = (w*thisX)+b
myY.append(thisY)
print(f"Real Y is {str(y)}")
print(f"My Y is {str(myY)}")
# Sample data
x = np.array(x)
y = np.array(y)
myY = np.array(myY)
plt.plot(x, y, 'o') # Plot points as circles
plt.plot(x, myY, 'o') # Plot points as circles
# Add vertical lines
for i in range(len(x)):
plt.vlines(x[i], y[i], myY[i], linestyles='dashed')
length = y[i] - myY[i]
plt.text(x[i], (y[i] + myY[i]) / 2, f"{length:.2f}", ha='center', va='center')
# Add gridlines
plt.grid(True)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Points with Vertical Lines')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import math
w = 3
b = -1
x = [-1, 0, 1, 2, 3, 4]
y = [-3, -1, 1, 3, 5, 7]
myY = []
for thisX in x:
thisY = (w*thisX)+b
myY.append(thisY)
print(f"Real Y is {str(y)}")
print(f"My Y is {str(myY)}")
# let's calculate the loss
total_square_error = 0
for i in range(0, len(y)):
square_error = (y[i] - myY[i]) ** 2
total_square_error += square_error
print(f"My loss is: {str(math.sqrt(total_square_error))}")
Loss function: Mean Squared Error (MSE)
$J = \frac{1}{n}\sum(actual-predicted)^2$
MSE loss function for linear regression
$J = \frac{1}{n}\sum^{n}_{i=0} (y_i - (mx_i+c))^2$
Run the below code in another cell of the notebook and examine how the MSE loss function changes as we change the parameters of our estimation function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Generate some sample data
np.random.seed(0)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
# Define a function to compute the loss
def compute_loss(w0, w1):
y_pred = w0 + w1 * X
return np.mean((y - y_pred) ** 2)
# Create a grid of parameter values
w0_range = np.linspace(-10, 10, 50)
w1_range = np.linspace(-10, 10, 50)
W0, W1 = np.meshgrid(w0_range, w1_range)
# Compute the loss for each combination of parameter values
loss = np.zeros_like(W0)
for i in range(len(w0_range)):
for j in range(len(w1_range)):
loss[i, j] = compute_loss(W0[i, j], W1[i, j])
# Plot the 3D surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(W0, W1, loss, cmap='viridis')
ax.set_xlabel('w0 (intercept)')
ax.set_ylabel('w1 (slope)')
ax.set_zlabel('Loss')
plt.show()
Implementing gradient descent calculation from scratch is a tedious process. It involves:
The TensorFlow library includes various utility APIs that support automated mathematical subsystems to help streamlining this process.
More details about GradientTape are included in the the ml-paradigm_minimizing_loss.ipynb notebook. - Select the tinyml kernel when open this notebook.
Up to this point, we have been manually guessing values for $m$ and $c$ because we knew our data was generated by a simple linear function ($Y=mX+c$)
But what if we don’t know the mathematical function that describes the data?
In real-world scenarios like detecting a pothole or recognizing a voice, the underlying math is often too complex to define with a single equation.
This is where we use a Neural Network. Instead of trying to find the parameters of a specific, known function, we allow the network to estimate its own internal parameters (weights).
Through a repeated cycle of Guessing, Measuring, and Optimizing, the network learns to approximate the correct output without us ever needing to know the mathematical format of the original, unknown function.
This is also the basic concept for implicit learning.
units=4 units=4 units=1 Let’s copy the following code into an empty cell in the ml-paradigm notebook.
Shift-L to turn on line number in cells.
1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import tensorflow as tf
model = tf.keras.Sequential([tf.keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=500)
print(model.predict(np.array([10.0])))
print(model.predict(np.array([10.0, 11.0])))
units= 1: Dimensionality of the output spaceinput_shape=[1]: Dimensionality of the input data sgd - Stochastic Gradient Descent.mean_squared_error - MSE.SHAPE and LOSS with relevance values for the following segment of code, then run it in a new cell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import sys
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
predictions = []
class myCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
predictions.append(model.predict(xs))
callbacks = myCallback()
# We then define the xs (inputs) and ys (outputs)
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
SHAPE = #YOUR CODE HERE#
LOSS = #YOUR CODE HERE#
model = Sequential([Dense(units=1, input_shape=SHAPE)])
model.compile(optimizer='sgd', loss=LOSS)
model.fit(xs, ys, epochs=300, callbacks=[callbacks], verbose=2)
EPOCH_NUMBERS=[1,25,50,150,300] # Update me to see other Epochs
plt.plot(xs,ys,label = "Ys")
for EPOCH in EPOCH_NUMBERS:
plt.plot(xs,predictions[EPOCH-1],label = "Epoch = " + str(EPOCH))
plt.legend()
plt.show()
1
2
3
4
5
6
7
8
my_layer = keras.layers.Dense(units=1, input_shape=[1])
model = tf.keras.Sequential([my_layer])
model.compile(optimizer='sgd', loss='mean_squared_error')
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=500)
```python linenums=”1” my_layer_1 = keras.layers.Dense(units=2, input_shape=[1]) my_layer_2 = keras.layers.Dense(units=1)
model = tf.keras.Sequential([my_layer_1, my_layer_2]) model.compile(optimizer=’sgd’, loss=’mean_squared_error’)
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float) ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=500) ```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
value_to_predict = 10.0
layer1_w1 = (my_layer_1.get_weights()[0][0][0])
layer1_w2 = (my_layer_1.get_weights()[0][0][1])
layer1_b1 = (my_layer_1.get_weights()[1][0])
layer1_b2 = (my_layer_1.get_weights()[1][1])
neuron1_output = (layer1_w1 * value_to_predict) + layer1_b1
neuron2_output = (layer1_w2 * value_to_predict) + layer1_b2
layer2_w1 = (my_layer_2.get_weights()[0][0])
layer2_w2 = (my_layer_2.get_weights()[0][1])
layer2_b = (my_layer_2.get_weights()[1][0])
neuron3_output = (layer2_w1 * neuron1_output) + (layer2_w2 * neuron2_output) + layer2_b
print(neuron3_output)
model.predict call for comparison purposes.
1,0,0,0,0,0,0,0,0,0,0]: represent images similar to number 01,0,0,0,0,0,0,0,0,0]: represent images similar to number 11,0,0,0,0,0,0,0,0]: represent images similar to number 21,0,0,0,0,0,0]: represent images similar to number 31,0,0,0,0,0]: represent images similar to number 41,0,0,0,0]: represent images similar to number 51,0,0,0]: represent images similar to number 61,0,0]: represent images similar to number 71,0]: represent images similar to number 81]: represent images similar to number 9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import tensorflow as tf
import matplotlib.pyplot as plt
data = tf.keras.datasets.mnist
(training_images, training_labels), (val_images, val_labels) = data.load_data()
training_images = training_images / 255.0
val_images = val_images / 255.0
model = tf.keras.models.Sequential([tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(20, activation=tf.nn.relu),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=20, validation_data=(val_images, val_labels))
model.evaluate(val_images, val_labels)
plt.figure(figsize=(3, 3))
plt.imshow(val_images[0], cmap='gray')
classifications = model.predict(val_images)
print(classifications[0])
print(val_labels[0])
training and validation.training data to train (adjust) the weights and biases on the neurons.validation data to test (validate) on how actually good these weights and biases are on unseen data.Flatten layer to the model to turn the 2D matrix representing the image into a one-dimensional vector.
ReLU activation function changes any output that is less than 0 to 0. softmax activation function helps finding the neuron from amongst the 10 that has the highest value.Adam optimizer can vary its learning rate to help with faster convergence.training_images and training_labels val_images and val_labels are kept for validation