2016-03-05 56 views
0
let gradientDescent (X : Matrix<double>) (y :Vector<double>) (theta : Vector<double>) alpha (num_iters : int) = 
    let J_history = Vector<double>.Build.Dense(num_iters) 
    let m = y.Count |> double 
    theta.At(0, 0.0) 
    let x = (X.Column(0).PointwiseMultiply(X*theta-y)) |> Vector.sum 
    for i in 0 .. (num_iters-1) do 
     let next_theta0 = theta.[0] - (alpha/m) * ((X.Column(0).PointwiseMultiply(X*theta-y)) |> Vector.sum) 
     let next_theta1 = theta.[1] - (alpha/m) * ((X.Column(1).PointwiseMultiply(X*theta-y)) |> Vector.sum) 
     theta.[0] = next_theta0 |> ignore 
     theta.[1] = next_theta1 |> ignore 
     J_history.[i] = computeCost X y theta |> ignore 
     () 
    (theta, J_history) 

即使矩陣和向量是可變的,它們的尺寸是固定的 和創建之後不能改變。可變的矢量場中沒有F#更新

http://numerics.mathdotnet.com/Matrix.html

我有THETA其尺寸2×1的矢量 我試圖更新有峯。[0]和[1]迭代地,但是當我在每次迭代之後看它時,它仍然是[0; 0]。我知道F#是不可變的,但我在他們的網站上面引用了Vector和Matrix是可變的,所以我不知道爲什麼這不起作用。

我的直覺是,它是與陰影......因爲我在for循環中,宣佈了一個讓next_theta0但我也不太清楚

此外,作爲一個跟進的問題。我覺得我實施這個方式非常可怕。我真的沒有理由在F#中實現這一點,因爲它在C#中會更容易(使用這種方法),因爲它沒有什麼「功能」。任何人都可以建議通過這種方式來使它更加實用。

回答

1

在F#破壞性的更新操作寫入<-,所以:

theta.[0] <- next_theta0 

你在你的代碼做什麼是比較theta.[0]next_theta0,這是導致bool的操作,這這就是爲什麼你必須在它後面添加一個ignore的調用,以避免編譯器警告。

下面是一個很好的通用規則:當你看到一個編譯器警告時,不要試圖欺騙編譯器。相反,試着瞭解警告出現的原因。有機會,它指向一個合理的問題。

這裏有更多的F#特定規則:使用ignore是一種代碼味道。 ignore是一種破解,主要用於與外部代碼進行交互,當外部代碼返回某些內容時,但並不真正期望消費者使用該返回值。

+0

啊,是的,我已經讀過,完全忘記了它。我想知道爲什麼它會返回一個布爾....謝謝! –