45368


Macbook air, Jupyter-Notebook, Python2.7

参考  
- [link_1](https://www.kdnuggets.com/2016/07/softmax-regression-related-logistic-regression.html)  
- [link_2](https://www.kdnuggets.com/2016/07/softmax-regression-related-logistic-regression.html)

上記のリンクを参考にしソフトマックス回帰の実装を試みました。accurate: 0.104384133612と精度が約10パーセントしかありません。cost
functionもすぐに極大点にたどり着きます、(局所解とは思えない、、)。どこがおかしいのでしょうか？

初歩的な内容かもしれませんが、よろしくお願いします。

[code]

     def softmax(z):
        e = np.exp(z - np.max(z))
        #return e/np.sum(e)
        return np.maximum(1e-5, e/np.sum(e))
    
    n_class = 10
    
    # Weight
    W = np.random.randn(X_train.shape[1], n_class)
    
    # Z = XW (+ b)
    def transfunc(X, W):
        return np.dot(X, W)
    
    Z = transfunc(X_train, W)
    
    def initialize_label(X):
        Z = transfunc(X, W)
        return np.argmax(np.apply_along_axis(softmax, 1, Z), axis = 1)
    
    # Assign each data to a random label
    labels = initialize_label(X_train); labels.shape
    
    
    def loss_function(X, theta):
        num = X.shape[0]
        J = 0
        z = np.dot(X, theta)
        for i in xrange(num):
            for k in xrange(n_class):
                if labels[i] == k:
                    J = J - np.log(softmax(z[i])[k])
                else:
                    J = J - 0
        return J
    
    def gradient_k(X, theta, k):
        num = X.shape[0]
        z = np.dot(X, theta)
        grad = np.zeros_like(theta[:,k])
        for i in xrange(num):
            if labels[i] == k:
                grad = grad - X[i]*(1 - softmax(z[i])[k])
            else:
                grad = grad + X[i]*softmax(z[i])[k]
        return grad
    
    loss_cost = [0]
    
    def update(X, theta, eta = 0.0001, max_iter = 100):
        num = X.shape[0]
        for i in xrange(max_iter):
            tmp_theta = theta
            for k in xrange(n_class):
                tmp_theta[:,k] = tmp_theta[:,k] + eta*gradient_k(X, theta, k)
            theta = tmp_theta
            loss_cost.append(loss_function(X, theta))
            if abs(loss_function(X, theta)-loss_cost[i]) < 1e-5:
                print "convege, {}:iter".format(i)
                break
        return theta
    
[/code]

[書いたスクリプト](https://github.com/kiwamizamurai/kiwamizamurai.github.io/blob/8aca25428316e8b3da2bff0f70f8ddbea1b1ceb6/codes/ipynb/IMPLEMENTATION/LOGISTIC_REGRESSION/Softmax_Regression_01.ipynb)


CC BY-SA 4.0
2018-07-06T10:09:16.347
45365
2018-07-06T15:12:46.550
2018-07-06T10:15:15.867
19110
question
python python2
Softmax Regressionの精度が低すぎる


一つずつ説明していきます。

まず、

[code]

    labels = initialize_label(X_train); labels.shape
    
[/code]

これは正解データのはずです。正解データは計算で求めるものではなく、`T_train` にあるので、  
以下のように修正します。

[code]

    labels = T_train
    
[/code]

次に、

[code]

    if labels[i] == k:
        grad = grad - X[i]*(1 - softmax(z[i])[k])
    else:
        grad = grad + X[i]*softmax(z[i])[k]
    
[/code]

これは符号が逆です。

[code]

    if labels[i] == k:
        grad = grad + X[i]*(1 - softmax(z[i])[k])
    else:
        grad = grad - X[i]*softmax(z[i])[k]
    
[/code]

最後に、

[code]

    predtheta = update(X_train, W, eta = 0.0001, max_iter = 100)
    
[/code]

学習率が低すぎるため、学習がなかなか進まないようです。

[code]

    predtheta = update(X_train, W, eta = 0.01, max_iter = 100)
    
[/code]

あと、それほど影響はないようですが、おまけとして、

[code]

    tmp_theta = theta
    
[/code]

これでは、オブジェクトはコピーされません。  
コピーしたいなら、以下のようにする必要があります。

[code]

    tmp_theta = np.copy(theta)
    
[/code]

以上です。

[code]

    after [1 5 0 ... 5 8 4]
    Correct [1 5 0 ... 5 8 4]
    accurate: 0.9812108559498957
    
[/code]

* * *

`gradient_k` は勾配ですよね。勾配が正の値なら重みを小さくする必要があります。  
従って、`In [566]` の上の式は `+` でなく `-` ではないでしょうか?

つまり、先程の回答で符号が逆と指摘した箇所は質問のコードで問題なくて、

[code]

    tmp_theta[:,k] = tmp_theta[:,k] + eta*gradient_k(X, theta, k)
    
[/code]

これが

[code]

    tmp_theta[:,k] = tmp_theta[:,k] - eta*gradient_k(X, theta, k)
    
[/code]

であるべきなのではないでしょうか?


CC BY-SA 4.0
2018-07-06T13:48:58.133
45368
2018-07-06T15:12:46.550
2018-07-06T15:12:46.550
5288
5288
45365
answer