<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Multilayer feedforward network example
This is a simple implementation of multilayer feed forward network. Flexible enough to change make easy changes to the architecture, but simple enough to have browse through the code. The main purpose of this module is to ilustrate the main components involved in neural network training
Step1:  We wil demonstrate the nonlinear representation capabilities fot the multilayer feedforward network with the XOR problem. First, let's create a small dataset with samples from positive and negative classes.
Step2:  Defining the network
Let's define a multiple layer network to learn the XOR function. First, we need to instatiate an empty Net object. Then layers can be added from input to output layers by invoking the addLayer method of the Net object.
Step3:  Choosing a solver and seting up the net trainer
The solver class contains the methods that can be employed to compute the paramter updates. The solver function is to take the gradients of the cost function with respect to the network parameters and calculate the corresponding increments to the current network parameters.
Step4:  The NetTrainer takes a Net object along with the solver and adds a loss function that will be employed for trainer. The main function of the NetTrainer is to manage calls that propagate training data forward, backpropagate the errors (cost gradients), and perform parameter updates. The trainer requires the training data and target vales (aka labels), Solver and Net objects and additional information such as the number of iterations, batch sizes, and display of current objective values during training.
Step5:  Training the network
Once the NetTrainer object has been properly instantiated, training is justa  matter of invoking the train method. The trainer will run for the specified number of iterations and display the information accordingly.
Step6:  Checking the results
After training, the Net object paramters must have change to approximate the input-output relation implicit in the training data. We can forward propagate the data and observe the predicted outputs.
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
# Module with the neural net classes 
import DNN
import Solvers
Explanation: Multilayer feedforward network example
This is a simple implementation of multilayer feed forward network. Flexible enough to change make easy changes to the architecture, but simple enough to have browse through the code. The main purpose of this module is to ilustrate the main components involved in neural network training: data manager, layers, activation functions, network, cost functions, and training algorithm.
End of explanation
N = 100
data = np.concatenate((np.random.multivariate_normal(mean=[0, 0], cov=[[0.5, 0],[0, 0.5]], size=N),
                       np.random.multivariate_normal(mean=[4, 4], cov=[[0.5, 0],[0, 0.5]], size=N),
                       np.random.multivariate_normal(mean=[0, 4], cov=[[0.5, 0],[0, 0.5]], size=N),
                       np.random.multivariate_normal(mean=[4, 0], cov=[[0.5, 0],[0, 0.5]], size=N)), 
                        axis=0)
# Arrays are explicitly defined as (N x 1) for convenience allowing generlizations to netowrks with multidimensional outputs",
labels = np.concatenate((np.ones((2*N, 1)), np.zeros((2*N, 1))), axis=0)
plt.plot(data[labels[:,0] == 1, 0], data[labels[:,0] == 1, 1], 'r+', label='label = 1')
plt.hold
plt.plot(data[labels[:,0] == 0, 0], data[labels[:,0] == 0, 1], 'bo', label='label = 0')
plt.legend()
plt.show()
Explanation: We wil demonstrate the nonlinear representation capabilities fot the multilayer feedforward network with the XOR problem. First, let's create a small dataset with samples from positive and negative classes.
End of explanation
# instantiate an empty network
my_net = DNN.Net()
# add layers to my_net in a bottom up fashion
my_net.addLayer(DNN.Layer(n_in=2, n_out=2, activation='relu'))
my_net.addLayer(DNN.Layer(n_in=2, n_out=1, activation='sigmoid'))
Explanation: Defining the network
Let's define a multiple layer network to learn the XOR function. First, we need to instatiate an empty Net object. Then layers can be added from input to output layers by invoking the addLayer method of the Net object.
End of explanation
# create solver object for training the feedforward network
solver_params = {'lr_rate': 0.001,
                 'momentum': 0.9} 
my_solver = DNN.SGDSolver(solver_params)
#my_solver = DNN.NAGSolver(solver_params)
#my_solver = DNN.RMSPropSolver(solver_params)
#my_solver = DNN.AdaGradSolver(solver_params)
#my_solver = Solvers.AdaDeltaSolver(solver_params)
Explanation: Choosing a solver and seting up the net trainer
The solver class contains the methods that can be employed to compute the paramter updates. The solver function is to take the gradients of the cost function with respect to the network parameters and calculate the corresponding increments to the current network parameters.
End of explanation
# instantiate a NetTrainer to learn parameters of my_net using the my_solver
train_params = {'net': my_net,
                'loss_func': 'xent',
                'batch_size': 10,
                'max_iter': 80000,
                'train_data': data,
                'label_data': labels,
                'solver': my_solver, 
                'print_interval': 10000}
my_trainer = DNN.NetTrainer(train_params)
Explanation: The NetTrainer takes a Net object along with the solver and adds a loss function that will be employed for trainer. The main function of the NetTrainer is to manage calls that propagate training data forward, backpropagate the errors (cost gradients), and perform parameter updates. The trainer requires the training data and target vales (aka labels), Solver and Net objects and additional information such as the number of iterations, batch sizes, and display of current objective values during training.
End of explanation
my_trainer.train()
Explanation: Training the network
Once the NetTrainer object has been properly instantiated, training is justa  matter of invoking the train method. The trainer will run for the specified number of iterations and display the information accordingly.
End of explanation
my_net.forward(data)
pred_labels = np.reshape(my_net.Xout > 0.5, -1)
## plot data point with the predicted labels
plt.plot(data[pred_labels, 0], data[pred_labels, 1], 'r+')
plt.hold
plt.plot(data[np.logical_not(pred_labels), 0], data[np.logical_not(pred_labels), 1], 'bo')
plt.show()
Explanation: Checking the results
After training, the Net object paramters must have change to approximate the input-output relation implicit in the training data. We can forward propagate the data and observe the predicted outputs.
End of explanation
<END_TASK>