Get started with machine learning

Firstly, I’d like to apologise for not writing a post for so long – I’ve been very busy.

Recently I’ve been playing with machine learning and here I’m going to talk about my progress to try and help others.

What is machine learning?

Machine learning is the ability of a computer to look at data and learn, solving a problem without code having to be written specifically for that problem.

In this post, we’re going to write a program to solve this puzzle from scratch:

Input 1 Input 2 Input 3 Output
0 0 1 0
1 1 1 1
1 0 1 1
0 1 1 0

As you may have realised, the output is simply the same as input 1. The table above is our training data. Our algorithm is going to use it to figure out what the output is if we enter different inputs such as 1, 0, 0.

How does the algorithm work?

The algorithm we’re going to make today simply works like this:

1. Each input gets assigned a ‘weight’.
2. The three weights are set to a random number between 1 and 0.
3. It attempts each of the puzzles in the training data hundreds of times.
4. To calculate the output it multiplies each input by its weight and adds them all together:
(input1*weight1)+(input2*weight2)+(input3*weight3).
For example, if it was trying the first training set and the weights were 0.5, 0.3 and 0.8 it would be:
(0*0.5)+(0*0.3)+(1*0.8) = 0.8.
As you can see, 0.8 is completely wrong – it should be 0.
5. It then calculates the error (difference between the correct answer and its attempt – in this case 0.8 – 0 = 0.8) and adjusts the weights.
If the attempt is too high, it decreases the weights. If the attempt is too low, it increases the weights. However, it only adjusts the weights that were used (the weights whose inputs were 1; the ones whose inputs were 0 did not take part in calculating the attempt, and hence aren’t adjusted (in this case only 0.8 would be adjusted)).
6. Repeat step 4 onwards a few thousand times.
7. The weights should have been adjusted so that weight1 is 1.0, weight2 is 0 and weight3 is 0 – in other words, the output is just input1*1.
8. The puzzle has been solved! You can now try it with any inputs. For example:
0, 0, 1: (0*1)+(0*0)+(1*0) = 0 – Correct!
1, 1, 1: (1*1)+(1*0)+(1*0) = 1 – Correct!
1, 0, 1: (1*1)+(0*0)+(1*0) = 1 – Correct!
and so on.

As you can see, it is quite a simple algorithm but it introduces the concept of ‘weights’. Now we can start coding!

```import random

training_input=[[0,0,1],[1,1,1],[1,0,1],[0,1,1]] #training puzzles
weight1=random.randint(1,9)/10 #weights are set randomly from 0.1 to 0.9
weight2=random.randint(1,9)/10
weight3=random.randint(1,9)/10
```

Firstly, as always, we need to import the modules – in this case just random. Then we create a list of our training data’s inputs and a list of our training data’s outputs. We then create the three weights and set each to a random decimal between 0.1 and 0.9.

```print('INITIAL VALUES:\nweight1:',weight1,'\nweight2:',weight2,'\nweight3:',weight3) #print initial weight values
attempt=(training_input*weight1)+(training_input*weight2)+(training_input*weight3) #try second puzzle without training
print('\nFIRST ATTEMPT:',round(attempt,2),'\nCORRECT:',training_output)

test=[int(input('\nEnter test num 1: ')),int(input('Enter test num 2: ')),int(input('Enter test num 3: '))] #enter a puzzle to test it
attempt=(test*weight1)+(test*weight2)+(test*weight3) #try the user's puzzle
print('ATTEMPT:',round(attempt,2))
```

We then print the random values of the three weights and an attempt of one of the puzzles just for comparison afterwards – it is not necessary. We then let the user input a puzzle for it to try before training – again, this is just for comparison with after training.

