2014-11-15 1 views
3

그라디언트가 필요한 알고리즘 중 하나를 사용하여 함수를 최적화하려고합니다. 기본적으로 줄리아에서 그라디언트를 사용하여 함수를 최적화하는 방법을 배우려고합니다. 그라디언트가 올바르게 지정되었다고 확신합니다. 그라디언트에 대해 비슷하게 정의 된 Matlab 함수가 인수의 테스트 값에 대해 Julia에서와 동일한 값을 갖기 때문에 이것을 알고 있습니다. 또한, 그라디언트와 함께 fminunc를 사용하는 Matlab 버전은 함수를 최적화하는 것처럼 보입니다. 윈도우 7 32 비트 시스템에서그라디언트를 사용하여 최적화 오류 : "일치하는 메소드 없음"

julia> include("ex2b.jl") 
ERROR: `g!` has no method matching g!(::Array{Float64,1}, ::Array{Float64,1}) 
while loading ...\ex2b.jl, in ex 
pression starting on line 64 

내가 줄리아 0.3.2을 실행하는거야 : 나는 줄리아 스크립트를 실행할 때

그러나, 나는 다음과 같은 오류가 발생하는 것 같다. 여기

using Optim 
function mapFeature(X1, X2) 
    degrees = 5 
    out = ones(size(X1)[1]) 
    for i in range(1, degrees+1) 
     for j in range(0, i+1) 
      term = reshape((X1.^(i-j) .* X2.^(j)), size(X1.^(i-j))[1], 1) 
      out = hcat(out, term) 
     end 
    end 
    return out 
end 

function sigmoid(z) 
    return 1 ./ (1 + exp(-z)) 
end 

function costFunc_logistic(theta, X, y, lam) 
    m = length(y) 
    regularization = sum(theta[2:end].^2) * lam/(2 * m) 
    return sum((-y .* log(sigmoid(X * theta)) - (1 - y) .* log(1 - sigmoid(X * theta)))) ./ m + regularization 
end 

function costFunc_logistic_gradient!(theta, X, y, lam, m) 
    grad= X' * (sigmoid(X * theta) .- y) ./ m 
    grad[2:end] = grad[2:end] + theta[2:end] .* lam/m 
    return grad 
end 

data = readcsv("ex2data2.txt") 
X = mapFeature(data[:,1], data[:,2]) 
m, n = size(data) 
y = data[:, end] 
theta = zeros(size(X)[2]) 
lam = 1.0 

f(theta::Array) = costFunc_logistic(theta, X, y, lam) 
g!(theta::Array) = costFunc_logistic_gradient!(theta, X, y, lam, m) 
optimize(f, g!, theta, method = :l_bfgs) 

그리고이 데이터의 일부입니다 :

0.051267,0.69956,1 
-0.092742,0.68494,1 
-0.21371,0.69225,1 
-0.375,0.50219,1 
-0.51325,0.46564,1 
-0.52477,0.2098,1 
-0.39804,0.034357,1 
-0.30588,-0.19225,1 
0.016705,-0.40424,1 
0.13191,-0.51389,1 
0.38537,-0.56506,1 
0.52938,-0.5212,1 
0.63882,-0.24342,1 
0.73675,-0.18494,1 
0.54666,0.48757,1 
0.322,0.5826,1 
0.16647,0.53874,1 
-0.046659,0.81652,1 
-0.17339,0.69956,1 
-0.47869,0.63377,1 
-0.60541,0.59722,1 
-0.62846,0.33406,1 
-0.59389,0.005117,1 
-0.42108,-0.27266,1 
-0.11578,-0.39693,1 
0.20104,-0.60161,1 
0.46601,-0.53582,1 
0.67339,-0.53582,1 
-0.13882,0.54605,1 
-0.29435,0.77997,1 
-0.26555,0.96272,1 
-0.16187,0.8019,1 
-0.17339,0.64839,1 
-0.28283,0.47295,1 
-0.36348,0.31213,1 
-0.30012,0.027047,1 
-0.23675,-0.21418,1 
-0.06394,-0.18494,1 
0.062788,-0.16301,1 
0.22984,-0.41155,1 
0.2932,-0.2288,1 
0.48329,-0.18494,1 
0.64459,-0.14108,1 
0.46025,0.012427,1 
0.6273,0.15863,1 
0.57546,0.26827,1 
0.72523,0.44371,1 
0.22408,0.52412,1 
0.44297,0.67032,1 
0.322,0.69225,1 
0.13767,0.57529,1 
-0.0063364,0.39985,1 
-0.092742,0.55336,1 
-0.20795,0.35599,1 
-0.20795,0.17325,1 
-0.43836,0.21711,1 
-0.21947,-0.016813,1 
-0.13882,-0.27266,1 
0.18376,0.93348,0 
0.22408,0.77997,0 

너희들이 추가 정보가 필요하면 알려주세요 여기에 코드 (줄리아 일부 matlab에의 기본적 번역)입니다. Btw, 호기심이 많은 코스 클라 머신을 배우는 것과 관련이 있습니다.

+2

'g!'는 배열에 정의되어 있지만 두 개의 배열을 입력으로 호출한다는 것이 이상하게 보입니다. 그게 문제의 일부가 될 수 있을까요? – cd98

답변

4

그래디언트는 그래디언트를 계산하는 함수가 아니며, (따라서 함수 이름에 느낌표와 오류 메시지의 두 번째 인수)를 저장하는 함수 여야합니다.

다음과 같이 작동합니다.

function g!(theta::Array, storage::Array) 
    storage[:] = costFunc_logistic_gradient!(theta, X, y, lam, m) 
end 
optimize(f, g!, theta, method = :l_bfgs) 
+0

빈센트, 실제로 그렇습니다. 도와 줘서 고마워. – user97979717

0

같은 클로저를 사용하고 (비용 및 그라데이션 반환하는 함수에 익숙해 사람들을 위해 버전) 무두질 :

initialθ = zeros(n,1); 
f, g! = cost_gradient(initialθ, X, y, λ); 
res = optimize(f, g!, initialθ, method = :cg, iterations = your_iterations); 
θ = res.minimum; 
: 어딘가에 코드에서, 그리고

function cost_gradient(θ, X, y, λ) 
    m = length(y); 
    return (θ::Array) -> begin 
     h = sigmoid(X * θ); #(m,n+1)*(n+1,1) -> (m,1) 
     J = (1/m) * sum(-y .* log(h) .- (1 - y) .* log(1 - h)) + λ/(2 * m) * sum(θ[2:end] .^ 2);   
    end, (θ::Array, storage::Array) -> begin 
     h = sigmoid(X * θ); #(m,n+1)*(n+1,1) -> (m,1) 
     storage[:] = (1/m) * (X' * (h .- y)) + (λ/m) * [0; θ[2:end]];  
    end 
end 

관련 문제