# Code from Chapter 9 of Machine Learning: An Algorithmic Perspective (2nd Edition) # by Stephen Marsland (http://stephenmonika.net) # You are free to use, change, or redistribute the code in any way you wish for # non-commercial purposes, but please maintain the name of the original author. # This code comes with no warranty of any kind. # Stephen Marsland, 2008, 2014 import numpy as np import scipy.optimize as so class mlp_cg: """ A Multi-Layer Perceptron""" def __init__(self,inputs,targets,nhidden,beta=1,momentum=0.9,outtype='logistic'): """ Constructor """ # Set up network size self.nin = np.shape(inputs)[1] self.nout = np.shape(targets)[1] self.ndata = np.shape(inputs)[0] self.nhidden = nhidden self.beta = beta self.momentum = momentum self.outtype = outtype # Initialise network self.weights1 = (np.random.rand(self.nin+1,self.nhidden)-0.5)*2/np.sqrt(self.nin) self.weights2 = (np.random.rand(self.nhidden+1,self.nout)-0.5)*2/np.sqrt(self.nhidden) def mlperror(self,weights,inputs,targets): split = (self.nin+1)*self.nhidden self.weights1 = np.reshape(weights[:split],(self.nin+1,self.nhidden)) self.weights2 = np.reshape(weights[split:],(self.nhidden+1,self.nout)) outputs = self.mlpshortfwd(inputs) # Compute the error # Different types of output neurons if self.outtype == 'linear': error = 0.5*np.sum((outputs-targets)**2) elif self.outtype == 'logistic': # Non-zero checks maxval = -np.log(np.finfo(np.float64).eps) minval = -np.log(1./np.finfo(np.float64).tiny - 1.) outputs = np.where(outputsminval,outputs,minval) outputs = 1./(1. + np.exp(-outputs)) error = - np.sum(targets*np.log(outputs) + (1 - targets)*np.log(1 - outputs)) elif self.outtype == 'softmax': nout = np.shape(outputs)[1] maxval = np.log(np.finfo(np.float64).max) - np.log(nout) minval = np.log(np.finfo(np.float32).tiny) outputs = np.where(outputsminval,outputs,minval) normalisers = np.sum(np.exp(outputs),axis=1)*np.ones((1,np.shape(outputs)[0])) y = np.transpose(np.transpose(np.exp(outputs))/normalisers) y[y0.5,1,0) else: # 1-of-N encoding outputs = np.argmax(outputs,1) targets = np.argmax(targets,1) cm = np.zeros((nclasses,nclasses)) for i in range(nclasses): for j in range(nclasses): cm[i,j] = np.sum(np.where(outputs==i,1,0)*np.where(targets==j,1,0)) print "Confusion matrix is:" print cm print "Percentage Correct: ",np.trace(cm)/np.sum(cm)*100