Welcome. Today, we are going to cover how to build a basic single perceptron neural network.

I want to make this the first of a series of articles where we delve deep into everything – CNNs, transfer learning, etc. so be sure to bookmark the site and keep checking it. Also, this will include some math, so strap in.

## What is Perceptron?

It is the most fundamental unit of a neural network (NN). In a complex NN, all data pass through several of these, often at the same time and performing different roles. But we’ll get to that later.

**For now, what is a perceptron?**

In supervised learning, a perceptron is a form of a linear classifier. So, any dataset that can be divided by a single straight line can be classified using a perceptron, i.e., any dataset that looks like this:

The last one cannot be considered linearly separable, because it is not a single line that can approximately separate the database.

## Building A Single Perceptron Neural Network

Let’s move on to building our first single perceptron neural network today. For this, we’ll begin with creating the data.

### 1. Create our dataset

First, we need our data set, which in our case will a 2D array. Open up your code editors, Jupyter notebook, or Google Colab.

import pandas as pd import numpy as np import random

Let’s make our data. I consider a 20*20 plane in this example to keep our results small and concise.

#Dataset df = pd.DataFrame() df['x'] = [random.randint(1,20) for x in range(10)] df['y'] = [random.randint(1,20) for x in range(10)] df.head()

Now, we need to label these. So we’ll filter out based on a line (I considered y=x). So every point below the line is y<x and every point above the line is mean y>x.

label=[] for i in range(df.shape[0]): if df.iloc[i,0] < df.iloc[i,1]: label.append(1) else: label.append(-1) df['label'] = label df

### 2. Initialize weights for the values

Now we can initialize the weights. We can’t use zero value, so we’ll just go with a random uniform distribution for weights:

#weights and bias weights = [np.round(random.uniform(-0.99,0.99),2) for i in range(2)]

**Then we multiply the weights with the input data points and sum:**

w = weights.copy() X = [[df.iloc[i,0],df.iloc[i,1]] for i in range(df.shape[0])] wx = [X[i][0]*w[0]+X[i][1]*w[1] for i in range(df.shape[0])]

Now, we have the sum of weights and inputs for each point.

So what the procedure is, is that we’ll plug in all these values one at a time into the activation function, and then based on output we’ll modify the weights.

### 3. Creating the Activation Function

Now we come to the activation function. The perceptron treats the sum and gives us a label, which we compare with the original label and determine if it is correct. If it is incorrect, the error is found and the weights are adjusted so that our solution *** moves*** in the direction of the original.

We’ll be using the signum function:

If wx <=0 , then output is 0. Else, the output is 1.

for i in range(df.shape[0]): if wx[i]<=0: pred = 0 else: pred = 1

Remember, we only have two inputs: x and y. Not the whole dataframe. So, we will expand this activation function to take in one datapoint at a time, and then finding the error and then adjusting the error:

for i in range(df.shape[0]): if wx[i]<=0: pred = -1 else: pred = 1 if pred != df['label'][i] : err = df['label'][i] - pred w[0] = w[0] + err w[1] = w[1] + err

This works perfectly now. To clearly see the outputs, we’ll put in a bunch of print statements:

for i in range(df.shape[0]): print('wx : ',wx[i]) if wx[i]<=0: pred = -1 else: pred = 1 print('label=',df['label'][i]) print('pred = ',pred) if pred != df['label'][i] : err = df['label'][i] - pred print('err',err) print('before', w[0],w[1]) w[0] = w[0] + err w[1] = w[1] + err print('after',w[0],w[1]) else: print('w_i', w[0],w[1])

And now if we run this:

A simple print formatting statement gives us the final weights.

### 4. Testing our model on another database

Similar to how we did the train-test-split, we’ll use a different database for our testing here.

#Test Dataset new_df = pd.DataFrame() new_df['x'] = [random.randint(1,20) for x in range(100)] new_df['y'] = [random.randint(1,20) for x in range(100)] new_df.head()

Then we generate the labels based on y=x line, and the sum of weights*inputs:

label_text = [] for i in range(new_df.shape[0]): if new_df.iloc[i,0] < new_df.iloc[i,1]: label_text.append(1) else: label_text.append(-1) new_wX = w[0]*new_df['x']+w[1]*new_df['y']

Here is mine:

So, now the moment of truth, we apply our activation function, and then we can compare the given labels with the predicted labels:

new_df['given label'] = label_text pred_label_text = [] for i in range(new_df.shape[0]): if new_wX[i]>=0: pred_label_text.append(-1) else: pred_label_text.append(1) new_df['predicted labels'] = pred_label_text

As you can see, we did pretty well for ourselves ðŸ™‚

## Conclusion

Congratulations on completing this tutorial. I hope this gave you a lot of insight into a “perceptron”. Stay in touch with us to read our future tutorials.