In the previous article, we plotted the surface for predicting Setosa.
Let’s get this in action. We will plug in 0.5 and 0.37 for the Setosa output.
import numpy as np
def setosa_output(petal, sepal):
# Top (blue) hidden node
top = max(0, (petal * -2.5) + (sepal * 0.6) + 1.6) * -0.1
# Bottom (orange) hidden node
bottom = max(0, (petal * -1.5) + (sepal * 0.4) + 0.7) * 1.5
# Final output (bias = 0)
return top + bottom
# Example
y = setosa_output(0.5, 0.37)
print(y)
This gives 0.09.
The Y-axis value is closer to 0 than 1, which means this iris is probably not Setosa.
Now let’s determine the output for the second species, Versicolor.
It’s similar, but the weights after applying ReLU are different.
import numpy as np
import matplotlib.pyplot as plt
def hidden_nodes(petal, sepal):
"""
Returns (top_node, bottom_node) AFTER ReLU, BEFORE output weights
Works for scalars or grids
"""
top = np.maximum(0, (petal * -2.5) + (sepal * 0.6) + 1.6)
bottom = np.maximum(0, (petal * -1.5) + (sepal * 0.4) + 0.7)
return top, bottom
def output_surface(petal, sepal, top_w, bottom_w, bias=0):
top, bottom = hidden_nodes(petal, sepal)
return (top * top_w) + (bottom * bottom_w) + bias
# Setosa
def setosa_output(petal, sepal):
return output_surface(petal, sepal, top_w=-0.1, bottom_w=1.5)
# Versicolor
def versicolor_output(petal, sepal):
return output_surface(petal, sepal, top_w=2.4, bottom_w=-5.2)
p_dots = np.linspace(0, 1, 6)
s_dots = np.linspace(0, 1, 6)
P_grid, S_grid = np.meshgrid(p_dots, s_dots)
Y_final = versicolor_output(P_grid, S_grid)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(
P_grid,
S_grid,
Y_final,
alpha=0.7
)
ax.set_xlabel('Petal Width')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Versicolor Output')
plt.show()
Similarly, we can do the same for Virginica.
def virginica_output(petal, sepal):
return output_surface(petal, sepal, top_w=-2.2, bottom_w=-3.7, bias=1)
Y_final = virginica_output(P_grid, S_grid)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(
P_grid,
S_grid,
Y_final,
alpha=0.7
)
ax.set_xlabel('Petal Width')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Virginica Output')
plt.show()
The value for Virginica is high when the petal width is close to 1.
Now let’s apply the petal and sepal widths and see which type of iris this is.
petal_width = 0.5
sepal_width = 0.37
setosa = setosa_output(petal_width, sepal_width)
versicolor = versicolor_output(petal_width, sepal_width)
virginica = virginica_output(petal_width, sepal_width)
print(setosa, versicolor, virginica)
We get the following output:
0.08979999999999996 0.8632000000000001 0.10419999999999974
Versicolor has the highest value (0.86), which means this iris is Versicolor.
And just like that, we made our neural network handy enough to do some prediction work.
Usually, when there are two or more output nodes, we send these values to Argmax or Softmax before making a final decision. We’ll explore that in the next article.
You can try the examples out in the Colab notebook.
Looking for an easier way to install tools, libraries, or entire repositories?
Try Installerpedia: a community-driven, structured installation platform that lets you install almost anything with minimal hassle and clear, reliable guidance.
Just run:
ipm install repo-name
… and you’re done! 🚀




Top comments (0)