11

私は先週、機械学習を学び始めました。モデルのパラメーターを推定する勾配降下スクリプトを作成したいとき、問題に遭遇しました: 適切な学習率と分散を選択する方法。収束することさえできません。また、別のトレーニング データ セットに変更すると、適切に選択された (学習率、分散) ペアが機能しなくなる可能性があります。たとえば、(下のスクリプト)、学習率を 0.001、分散を 0.00001 に設定すると、「data1」に対して、適切な theta0_guess と theta1_guess を取得できます。しかし 'data2' については、数十の (学習率、分散) ペアを試しても収束に至りません。

ですから、(学習率、分散)ペアを決定するための基準や方法があると誰かが教えてくれたらいいのですが。

import sys

data1 = [(0.000000,95.364693) ,
    (1.000000,97.217205) ,
    (2.000000,75.195834),
    (3.000000,60.105519) ,
    (4.000000,49.342380),
    (5.000000,37.400286),
    (6.000000,51.057128),
    (7.000000,25.500619),
    (8.000000,5.259608),
    (9.000000,0.639151),
    (10.000000,-9.409936),
    (11.000000, -4.383926),
    (12.000000,-22.858197),
    (13.000000,-37.758333),
    (14.000000,-45.606221)]

data2 = [(2104.,400.),
     (1600.,330.),
     (2400.,369.),
     (1416.,232.),
     (3000.,540.)]

def create_hypothesis(theta1, theta0):
    return lambda x: theta1*x + theta0

def linear_regression(data, learning_rate=0.001, variance=0.00001):


    theta0_guess = 1.
    theta1_guess = 1.


    theta0_last = 100.
    theta1_last = 100.

    m = len(data)

    while (abs(theta1_guess-theta1_last) > variance or abs(theta0_guess - theta0_last) > variance):

        theta1_last = theta1_guess
        theta0_last = theta0_guess

        hypothesis = create_hypothesis(theta1_guess, theta0_guess)

        theta0_guess = theta0_guess - learning_rate * (1./m) * sum([hypothesis(point[0]) - point[1] for point in data])
        theta1_guess = theta1_guess - learning_rate * (1./m) * sum([ (hypothesis(point[0]) - point[1]) * point[0] for point in data])   

    return ( theta0_guess,theta1_guess )



points = [(float(x),float(y)) for (x,y) in data1]

res = linear_regression(points)
print res
4

2 に答える 2

14

プロットは、アルゴリズムのパフォーマンスを確認する最良の方法です。収束を達成したかどうかを確認するには、各反復後にコスト関数の進化をプロットできます。特定の反復の後、収束を想定できるほど改善されないことがわかります。次のコードを見てください。

cost_f = []
while (abs(theta1_guess-theta1_last) > variance or abs(theta0_guess - theta0_last) > variance):

    theta1_last = theta1_guess
    theta0_last = theta0_guess

    hypothesis = create_hypothesis(theta1_guess, theta0_guess)
    cost_f.append((1./(2*m))*sum([ pow(hypothesis(point[0]) - point[1], 2) for point in data]))

    theta0_guess = theta0_guess - learning_rate * (1./m) * sum([hypothesis(point[0]) - point[1] for point in data])
    theta1_guess = theta1_guess - learning_rate * (1./m) * sum([ (hypothesis(point[0]) - point[1]) * point[0] for point in data])   

import pylab
pylab.plot(range(len(cost_f)), cost_f)
pylab.show()

次の図をプロットします (learning_rate=0.01、variance=0.00001 で実行)

ご覧のとおり、1000 回の反復の後、あまり改善されません。私は通常、コスト関数が 1 回の反復で 0.001 未満に減少した場合に収束を宣言しますが、これは私の経験に基づいています。

学習率を選択するためにできる最善の方法は、コスト関数をプロットしてパフォーマンスを確認し、次の 2 つのことを常に覚えておくことです。

  • 学習率が小さすぎると、収束が遅くなります
  • 学習率が大きすぎると、反復ごとにコスト関数が減少せず、収束しない可能性があります

learning_rate > 0.029 および分散 = 0.001 を選択してコードを実行すると、2 番目のケースになり、勾配降下法は収束しませんが、値 learning_rate < 0.0001、分散 = 0.001 を選択すると、アルゴリズムが多くの反復を必要とすることがわかります。収束します。

learning_rate=0.03 で収束しない例

learning_rate=0.0001 で収束が遅い例 ここに画像の説明を入力

于 2013-05-20T11:09:18.787 に答える