Softmax regression (SR) (or multinomial logistic regression) is a generalization of logistic regression to the case where we want to handle multiple classes. Same as the blog about LR, this blog will detail the modeling approach, loss function, forward and backward propagation of SR. In the end, I will use python with numpy to implement SR and give the use on data sets iris and mnist. You can find all the code here.
Softmax function
The softmax function is defined by the following formula. Where K is the number of classes and K⩾2.
softmax(x)=∑j=1Kex(j)1ex(1)ex(2)⋮ex(K)
Unfortunately, the original softmax definition has a numerical overflow problem in actual use. For a large positive x(i) value, the value of ex(i) may be quite large and cause a numerical overflow. Similarly, for a smaller negative x(i) value, the value of ex(i) may be very close to zero, resulting in a numerical underflow. Therefore, in practice we use the following equivalent formula.
Where D=max(x).
We need to use the derivative of softmax in backpropagation, so let’s calculate it first. For writing convenience, let y^=softmax(x), then y(i)^=∑j=1Kex(j)ex(i).
In LR we assumed that the labels were binary: y∈{0,1}. SR allows us to handle K classification problem. In SR we often use one hot vector to represent the label. For example, in the MNIST digit recognition task, we will use y=[0,0,0,1,0,0,0,0,0,0,0]T to represent the label of the image with the number 3. In SR we use softmax function to model probability. Suppose we have a training set {(x1,y1),(x2,y2),...,(xm,ym)} of m labeled examples, where the input features are xi∈ℜ[n,1]. We can use the i-th output of the softmax function as the probability that the current sample belongs to the i-th class. The formal expression is as follows.
Here we use python with numpy to implement the forward and backward propagation of SR.
def softmax(x): """ Softmax regression for a vector or matrix. Args: x: [n_examples, n_classes] Returns: values after softmax. """ b = x - np.max(x, axis=1, keepdims=True) expb = np.exp(b) softmax = expb / np.sum(expb, axis=1, keepdims=True) return softmax
class SoftmaxRegression: def __init__(self, max_iter=200, learning_rate=0.01): self.max_iter = max_iter self.learning_rate = learning_rate def fit(self, X, Y): """ Train the model. Args: X: [n_samples, n_features] Y: [n_samples, n_classes] """ m, n = X.shape _, K = Y.shape self.w_ = np.zeros([n, K]) self.b_ = np.zeros([1, K]) self.cost_ = [] for i in range(self.max_iter): Y_hat = self.predict(X) cost = -np.sum(Y * np.log(Y_hat)) / m if i != 0 and i % 10 == 0: print("Step: " + str(i) + ", Cost: " + str(cost)) self.cost_.append(cost) self.w_ -= self.learning_rate * np.dot(X.T, Y_hat - Y) / m self.b_ -= self.learning_rate * np.sum(Y_hat - Y, axis=0) / m def predict(self, X): """ Predict the given examples. Args: X: [n_samples, n_features] """ z = np.dot(X, self.w_) return softmax(np.dot(X, self.w_) + self.b_) def score(self, X, Y): Y_hat = self.predict(X) Y_hat = np.argmax(Y_hat, axis=1) Y = np.argmax(Y, axis=1) true_num = np.sum(Y_hat == Y) return true_num / len(X)
Example
In order to verify the correctness of the implementation. I experimented on the irsi dataset and the mnist dataset. The parameters and results of the experiment are as follows:
iris
mnist
learnig rate
0.1
0.01
max iterate
100
10000
test accuracy
100%
90.98%
You can find the all the experimental code here and reproduce the experimental results.
评论 0
按时间正序正在加载讨论…