|
| 1 | +import numpy as np |
| 2 | +import matplotlib.pyplot as plt |
| 3 | +from sklearn import datasets |
| 4 | +np.random.seed(0) |
| 5 | + |
| 6 | +#Linearly Seperable dataset using sklearn with 2 features |
| 7 | +X, y = datasets.make_blobs(n_samples = 1000, centers = 2, cluster_std=1.5) |
| 8 | +plt.scatter(X[:,0],X[:,1], c=y) |
| 9 | + |
| 10 | +#Split dataset into train and test sets |
| 11 | +from sklearn.model_selection import train_test_split |
| 12 | +X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size =0.3, random_state=1) |
| 13 | + |
| 14 | +#Flattening |
| 15 | +X_train_flatten = X_train.reshape(X_train.shape[0], -1).T |
| 16 | +X_test_flatten = X_test.reshape(X_test.shape[0], -1).T |
| 17 | + |
| 18 | +#Standardization |
| 19 | +X_train_flatten = (X_train_flatten)/(X_train_flatten.max()) |
| 20 | +X_test_flatten = (X_test_flatten)/(X_test_flatten.max()) |
| 21 | + |
| 22 | +#Sigmoid function |
| 23 | +def sigmoid(z): |
| 24 | + s = 1/(1 + np.exp(-z)) |
| 25 | + return s |
| 26 | + |
| 27 | +#initialize_weights randomly |
| 28 | +def initialize_weights(dim): |
| 29 | + |
| 30 | + W = np.random.normal((dim,1)) |
| 31 | + b = 0 |
| 32 | + return W, b |
| 33 | + |
| 34 | + assert(W.shape == (dim, 1)) |
| 35 | + assert(isinstance(b, float) or isinstance(b, int)) |
| 36 | + |
| 37 | +#Propagation Function |
| 38 | +def propagate_func(W, b, X, Y): |
| 39 | + |
| 40 | + #Forward Prop |
| 41 | + m = X.shape[1] |
| 42 | + A = sigmoid(np.dot(W.T, X) + b) |
| 43 | + cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) |
| 44 | + #Forward Prop |
| 45 | + |
| 46 | + #Backward Prop |
| 47 | + dW = (1/m)*np.dot(X, (A-Y).T) |
| 48 | + db = (1/m)*np.sum(A-Y) |
| 49 | + #Backward Prop |
| 50 | + |
| 51 | + assert(dW.shape == W.shape) |
| 52 | + assert(db.dtype == float) |
| 53 | + cost = np.squeeze(cost) |
| 54 | + assert(cost.shape == ()) |
| 55 | + |
| 56 | + grad_dict = {"dW":dW , "db":db} |
| 57 | + return grad_dict, cost |
| 58 | + |
| 59 | +#Optimization using gradient descent |
| 60 | +def optimize(W, b, X, Y, num_iterations, learning_rate, print_cost = False): |
| 61 | + |
| 62 | + costs = [] |
| 63 | + |
| 64 | + for i in range(num_iterations): |
| 65 | + |
| 66 | + grad_dict, cost = propagate_func(W,b,X,Y) |
| 67 | + |
| 68 | + dW = grad_dict["dW"] |
| 69 | + db = grad_dict["db"] |
| 70 | + |
| 71 | + #Gradient Descent |
| 72 | + W = W - learning_rate * dW |
| 73 | + b = b - learning_rate * db |
| 74 | + #Gradient Descent |
| 75 | + |
| 76 | + if i%1000 == 0: |
| 77 | + costs.append(cost) |
| 78 | + |
| 79 | + if print_cost and i % 1000 == 0: |
| 80 | + print ("Cost after iteration %i: %f" % (i, cost)) |
| 81 | + |
| 82 | + param_dict = {"W":W, "b":b} |
| 83 | + grad_dict = {"dW":dW, "db":db} |
| 84 | + |
| 85 | + return param_dict, grad_dict, costs |
| 86 | + |
| 87 | +#Prediction function |
| 88 | +def predict(W, b, X): |
| 89 | + m = X.shape[1] |
| 90 | + Y_pred = np.zeros((1,m)) |
| 91 | + W = W.reshape(X.shape[0], 1) |
| 92 | + |
| 93 | + A = sigmoid(np.dot(W.T, X)+ b) |
| 94 | + |
| 95 | + for i in range(m): |
| 96 | + Y_pred[0,i] = 1 if A[0,i] > 0.5 else 0 |
| 97 | + |
| 98 | + assert(Y_pred.shape == (1, m)) |
| 99 | + |
| 100 | + return Y_pred |
| 101 | + |
| 102 | +#Perceptron Model |
| 103 | +def model(X_train, Y_train , X_test, Y_test, num_iterations, learning_rate, print_cost = False): |
| 104 | + |
| 105 | + W, b = initialize_weights(X_train.shape[0]) |
| 106 | + param_dict, grad_dict, costs = optimize(W, b, X_train, Y_train, num_iterations, learning_rate, print_cost) |
| 107 | + |
| 108 | + W = param_dict["W"] |
| 109 | + b = param_dict["b"] |
| 110 | + |
| 111 | + Y_pred_test = predict(W, b ,X_test) |
| 112 | + Y_pred_train = predict(W, b, X_train) |
| 113 | + |
| 114 | + print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_pred_train - Y_train)) * 100)) |
| 115 | + print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_pred_test - Y_test)) * 100)) |
| 116 | + |
| 117 | + dict = {"costs": costs, |
| 118 | + "Y_pred_test": Y_pred_test, |
| 119 | + "Y_pred_train" : Y_pred_train, |
| 120 | + "W" : W, |
| 121 | + "b" : b, |
| 122 | + "learning_rate" : learning_rate, |
| 123 | + "num_iterations": num_iterations} |
| 124 | + |
| 125 | + return dict |
| 126 | + |
| 127 | +dict = model(X_train_flatten, Y_train, X_test_flatten, Y_test, num_iterations = 100000, learning_rate =0.001, print_cost = True) |
| 128 | + |
| 129 | +W = dict["W"] |
| 130 | +b = dict["b"] |
| 131 | + |
| 132 | +#Linearly seperated values x_vals |
| 133 | +x_vals = np.linspace(-3,6,10).reshape((10,1)) |
| 134 | +#y_vals corresponding to x_vals using eqn W[0]*X1 + W[1]*X2 + b = 0 |
| 135 | +y_vals = -1*((W[0]*x_vals + b)/(W[1])) |
| 136 | + |
| 137 | +plt.xlabel('X1') |
| 138 | +plt.ylabel('X2') |
| 139 | +plt.scatter(X[:,0], X[:,1], c=y, s=0.003) |
| 140 | +plt.plot(x_vals, y_vals) |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | + |
| 145 | + |
| 146 | + |
0 commit comments