From 810a213a0f2948712db7924da2db37997d601071 Mon Sep 17 00:00:00 2001 From: SJ2050 Date: Mon, 22 Nov 2021 10:23:06 +0800 Subject: [PATCH] Optimize softmax regression code. --- .../homework/code/softmax_regression.py | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/homework_04_logistic_regression/homework/code/softmax_regression.py b/homework_04_logistic_regression/homework/code/softmax_regression.py index 3e5e125..84120a2 100644 --- a/homework_04_logistic_regression/homework/code/softmax_regression.py +++ b/homework_04_logistic_regression/homework/code/softmax_regression.py @@ -1,7 +1,7 @@ ''' Author: SJ2050 Date: 2021-11-21 17:06:31 -LastEditTime: 2021-11-21 22:29:52 +LastEditTime: 2021-11-22 10:18:42 Version: v0.0.1 Description: Softmax regerssion. Copyright © 2021 SJ2050 @@ -28,47 +28,42 @@ class SoftmaxRegression(): self.weights = np.random.random((self.inp_dim, self.out_dim)) self.b = np.random.random((self.out_dim, 1)) - y = lambda k, cls: 1 if k == cls else 0 - weights_grad = [[] for i in range(self.out_dim)] for j in range(num_iterations): - # print(f'iteration: {j}') + print(f'iteration: {j}') data_index = list(range(train_data_num)) for i in range(train_data_num): rand_index = int(np.random.uniform(0, len(data_index))) - # x_vec = np.vstack(self.train_data[rand_index]) - x_vec = self.train_data[rand_index].reshape(-1, 1) - softmax_values = softmax(np.dot(self.weights.T, x_vec)+self.b)[:, 0] + x_arr = self.train_data[rand_index] + x_vec = x_arr.reshape(-1, 1) + x = np.array([x_arr for _ in range(self.out_dim)]).T + softmax_values = softmax(np.dot(self.weights.T, x_vec)+self.b).reshape(-1) label =self.train_label[rand_index] cls = np.argwhere(self.classes == label)[0][0] - error = lambda k: y(k, cls)-softmax_values[k] + y_arr = np.zeros(self.out_dim) + y_arr[cls] = 1 + err_arr = y_arr-softmax_values + err_vec = err_arr.reshape(-1, 1) + err = np.diag(err_arr) - for k in range(self.out_dim): - err = error(k) - # self.weights += np.pad(alpha*err*x_vec, ((0, 0), (k, self.out_dim-1-k)), \ - # 'constant', constant_values=0) - weights_grad[k] = (alpha*err*x_vec)[:, 0] - # print(self.weights) - self.b[k, 0] += alpha*err - self.weights += np.array(weights_grad).T - - del(data_index[rand_index]) + self.weights += alpha*np.dot(x, err) + self.b += alpha*err_vec self.is_trained = True - def predict(self, predict_data): if self.is_trained: predict_num = len(predict_data) result = np.empty(predict_num) - for i in range(predict_num): - # x_vec = np.vstack(predict_data[i]) - x_vec = predict_data[i].reshape(-1, 1) - result[i] = self.classes[np.argmax(softmax(np.dot(self.weights.T, x_vec)+self.b))] - return result + result = [self.classes[np.argmax(softmax(np.dot(self.weights.T, \ + predict_data[i].reshape(-1, 1))+self.b))] \ + for i in range(predict_num)] + + return np.array(result) else: print('Need training before predicting!!') + if __name__ == '__main__': # test binary classsfication import matplotlib.pyplot as plt