def train(self, X, y, iter=10): self.clean() # Convert input values to RavOp tensors X = Tensor(X, name="X") y = Tensor(y, name="y") # Initialize params learning_rate = Scalar(self.learning_rate) size = X.shape[1] no_samples = Scalar(X.shape[0]) weights = Tensor(np.random.uniform(0, 1, size).reshape((size, 1)), name="weights") # 1. Predict y_pred = X.matmul(weights, name="y_pred") # 2. Compute cost cost = self.__compute_cost(y, y_pred, no_samples) # 3. Gradient descent - Update weight values for i in range(iter): y_pred = X.matmul(weights, name="y_pred{}".format(i)) c = X.trans().matmul(y_pred) d = learning_rate.div(no_samples) weights = weights.sub(c.elemul(d), name="weights{}".format(i)) cost = self.__compute_cost(y, y_pred, no_samples, name="cost{}".format(i)) return cost, weights
def train(self, X, y, iter=10): # Remove old ops and start from scratch self.clean() # Convert input values to RavOp tensors X = Tensor(X, name="X") y = Tensor(y, name="y") # Initialize params learning_rate = Scalar(self._learning_rate) size = X.shape[1] no_samples = Scalar(X.shape[0]) weights = Tensor(np.random.uniform(0, 1, size).reshape((size, 1)), name="weights") # 1. Predict - Calculate y_pred y_pred = self.sigmoid(X.matmul(weights), name="y_pred") # 2. Compute cost cost = self.__compute_cost(y, y_pred, no_samples) for i in range(iter): y_pred = self.sigmoid(X.matmul(weights), name="y_pred{}".format(i)) weights = weights.sub(learning_rate.div(no_samples).elemul(X.trans().matmul(y_pred.sub(y))), name="weights{}".format(i)) cost = self.__compute_cost(y=y, y_pred=y_pred, no_samples=no_samples, name="cost{}".format(i)) return cost, weights
def __compute_cost(self, y, y_pred, no_samples, name="cost"): """Cost function""" epsilon = Scalar(1e-5) one = Scalar(1) c1 = y.neg().trans().matmul(y_pred.add(epsilon).natlog()) c2 = one.sub(y).trans().matmul(one.sub(y_pred).add(epsilon).natlog()) cost = one.div(no_samples).elemul(c1.sub(c2), name=name) return cost
def predict(self, X_test): """ predict the data Parameters: X_test = Data on which prediction has to be made Output: Gives you the Prediction """ if self.weights == "uniform": neighbours = self.KNN_neighbours(X_test) print("\n neighbours \n", neighbours, "\n data type \n", type(neighbours)) # neighbours is a Tensor, use neighbours.output for converting to nd array # to understand bincount(), visit - https://i.stack.imgur.com/yAwym.png # print("\n\n what is neighbours here ...? \n\n", neighbours, "\n\n What is the Data Type of Neighbours?\n\n", type(neighbours)) # y_train_array = self.y_train y_pred = ([ np.argmax(np.bincount(self.y_train[neighbour])) for neighbour in neighbours ]) # y_pred = Tensor(y_pred, name = "y_pred_from uniform weights") print("\n y_pred \n", y_pred, "\n data type \n", type(y_pred)) return y_pred if self.weights == "distance": # N nearest neighbours distance and indexes distance, neighbour_index = self.KNN_neighbours( X_test, return_distance=True) # X_test is array here not Tensor but returned variables are Tensors # print("\n distance \n", distance, "\n neighbour_index \n", neighbour_index, "\ndistance type\n", type(distance) # , "\n neighbour_index data type \n", type(neighbour_index)) # distance_demo = Tensor(distance, name = "distance_in_inverse") # from here it does not work.. a = Scalar(1) # d = Scalar(4) # e = d.add(a) # while e.status != "computed": # pass # print("\n\nOutput is : \n\n",e.output, "\n\n Status is : \n\n", e.status) # a = Tensor([[1]]) # print("\n what is a \n", a) print("\n Data type of distance before converting to Tensor \n", type(distance)) distance = Tensor(distance, name="distance tensor") print("\n distance being converetd to Tensor: \n", distance) print("\n\n Shape of New Tensor Created \n\n", distance.shape) inverse_distance = a.div(distance) while inverse_distance.status != "computed": pass print("\n inverse_distance_first created \n", inverse_distance) mean_inverse_distance = inverse_distance.div( inverse_distance.sum(axis=1).output[:, np.newaxis]) while mean_inverse_distance.status != "computed": pass print("\n mean_inverse_distance", mean_inverse_distance, "data type of mean_inverse_distance", type(mean_inverse_distance)) mean_inverse_distance = Tensor(mean_inverse_distance, name="mean_inverse_distance") proba = [] # running loop on K nearest neighbours elements only and selecting train for them for i, row in enumerate(mean_inverse_distance.output): row_pred = self.y_train[neighbour_index.output[i]] print("\n row_pred \n", row_pred, " \n data type \n", type(row_pred)) for k in range(self.n_classes): indices = np.where( (Tensor(row_pred, name="row_pred").equal(k)).output) while indices.status != "computed": pass print("\n indices \n", indices, " \n data type \n", type(indices)) prob_ind = sum(row[indices]) print("\n prob_ind", prob_ind, "\n data type \n", type(prob_ind)) proba.append(Tensor(prob_ind, name="prob_ind").output) print(proba, "proba") predict_proba = Tensor(proba, name="proba").reshape( Scalar(X_test.shape[0]), self.n_classes) print("\n predict_proba \n", predict_proba, "\n data type \n", type(predict_proba)) y_pred = Tensor( [argmax(Scalar(item)) for item in predict_proba.output], name="y_pred") print("\n y_pred \n", y_pred, "\n data type \n", type(y_pred)) return y_pred
def sigmoid(self, x, name="sigmoid"): """Sigmoid activation function""" # 1/(1+e^-x) one = Scalar(1) return one.div(x.neg().exp().add(one), name=name)