8

スタンフォード機械学習の講義(講義2の25:00頃)で説明されている最急降下アルゴリズムのコードを少し書き出そうとしています。以下は私が最初に使用した実装であり、講義から適切にコピーされたと思いますが>8、トレーニングセットに大きな数()を追加すると収束しません。

X数値を入力していて、トレーニングセットにが追加されているので、現時点では、それをどこにpoint (X,X)収束させようとしているだけです。トレーニングセットは配列であり、はポイントです。y=ax+ba=1=theta\[1\]b=0=theta\[0\]xy(x[i],y[i])

void train()
{
    double delta;
    for (int i = 0; i < x.size(); i++)
    {
        delta = y[i]-hypothesis(x[i]);
        theta[1] += alpha*delta*x[i];
        theta[0] += alpha*delta*1;
    }
}

void C_Approx::display()
{
    std::cout<<theta[1]<<"x + "<<theta[0]<<" \t "<<"f(x)="<<hypothesis(1)<<std::endl;
}

私が得ている結果のいくつか:私は数値を入力し、それはtrain()数回実行され、そしてdisplay()

1
0.33616x + 0.33616   f(x)=0.67232
1
0.482408x + 0.482408     f(x)=0.964816
1
0.499381x + 0.499381     f(x)=0.998762
1
0.499993x + 0.499993     f(x)=0.999986
1
0.5x + 0.5   f(x)=1

それが通過した後に発散する例8

1
0.33616x + 0.33616   f(x)=0.67232
2
0.705508x + 0.509914     f(x)=1.21542
3
0.850024x + 0.449928     f(x)=1.29995
4
0.936062x + 0.330346     f(x)=1.26641
5
0.951346x + 0.231295     f(x)=1.18264
6
0.992876x + 0.137739     f(x)=1.13062
7
0.932206x + 0.127372     f(x)=1.05958
8
1.00077x + 0.000493063   f(x)=1.00126
9
-0.689325x + -0.0714712      f(x)=-0.760797
10
4.10321e+08x + 4.365e+07     f(x)=4.53971e+08
11
1.79968e+22x + 1.61125e+21   f(x)=1.9608e+22
12
-3.9452e+41x + -3.26957e+40      f(x)=-4.27216e+41

ここで提案したステップのスケーリングのソリューションを試したところ、同様の結果が得られました。私は何が間違っているのですか?

4

6 に答える 6

9

あなたの実装は良いです。一般に、確率的勾配降下法は、αが大きすぎると発散する可能性があります。大規模なデータセットで行うことは、適度なサイズのランダムサンプルを取得し、最良の結果が得られるαを見つけて、残りの部分に使用することです。

于 2011-10-16T14:34:26.337 に答える
4

学習率が大きすぎたため、(Javaではありますが)同じ問題が発生しました。
要するに、私は使用していて、実際の収束を確認α = 0.001するためにそれをプッシュする必要がありました。 もちろん、これらの値はデータセットにリンクされています。0.000001

于 2014-03-03T10:05:15.507 に答える
1

コスト関数が増加したり、上下に循環したりすると、通常、の値が大きすぎますalpha。何alphaを使っていますか?

から始めて、alpha = 0.001それが収束するかどうかを確認しますか?いろいろ試してみてalphas (0.003, 0.01, 0.03, 0.1, 0.3, 1)、すぐに収束するものを見つけてください。

正規化は機能(多変量線形回帰)theta[1]にのみ適用されるため、データのスケーリング(正規化)は1つの機能(your)のみでは役に立ちません。2+

また、少数の機能については、正規方程式を使用して正しい答えを得ることができることにも注意してください。

于 2011-10-20T15:08:47.463 に答える
1

収束を保証するためにバックトラッキングライン探索を使用します。実装は非常に簡単です。参考のために、Stephen Boyd、ConvexOptimizationを参照してください。0.3や0.8など、ライン探索をバックトラックするための標準的なアルファ値、ベータ値を選択できます。

于 2016-04-22T06:19:24.197 に答える
0

私があなたを正しく理解しているなら、あなたのトレーニングセットは線の端にゼロ以外の勾配しかありませんか?ラインから開始しない限り(実際にはトレーニングポイントの1つから開始する)、ラインは見つかりません。あなたは常に極小です。

于 2011-10-16T14:22:50.137 に答える
0

あなたがどの問題を解決しているのかは、あなたの説明からは明確ではありません。また、外部リソースへのリンクを投稿することは非常に危険です-スタックオーバーフローでブロックされる可能性があります。

いずれにせよ、-勾配降下法と(劣勾配降下法も)固定ステップサイズ(MLコミュニティでは学習率と呼ばれます)で収束する必要はありません。

ps Machine Learningコミュニティは、「収束条件」と「何への収束」には関心がありません。相互検証を通過して良好な結果が得られる「何か」を作成することに関心があります。

最適化に興味がある場合は、凸最適化を検討し始めてください。残念ながら、その上で仕事を見つけるのは難しいですが、それはさまざまな数学の最適化の事柄で何が起こるかにクリーンなビジョンを追加します。

単純な二次目的のためにそれを示すソースコードは次のとおりです。

#!/usr/bin/env python
# Gradiend descend method (without stepping) is not converged for convex         
# objective

alpha = 0.1

#k = 10.0 # jumping around minimum
k = 20.0   # diverge
#k = 0.001  # algorithm converged but gap to the optimal is big

def f(x): return k*x*x
def g(x): return 2*k*x

x0 = 12
xNext = x0
i = 0
threshold = 0.01

while True:
    i += 1
    xNext = xNext + alpha*(-1)*(g(xNext))
    obj = (xNext)
    print "Iteration: %i, Iterate: %f, Objective: %f, Optimality Gap: %f" % (i, xNext, obj, obj - f(0.0))

    if (abs(g(xNext)) < threshold):
        break
    if i > 50:
        break

print "\nYou launched application with x0=%f,threshold=%f" % (x0, threshold)
于 2018-06-08T21:40:01.810 に答える