```input('Press enter to continue...')
print('starting to train')
for i in range(10000): #repeat 10000 times
index=random.randint(0,3) #pick random puzzle number
attempt=(training_input[index]*weight1)+(training_input[index]*weight2)+(training_input[index]*weight3) #attempt the puzzle
if attempt > training_output[index]: #if the attempt is too large
error = attempt - training_output[index] #calculate the difference
weight1 = weight1 - ((error/10)*training_input[index]) #if the number in the puzzle is 1, set its weight to
weight2 = weight2 - ((error/10)*training_input[index]) #the weight - a tenth of the difference
weight3 = weight3 - ((error/10)*training_input[index])
elif attempt <span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>< training_output[index]: #if the attempt is too low
error = training_output[index] - attempt #calculate the difference
weight1 = weight1 + ((error/10)*training_input[index]) #if the number in the puzzle is 1, set its weight to
weight2 = weight2 + ((error/10)*training_input[index]) #the weight + a tenth of the difference
weight3 = weight3 + ((error/10)*training_input[index])
```

After the user has pressed enter to show they are ready to train, we start the training. We train (attempt a puzzle and adjust the weights) 10000 times. Firstly, we pick a random puzzle from the training data and attempt it. Then, if the attempt was too large we calculate the difference between the attempt and the correct answer and decrease the weight by the difference (error) divided by 10 multiplied by the input. However, if the attempt was too low, we calculate the difference between the attempt and the correct answer and increase the weight by the difference divided by 10 multiplied by the input.

```print('training finished')
input('Press enter to continue...')
print('\n\nAFTER TRAINING:\nweight1:',round(weight1,2),'\nweight2:',round(weight2,2),'\nweight3:',round(weight3,2)) #print the final weight values

attempt=(training_input*weight1)+(training_input*weight2)+(training_input*weight3) #try second puzzle with training
print('\nFINAL ATTEMPT:',round(attempt,2),'\nCORRECT:',training_output)
```

We then print the weight values again and try a puzzle again for comparison.

```test=[int(input('\n\nEnter test num 1: ')),int(input('Enter test num 2: ')),int(input('Enter test num 3: '))] #enter a puzzle to test it
attempt=(test*weight1)+(test*weight2)+(test*weight3) #try the user's puzzle
print('ATTEMPT:',round(attempt,2))
```

Lastly, we let the user to enter their own puzzle to test it.

It should print something like this:

```INITIAL VALUES:
weight1: 0.1
weight2: 0.9
weight3: 0.4

FIRST ATTEMPT: 1.4
CORRECT: 1

Enter test num 1: 1
Enter test num 2: 0
Enter test num 3: 0
ATTEMPT: 0.1
Press enter to continue...
starting to train
training finished
Press enter to continue...

AFTER TRAINING:
weight1: 1.0
weight2: 0.0
weight3: 0.0

FINAL ATTEMPT: 1.0
CORRECT: 1

Enter test num 1: 1
Enter test num 2: 0
Enter test num 3: 0
ATTEMPT: 1.0
```

As you can see, it can now solve the puzzle. However, the beauty of machine learning is that you can change the puzzle without changing the algorithm. For example, it would still work if I changed the puzzle to:

Input 1 Input 2 Input 3 Output
0 0 1 5
1 1 1 8
1 0 1 6
0 1 1 7

In this puzzle, the output is (input1*1)+(input2*2)+(input3*5); input 1 is worth 1, input 2 is worth 2 and input 3 is worth 5. We can change training_output to `[5,8,6,7]` in order to try this puzzle instead. And it works! It outputs:

```INITIAL VALUES:
weight1: 0.1
weight2: 0.9
weight3: 0.6

FIRST ATTEMPT: 1.6
CORRECT: 8

Enter test num 1: 1
Enter test num 2: 0
Enter test num 3: 0
ATTEMPT: 0.1
Press enter to continue...
starting to train
training finished
Press enter to continue...

AFTER TRAINING:
weight1: 1.0
weight2: 2.0
weight3: 5.0

FINAL ATTEMPT: 8.0
CORRECT: 8

Enter test num 1: 1
Enter test num 2: 0
Enter test num 3: 0
ATTEMPT: 1.0
```

However, there is a limit to how far we can take this. For example, if we asked this AI to identify faces or drive a self-driving car, it would have no hope. This is what general AI is about: an AI that can perform any intellectual task a human can. So a general AI could recognise faces, drive a car, try to destroy the human race or just solve a puzzle without any modification. However, such programs are probably still decades away.

I hope you’ve enjoyed this post, and keep an eye out for part 2 where you’ll use the scikit-learn machine learning library.

If you have any questions or feedback or… well, anything you can comment below.