web-dev-qa-db-ja.com

勾配降下は失敗するようです

勾配降下アルゴリズムを実装してコスト関数を最小化し、画像の品質が良いかどうかを判断するための仮説を立てました。オクターブでやった。アイデアはどういうわけか、Andrew Ngによる 機械学習クラス のアルゴリズムに基づいています。

したがって、私には880の値「y」があり、これには0.5〜12の値が含まれています。また、「X」には50〜300の880の値があり、画像の品質を予測できます。

悲しいことに、アルゴリズムは失敗したようです。いくつかの反復の後、thetaの値は非常に小さいため、theta0とtheta1は「NaN」になります。そして、私の線形回帰曲線は奇妙な値を持っています...

これは勾配降下アルゴリズムのコードです:(theta = zeros(2, 1);、alpha = 0.01、iterations = 1500)

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters


    tmp_j1=0;
for i=1:m, 
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i));
end

    tmp_j2=0;
for i=1:m, 
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2)); 
end

    tmp1= theta(1,1) - (alpha *  ((1/m) * tmp_j1))  
    tmp2= theta(2,1) - (alpha *  ((1/m) * tmp_j2))  

    theta(1,1)=tmp1
    theta(2,1)=tmp2

    % ============================================================

    % Save the cost J in every iteration    
    J_history(iter) = computeCost(X, y, theta);
end
end

そしてここにコスト関数の計算があります:

function J = computeCost(X, y, theta)   %

m = length(y); % number of training examples
J = 0;
tmp=0;
for i=1:m, 
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung
end
J= (1/(2*m)) * tmp
end
26
Tyzak

computeCost関数が間違っていると思います。私は昨年NGのクラスに出席し、次の実装(ベクトル化)を持っています。

m = length(y);
J = 0;
predictions = X * theta;
sqrErrors = (predictions-y).^2;

J = 1/(2*m) * sum(sqrErrors);

残りの実装は私には問題ないようですが、ベクトル化することもできます。

theta_1 = theta(1) - alpha * (1/m) * sum((X*theta-y).*X(:,1));
theta_2 = theta(2) - alpha * (1/m) * sum((X*theta-y).*X(:,2));

その後、一時的なtheta(ここではtheta_1およびtheta_2と呼ばれます)を「実際の」thetaに正しく戻します。

一般に、ループの代わりにベクトル化する方が便利です。読み取りやデバッグの煩わしさが軽減されます。

25
Thomas Jungblut

一見複雑に見えるforループがvectorizedになり、単一の1行式に収まるのではないかと疑問に思っている場合は、以下をお読みください。ベクトル化された形式は次のとおりです。

theta = theta - (alpha/m) * (X' * (X * theta - y))

以下は、勾配降下アルゴリズムを使用してこのベクトル化された式に到達する方法の詳細な説明です。

これは、θの値を微調整する勾配降下アルゴリズムです: enter image description here

以下のX、y、θの値が与えられていると仮定します。

  • m =トレーニング例の数
  • n =フィーチャの数+ 1

enter image description here

ここに

  • m = 5(トレーニング例)
  • n = 4(機能+1)
  • X = m x n行列
  • y = m x 1ベクトル行列
  • θ= n x 1ベクトル行列
  • バツ 私は番目 トレーニング例
  • バツj jです番目 特定のトレーニング例の機能

さらに、

  • h(x) = ([X] * [θ])(トレーニングセットの予測値のm x 1行列)
  • h(x)-y = ([X] * [θ] - [y])(予測におけるエラーのm x 1行列)

機械学習の全体的な目的は、予測のエラーを最小限に抑えることです。上記の結果に基づいて、エラーマトリックスはm x 1ベクトルマトリックスです。

enter image description here

θの新しい値を計算するにはj、jを掛けたすべてのエラー(m行)の合計を取得する必要があります番目 トレーニングセットXの特徴値つまり、Eのすべての値を取り、個別にjで乗算します。番目対応するトレーニング例の特徴をすべてまとめて追加します。これは、θの新しい(できればより良い)値を取得するのに役立ちますj。すべてのjまたはフィーチャの数に対してこのプロセスを繰り返します。マトリックス形式では、次のように記述できます。

enter image description here

これは次のように簡略化できます enter image description here

  • E 'は1 x m行列、Xはm x n行列であるため、[E]' x [X]は行ベクトル行列を提供します。ただし、列行列を取得することに関心があるため、結果の行列を転置します。

より簡潔に言えば、次のように書くことができます enter image description here

(A * B)' = (B' * A')およびA'' = Aなので、上記を次のように書くこともできます

enter image description here

これは、私たちが最初に始めた式です。

theta = theta - (alpha/m) * (X' * (X * theta - y))
32
jerrymouse

シータのことをベクトル化しました...誰かを助けるかもしれません

theta = theta - (alpha/m *  (X * theta-y)' * X)';
31
Markus

ベクトル化されたバージョンのようにスケーラブルではありませんが、勾配降下法のループベースの計算は同じ結果を生成するはずです。上記の例では、勾配降下法が正しいシータを計算できない最も可能性の高いケースは、alphaの値です。

検証済みのコストと勾配降下関数のセットと、質問で説明したものと同様のデータのセットを使用すると、シータは、alpha = 0.01の場合、数回の反復の直後にNaN値になります。ただし、alpha = 0.000001に設定すると、100回の反復後でも勾配降下は期待どおりに機能します。

2
AdiGri

最小二乗コスト関数を使用することに問題がなければ、勾配降下法の代わりに正規方程式を使用してみることができます。これははるかに単純で、1行だけで、計算が高速です。

これが通常の方程式です: http://mathworld.wolfram.com/NormalEquation.html

そしてオクターブ形式で:

theta = (pinv(X' * X )) * X' * y

通常の方程式の使用方法を説明するチュートリアルは次のとおりです。 http://www.lauradhamilton.com/tutorial-linear-regression-with-octave

2
user2437742

ここでベクトルのみを使用すると、Mathematicaの勾配降下法によるLRのコンパクトな実装になります:

Theta = {0, 0}
alpha = 0.0001;
iteration = 1500;
Jhist = Table[0, {i, iteration}];
Table[  
  Theta = Theta - 
  alpha * Dot[Transpose[X], (Dot[X, Theta] - Y)]/m; 
  Jhist[[k]] = 
  Total[ (Dot[X, Theta] - Y[[All]])^2]/(2*m); Theta, {k, iteration}]

注:もちろん、Xはn * 2行列であり、X [[、1]]は1のみを含むと想定します。

0
user34018

これはうまくいくはずです:-

theta(1,1) = theta(1,1) - (alpha*(1/m))*((X*theta - y)'* X(:,1) ); 

theta(2,1) = theta(2,1) - (alpha*(1/m))*((X*theta - y)'* X(:,2) ); 
0
Gator-aid

勾配降下法機械学習コースの最初のPdfファイルを覚えている場合は、学習率に注意してください。これは、言及されたpdfからのメモです。

実装上の注意:学習率が高すぎる場合、J(theta)が分岐してblow up', resulting in values which are too large for computer calculations. In these situations, Octave/MATLAB will tend to return NaNs. NaN stands fornot a number 'であり、多くの場合、-無限大と+ infinityを含む未使用の操作が原因です。

0
morteza

この方法でよりクリーンになり、ベクトル化されます

predictions = X * theta;
errorsVector = predictions - y;
theta = theta - (alpha/m) * (X' * errorsVector);