天天看點

Softmax ClassifierSoftmax Classifier

Softmax Classifier

softmax分類器和logistics regression有點像,softmax其實就是從logistics發張過來的。由于是多分類了,需要走更多的機率來表示每一個分類。softmax的公式:

Softmax ClassifierSoftmax Classifier

問題來了,為什麼不直接求

Softmax ClassifierSoftmax Classifier

?而是繞這麼大的一圈最後還是求最大值。①我們需要的其實就是max,但是這個max有一個缺點,就是不可導。是以我們需要一個函數來模拟max,exp是指數函數,數值大的增長的速度就會更塊,這樣就可以把最大的區分出來。同時也是可導的,這樣設計也可以使得特征對機率的影響是乘性的。②softmax是從logistics發展過來的,自然就用到了交叉熵損失函數,

Softmax ClassifierSoftmax Classifier

,目标類

Softmax ClassifierSoftmax Classifier

其他的都是0,這個時候求導,

Softmax ClassifierSoftmax Classifier

,這個形式非常簡潔,而且與線性回歸(采用最小均方誤差目标函數)、兩類分類(采用cross-entropy目标函數)時的形式一緻。

主要實作流程:

首先就是exp的歸一化操作,得到目前樣本屬于每一個類别的機率,

Softmax ClassifierSoftmax Classifier

然後就是求對數化求cost function。

Softmax ClassifierSoftmax Classifier

求導操作:

Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier

Softmax裡的參數特點

Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier

是以可以看出,最優參數

Softmax ClassifierSoftmax Classifier

減去一些向量φ對預測結果是沒有什麼影響的,也就是說在模型裡面,是有多組的最優解,因為φ的不同就意味着不同的解,而φ對于結果又是沒有影響的,是以就存在多組解的可能。

Softmax和logistics的關系

Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier

是以說softmax是logistics的一種擴充,回到二分類,softmax也是一樣的,都是用的cross-entropy。

代碼實作

使用手寫數字識别的資料集:

class DataPrecessing(object):
    def loadFile(self):
        (x_train, x_target_tarin), (x_test, x_target_test) = mnist.load_data()
        x_train = x_train.astype('float32')/255.0
        x_test = x_test.astype('float32')/255.0
        x_train = x_train.reshape(len(x_train), np.prod(x_train.shape[1:]))
        x_test = x_test.reshape(len(x_test), np.prod(x_test.shape[1:]))
        x_train = np.mat(x_train)
        x_test = np.mat(x_test)
        x_target_tarin = np.mat(x_target_tarin)
        x_target_test = np.mat(x_target_test)
        return x_train, x_target_tarin, x_test, x_target_test

    def Calculate_accuracy(self, target, prediction):
        score = 0
        for i in range(len(target)):
            if target[i] == prediction[i]:
                score += 1
        return score/len(target)

    def predict(self, test, weights):
        h = test * weights
        return h.argmax(axis=1)

           

引入資料集,格式的轉換等等。

def gradientAscent(feature_data, label_data, k, maxCycle, alpha):
    '''train softmax model by gradientAscent
    input:feature_data(mat) feature
    label_data(mat) target
    k(int) number of classes
    maxCycle(int) max iterator
    alpha(float) learning rate
    '''
    Dataprecessing = DataPrecessing()
    x_train, x_target_tarin, x_test, x_target_test = Dataprecessing.loadFile()
    x_target_tarin = x_target_tarin.tolist()[0]
    x_target_test = x_target_test.tolist()[0]
    m, n = np.shape(feature_data)
    weights = np.mat(np.ones((n, k)))
    i = 0
    while i <= maxCycle:
        err = np.exp(feature_data*weights)
        if i % 100 == 0:
            print('cost score : ', cost(err, label_data))
            train_predict = Dataprecessing.predict(x_train, weights)
            test_predict = Dataprecessing.predict(x_test, weights)
            print('Train_accuracy : ', Dataprecessing.Calculate_accuracy(x_target_tarin, train_predict))
            print('Test_accuracy : ', Dataprecessing.Calculate_accuracy(x_target_test, test_predict))
        rowsum = -err.sum(axis = 1)
        rowsum = rowsum.repeat(k, axis = 1)
        err = err / rowsum
        for x in range(m):
            err[x, label_data[x]] += 1
        weights = weights + (alpha/m) * feature_data.T * err
        i += 1
    return weights

def cost(err, label_data):
    m = np.shape(err)[0]
    sum_cost = 0.0
    for i in range(m):
        if err[i, label_data[i]] / np.sum(err[i, :]) > 0:
            sum_cost -= np.log(err[i, label_data[i]] / np.sum(err[i, :]))
        else:
            sum_cost -= 0
    return sum_cost/m

           

實作其實還是比較簡單的。

Dataprecessing = DataPrecessing()
    x_train, x_target_tarin, x_test, x_target_test = Dataprecessing.loadFile()
    x_target_tarin = x_target_tarin.tolist()[0]
    gradientAscent(x_train, x_target_tarin, 10, 100000, 0.001)
           

運作函數。

Softmax ClassifierSoftmax Classifier
Softmax ClassifierSoftmax Classifier

GitHub代碼 https://github.com/GreenArrow2017/MachineLearning/tree/master/MachineLearning/Linear%20Model/LogosticRegression

繼續閱讀