|
|
|
@ -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
|
|
|
|
|