Simple machine learning abstraction for kids

Update: this also works on a BBC micro:bit, scroll down to find out more!

There are some great resources for teaching machine learning to kids, but I’ve noticed a lot of them rely on some magic happening in the cloud, or the code or training model is really complex, or they’re quite hard for a teacher to set up and explain.

This probably isn’t an original idea, but see what you think.

I made a really simple abstraction of what machine learning is: training a machine with data to do a task that a human would normally do.

In this case I’ve picked the task of teaching a machine number bonds to 10.

Number bonds are fundamental building blocks of maths that should be familiar to any school student: you learn early on to recognise what numbers you need to add to a given number to get to a round figure. For example:
1 + 9 = 10
2 + 8 = 10
70 + 30 = 100
and so on.

Here a simple Python program has an array 10 digits long to store its training data. Position 0 in the array holds the number bond for 0, position 1 holds the bond for 1, and so on.

We start by setting them all to 5, somewhere in the middle. The program generates random number between 0 and 9 and tells us what it thinks the bond to 10 is for that number. It also keeps score of right and wrong answers, and then we, the humans, get to have a go. When we give a correct answer, the program improves its training data not by changing its answer to ours – we might be wrong, and different people could be playing the game – but by taking an average of its existing answer and our new one. This means students can see the process gradually unfolding, and watch the training data get better over time.

So gradually you can see the machine’s answers getting closer to the correct ones. When you think it’s learned all or most of its number bonds to 10, you can reset the scores by typing ‘reset’ which keeps the training data in the array but allows us to have a game on something like equal terms.

A few things to note: the array holds averages that aren’t integers, for example it could hold 2.5 as a number bond, but the program rounds it using the Python round() function when displaying it and using it as an answer. This is to speed up the process a bit without making it too quick. You might want also to look at rounding numbers in Python, which is a whole other topic but potentially crucial for data science work. This seems like a good primer: https://realpython.com/python-rounding/. In short: rounding numbers in Python probably doesn’t work the way you think it does or should!

You might want to tweak the code so the training data can learn from incorrect answers as well, I’d love to know if you try that and if misleading the machine could be a sneaky strategy to beat it, albeit missing the point of the exercise entirely. In my experience, at least one student would do something like this.

Have a play with it, let me know what you think. Does this help explain ML in a simple way? What other examples can you think of?

Download the code here, read it below or try it out in Repl.it

# Simple machine learning example for kids by Giles Booth @blogmywiki
# https://youtu.be/h-Arrtg6x7c

# using decimals not integers so we can see it improve, thanks @veryalien!
bonds = [5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0]
import random
human_wins = 0
machine_wins = 0
turns = 0

print('Train a machine to learn its number bonds to 10!')
print('If I give you a number, you tell me what you add to it to make 10')

while True:
    number = random.randint(0,9)
    print()
    print(bonds) # added so you can see it improve its data set
    print('Number is ' + str(number))
    print('Machine says the bond to 10 is ' + str(round(bonds[number])))
    if number + round(bonds[number]) == 10:
        print('Machine is right!')
        machine_wins += 1
    else:
        print('Machine is wrong, more training data needed.')
    human_answer = input('Give me your answer 1-10: ')
    if human_answer == 'quit':
        break
    elif human_answer == 'reset':
        human_wins = 0
        machine_wins = 0
        turns = 0
    elif number + int(human_answer) == 10:
        print('Correct!')
        human_wins += 1
        bonds[number] = (bonds[number] + int(human_answer)) / 2
        print('Now machine thinks it is ' + str(round(bonds[number])))
    else:
        print('Wrong! Are you trying to mislead a poor machine?')
    turns += 1
    print('Human score ' + str(human_wins) + ' out of ' + str(turns))
    print('Machine score ' + str(machine_wins) + ' out of ' + str(turns))

Scratch version for younger students

If you’d like to try this with younger students, elfwoo is recreating this game in Scratch. Check it out!

Run it on a BBC micro:bit

This program will run unmodified on a BBC micro:bit in a serial console, or you can download this version that adds some sound and LED images. The video above explains more.

This entry was posted in computers, education, microbit and tagged , , , , , , . Bookmark the permalink.

5 Responses to Simple machine learning abstraction for kids

  1. elfwoo says:

    Hi there, saw your twitter post and just tried messing around with your project idea in Scratch. Code not kept so clean and simple as wanted to add in sounds, animation and different Machine responses, but user can see numbers changing in on-screen list as they assist the machine, so still get your idea. They can also persist to add wrong answers within the 0-9 range and see the effect. See what you think here: https://scratch.mit.edu/projects/569242867/ Still playing :) but wondered if you have a Scratch user name so can give you credit for inspiring this project ? Big thanks, elfwoo

  2. veryalien says:

    Hi Giles,

    I think you need to initialise your bonds as:

    bonds = [5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0]

    Otherwise your bonds will always be integers initially set to 5, so your calculation here, to gradually get to the correct bond value with an average:

    bonds[number] = (bonds[number] + int(human_answer)) / 2

    won’t actually work as you expect.

    If you display the values in bonds, you’ll see what I mean, like this:

    bonds[number] = (bonds[number] + int(human_answer)) / 2
    print(‘Now machine thinks it is ‘ + str(round(bonds[number])))
    for b in bonds:
    print(b)

Leave a Reply