Nov-09-2020, 10:32 PM
Hello!
I need help with my python programming where I implemented Multiclass Perceptron. I am having trouble in updating the weight. I don't know where I am going wrong I always end up getting low accuracy value. I have pasted my code below as well as the output. I have used Sklearn module to compare my accuracy.
Thanks
I need help with my python programming where I implemented Multiclass Perceptron. I am having trouble in updating the weight. I don't know where I am going wrong I always end up getting low accuracy value. I have pasted my code below as well as the output. I have used Sklearn module to compare my accuracy.
Thanks
''' Implementation of Perceptron for multi-class classification ''' class PerceptronMultiClass(object): def __init__(self): # Define private variables, weights and number of classes self.__weights = None self.__n_class = -1 def __update(self, x, y): ''' Update the weight vector during each training iteration Args: x : numpy d x N feature vector y : numpy 1 x N ground-truth label ''' # TODO: Implement the member update function threshold = 0.5 * np.ones([1, x.shape[1]]) x = np.concatenate([threshold, x], axis = 0) for n in range(x.shape[1]): x_n = np.expand_dims(x[:, n],axis=-1) prediction = np.matmul(self.__weights.T,x_n) #print('ARGMAX',np.argmax(prediction)) prediction = np.argmax(np.amax(prediction)) if prediction != y[n]: for c in range(self.__n_class): weights_c = np.expand_dims(self.__weights[:,c],axis=0) #print('dimensions before',weights_c.shape) weights_c = weights_c #print('dimensions after',weights_c.shape) #print('shape of x_n',x_n.shape) if c == prediction: weights_c = weights_c - x_n self.__weights[:,c] = weights_c[:,0] elif c == y[n]: weights_c = weights_c + x_n self.__weights[:,c] = weights_c[:,0] else: continue def fit(self, x, y, T=100, tol=1e-3): ''' Fits the model to x and y by updating the weight vector based on mis-classified examples for t iterations until convergence Args: x : numpy d x N feature vector y : numpy 1 x N ground-truth label t : int number of iterations to optimize perceptron tol : float change of loss tolerance, if greater than loss + tolerance, then stop ''' # TODO: Implement the fit function #Initialize the weights to zero for n in range(y.shape[0]): self.__n_class= len(np.unique(y)) #number of classes #print(x.shape[0],x.shape[1],self.__n_class) #(d+1,C) self.__weights = np.zeros([x.shape[0]+1, self.__n_class]) for i in range(self.__n_class): self.__weights[0] = -1.0 #print(self.__weights) #print(self.__weights.shape[0],self.__weights.shape[1]) #finding misclassified examples # c_hat = h(x^n(t)) , c_star = y^n ---> unique values determine the __n_class #Initialize loss and weights prev_loss = 2.0 pre_weights = np.copy(self.__weights) for t in range(T): predictions = self.predict(x) #loss = 1/N sum n^N loss = np.mean(np.where(predictions !=y, 1.0, 0.0)) #stopping convergence if loss == 0.0: break elif loss > prev_loss + tol and t > 2: self.__weights = pre_weights break prev_loss = loss pre_weights = np.copy(self.__weights) #updating weight vector and class self.__update(x,y) def predict(self, x): ''' Predicts the label for each feature vector x Args: x : numpy d x N feature vector Returns: numpy : 1 x N label vector ''' # TODO: Implement the predict function #compute weights (d+1,N) #threshold shape is (1,N) threshold = 0.5 * np.ones((1, x.shape[1])) #print('threshold',threshold.shape) #x is (d,N), thus concatenate threshold and # X x = np.concatenate([threshold,x],axis=0) #--> (d+1,N) #print('Size of x',x.shape) #predict w^T(d+1,N)^T . (d+1,N) --> (1,N) predictions = np.matmul(self.__weights.T,x) #print(predictions.shape[0],predictions.shape[1]) #argmax of predcitions #print('prediction of values',predictions) predictions = np.argmax(np.amax(predictions,axis=1)) #print('predictions after argmax',predictions) return predictions def score(self, x, y): ''' Predicts labels based on feature vector x and computes the mean accuracy of the predictions Args: x : numpy d x N feature vector y : numpy 1 x N ground-truth label Returns: float : mean accuracy ''' # TODO: Implement the score function predcitions = self.predict(x) #accuracy score scores = np.where(predcitions == y, 1.0, 0.0) return np.mean(scores) def split_dataset(x, y, n_sample_train_to_val_test=8): ''' Helper function to splits dataset into training, validation and testing sets Args: x : numpy d x N feature vector y : numpy 1 x N ground-truth label n_sample_train_to_val_test : int number of training samples for every validation, testing sample Returns: x_train : numpy d x n feature vector y_train : numpy 1 x n ground-truth label x_val : numpy d x m feature vector y_val : numpy 1 x m ground-truth label x_test : numpy d x m feature vector y_test : numpy 1 x m ground-truth label ''' n_sample_interval = n_sample_train_to_val_test + 2 train_idx = [] val_idx = [] test_idx = [] for idx in range(x.shape[0]): if idx and idx % n_sample_interval == (n_sample_interval - 1): val_idx.append(idx) elif idx and idx % n_sample_interval == 0: test_idx.append(idx) else: train_idx.append(idx) x_train, x_val, x_test = x[train_idx, :], x[val_idx, :], x[test_idx, :] y_train, y_val, y_test = y[train_idx], y[val_idx], y[test_idx] return x_train, y_train, x_val, y_val, x_test, y_test if __name__ == '__main__': iris_data = skdata.load_iris() wine_data = skdata.load_wine() datasets = [iris_data, wine_data] tags = ['iris', 'wine'] # TODO: Experiment with 3 different max training steps (T) for each dataset train_steps_iris = [60,100,200] train_steps_wine = [60, 80, 100] train_steps = [train_steps_iris, train_steps_wine] # TODO: Set a tolerance for each dataset tol_iris = 1e-2 tol_wine = 1 tols = [tol_iris, tol_wine] for dataset, steps, tol, tag in zip(datasets, train_steps, tols, tags): # Split dataset into 80 training, 10 validation, 10 testing x = dataset.data y = dataset.target x_train, y_train, x_val, y_val, x_test, y_test = split_dataset( x=x, y=y, n_sample_train_to_val_test=8) ''' Trains and tests Perceptron model from scikit-learn ''' model = Perceptron(penalty=None, alpha=0.0, tol=1e-3) # Trains scikit-learn Perceptron model model.fit(x_train, y_train) print('Results on the {} dataset using scikit-learn Perceptron model'.format(tag)) # Test model on training set scores_train = model.score(x_train, y_train) print('Training set mean accuracy: {:.4f}'.format(scores_train)) # Test model on validation set scores_val = model.score(x_val, y_val) print('Validation set mean accuracy: {:.4f}'.format(scores_val)) # Test model on testing set scores_test = model.score(x_test, y_test) print('Testing set mean accuracy: {:.4f}'.format(scores_test)) ''' Trains, validates, and tests our Perceptron model for multi-class classification ''' # TODO: obtain dataset in correct shape (d x N) x_train = np.transpose(x_train, axes=(1, 0)) x_val = np.transpose(x_val, axes=(1, 0)) x_test = np.transpose(x_test, axes=(1, 0)) # Initialize empty lists to hold models and scores models = [] scores = [] for T in steps: # TODO: Initialize PerceptronMultiClass model model = PerceptronMultiClass() print('Results on the {} dataset using our Perceptron model trained with {} steps and tolerance of {}'.format(tag, T, tol)) # TODO: Train model on training set model.fit(x_train, y_train) # TODO: Test model on training set scores_train = model.score(x_train, y_train) print('Training set mean accuracy: {:.4f}'.format(scores_train)) # TODO: Test model on validation set scores_val = model.score(x_val, y_val) print('Validation set mean accuracy: {:.4f}'.format(scores_val)) # TODO: Save the model and its score models.append(model) scores.append(scores_val) # TODO: Select the best performing model on the validation set #iterate the validation scores for i in range(len(scores)): best_idx = i print('Using best model trained with {} steps and tolerance of {}'.format(steps[best_idx], tol)) # TODO: Test model on testing set scores_test = model.score(x_test, y_test) print('Testing set mean accuracy: {:.4f}'.format(scores_test))
Output:Results on the iris dataset using scikit-learn Perceptron model
Training set mean accuracy: 0.8512
Validation set mean accuracy: 0.7333
Testing set mean accuracy: 0.9286
Results on the iris dataset using our Perceptron model trained with 60 steps and tolerance of 0.01
Training set mean accuracy: 0.3306
Validation set mean accuracy: 0.3333
Results on the iris dataset using our Perceptron model trained with 100 steps and tolerance of 0.01
Training set mean accuracy: 0.3306
Validation set mean accuracy: 0.3333
Results on the iris dataset using our Perceptron model trained with 200 steps and tolerance of 0.01
Training set mean accuracy: 0.3306
Validation set mean accuracy: 0.3333
Using best model trained with 200 steps and tolerance of 0.01
Testing set mean accuracy: 0.3571
Results on the wine dataset using scikit-learn Perceptron model
Training set mean accuracy: 0.5625
Validation set mean accuracy: 0.4118
Testing set mean accuracy: 0.4706
Results on the wine dataset using our Perceptron model trained with 60 steps and tolerance of 1
Training set mean accuracy: 0.3889
Validation set mean accuracy: 0.4706
Results on the wine dataset using our Perceptron model trained with 80 steps and tolerance of 1
Training set mean accuracy: 0.3889
Validation set mean accuracy: 0.4706
Results on the wine dataset using our Perceptron model trained with 100 steps and tolerance of 1
Training set mean accuracy: 0.3889
Validation set mean accuracy: 0.4706
Using best model trained with 100 steps and tolerance of 1
Testing set mean accuracy: 0.4118