Practice: Neural Networks with One Hidden Layer Noisy XOR

Table of Contents

In this lab, you will see how many neurons it takes to classify noisy XOR data with one hidden layer neural network.

  • Helper Functions
  • Neural Network Module and Training Function
  • Prepare Data
  • One Neuron
  • Two Neurons
  • Three Neurons

  • Estimated Time Needed: 25 min </div>


    Import the following libraries:

    
    
    In [ ]:
    !conda install -y torchvision
    import numpy as np
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import matplotlib.pyplot as plt 
    from matplotlib.colors import ListedColormap
    

    Helper Functions

    Use the following function to plot the data:

    
    
    In [ ]:
    def  plot_decision_regions_2class(model,data_set):
        cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA','#00AAFF'])
        cmap_bold = ListedColormap(['#FF0000', '#00FF00','#00AAFF'])
        X=data_set.x.numpy()
        y=data_set.y.numpy()
        h = .02
        x_min, x_max = X[:, 0].min()-0.1 , X[:, 0].max()+0.1 
        y_min, y_max = X[:, 1].min()-0.1 , X[:, 1].max() +0.1 
        xx, yy = np.meshgrid(np.arange(x_min, x_max, h),np.arange(y_min, y_max, h))
        XX=torch.torch.Tensor(np.c_[xx.ravel(), yy.ravel()])
    
        yhat=np.logical_not((model(XX)[:,0]>0.5).numpy()).reshape(xx.shape)
        plt.pcolormesh(xx, yy, yhat, cmap=cmap_light)
        plt.plot(X[y[:,0]==0,0],X[y[:,0]==0,1],'o',label='y=0')
        plt.plot(X[y[:,0]==1,0],X[y[:,0]==1,1],'ro',label='y=1')
        plt.title("decision region")
        plt.legend()
    

    Use the following function to calculate accuracy:

    
    
    In [ ]:
    def accuracy(model,data_set):
    
        return np.mean(data_set.y.view(-1).numpy()==(model(data_set.x)[:,0]>0.5).numpy())
    

    Neural Network Module and Training Function

    Define the neural network module or class:

    
    
    In [ ]:
    class Net(nn.Module):
        def __init__(self,D_in,H,D_out):
            super(Net,self).__init__()
            self.linear1=nn.Linear(D_in,H)
            self.linear2=nn.Linear(H,D_out)
    
            
        def forward(self,x):
            x=torch.sigmoid(self.linear1(x))  
            x=torch.sigmoid(self.linear2(x))
            return x
    

    Define a function to train the model:

    
    
    In [ ]:
    def train(data_set,model,criterion, train_loader, optimizer, epochs=5):
        LOSS=[]
        ACC=[]
        for epoch in range(epochs):
            for x,y in train_loader:
                optimizer.zero_grad()
            
                yhat=model(x)
                loss=criterion(yhat,y)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
    
            ACC.append(accuracy(model,data_set))
            LOSS.append(loss)
            
        fig, ax1 = plt.subplots()
        color = 'tab:red'
        ax1.plot(LOSS,color=color)
        ax1.set_xlabel('epoch',color=color)
        ax1.set_ylabel('total loss',color=color)
        ax1.tick_params(axis='y', color=color)
        
        ax2 = ax1.twinx()  
        color = 'tab:blue'
        ax2.set_ylabel('accuracy', color=color)  # we already handled the x-label with ax1
        ax2.plot( ACC, color=color)
        ax2.tick_params(axis='y', labelcolor=color)
        fig.tight_layout()  # otherwise the right y-label is slightly clipped
        
        plt.show()
    
        return LOSS
    

    Create a Dataset and a DataSet Object

    Dataset class:

    
    
    In [ ]:
    from torch.utils.data import Dataset, DataLoader
    
    class XOR_Data(Dataset):
        def __init__(self,N_s=100):
            
            self.x=torch.zeros((N_s,2))
            self.y=torch.zeros((N_s,1))
            for i in range(N_s//4):
    
                self.x[i,:]=torch.Tensor([0.0,0.0]) 
                self.y[i,0]=torch.Tensor([0.0])
    
                self.x[i+N_s//4,:]=torch.Tensor([0.0,1.0])
                self.y[i+N_s//4,0]=torch.Tensor([1.0])
        
                self.x[i+N_s//2,:]=torch.Tensor([1.0,0.0])
                self.y[i+N_s//2,0]=torch.Tensor([1.0])
        
                self.x[i+3*N_s//4,:]=torch.Tensor([1.0,1.0])
                self.y[i+3*N_s//4,0]=torch.Tensor([0.0])
    
                self.x=self.x+0.01*torch.randn((N_s,2))
                
            self.len=N_s
            #self.y=self.y.type(torch.LongTensor) 
        def __getitem__(self,index):    
                
            return self.x[index],self.y[index]
        def __len__(self):
            return self.len
        def plot_stuff(self):
            plt.plot(self.x[self.y[:,0]==0,0].numpy(),self.x[self.y[:,0]==0,1].numpy(),'o',label="y=0")
            plt.plot(self.x[self.y[:,0]==1,0].numpy(),self.x[self.y[:,0]==1,1].numpy(),'ro',label="y=1")
            plt.legend()
    

    Dataset object:

    
    
    In [ ]:
    data_set=XOR_Data()
    data_set.plot_stuff()
    

    One Neuron

    Create a neural network model with one neuron. Then, use the following code to train it:

    
    
    In [ ]:
    
    

    Double-click here for the solution.

    
    
    In [ ]:
    learning_rate=0.001
    criterion=nn.BCELoss()
    optimizer=torch.optim.SGD(model.parameters(), lr=learning_rate)
    train_loader=DataLoader(dataset=data_set,batch_size=1)
    LOSS12=train(data_set,model,criterion, train_loader, optimizer, epochs=500)
    plot_decision_regions_2class(model,data_set)
    

    Two Neurons

    Create a neural network model with two neurons. Then, use the following code to train it:

    
    
    In [ ]:
    
    

    Double-click here for the solution.

    
    
    In [ ]:
    learning_rate=0.1
    criterion=nn.BCELoss()
    optimizer=torch.optim.SGD(model.parameters(), lr=learning_rate)
    train_loader=DataLoader(dataset=data_set,batch_size=1)
    LOSS12=train(data_set,model,criterion, train_loader, optimizer, epochs=500)
    plot_decision_regions_2class(model,data_set)
    

    Three Neurons

    Create a neural network model with three neurons. Then, use the following code to train it:

    
    
    In [ ]:
    
    

    Double-click here for the solution.

    
    
    In [ ]:
    learning_rate=0.1
    criterion=nn.BCELoss()
    optimizer=torch.optim.SGD(model.parameters(), lr=learning_rate)
    train_loader=DataLoader(dataset=data_set,batch_size=1)
    LOSS12=train(data_set,model,criterion, train_loader, optimizer, epochs=500)
    plot_decision_regions_2class(model,data_set)
    

    About the Authors:

    Joseph Santarcangelo has a PhD in Electrical Engineering. His research focused on using machine learning, signal processing, and computer vision to determine how videos impact human cognition.

    Other contributors: Michelle Carey ,Mavis Zhou


    Copyright © 2018 cognitiveclass.ai. This notebook and its source code are released under the terms of the MIT License.