多元函数的数值梯度,用于校验多元函数的解析解(或者书写是否有误)的准确性。
function numgrad = computeNumericGradient(J, theta)
epsilon = 1e-4;
n = size(theta, 1);
numgrad = zeros(n, 1);
for i = 1:n,
tmp1 = theta;
tmp2 = theta;
tmp1(i) = tmp1(i) + epsilon;
tmp2(i) = tmp2(i) - epsilon;
numgrad(i) = (J(tmp1) - J(tmp2))/2/epsilon;
end
简单起见,我们仅以二元函数为例,进行演示,如何进行梯度校验:
>> f = @(x) x(1)^2+x(2)^3;
% 其在 x=[2, 3]' 处的梯度为(解析解)[4, 27]
% 采用数值分析的方式,梯度为:
>> computeNumbericGradient(f, [2, 3]')
ans =
4.0000
27.0000
代码的优化
numgrad = zeros(n, 1);
for i = 1:n,
numgrad(i) = ...;
end
一般都能改造为矢量化的运算方式,暂时我还没想到改造方法。不过 computeNumericGradient 还是太丑陋了,一种稍微矢量化的运算方法如下:
function numgrad = computeNumericGrad(J, theta)
n = length(theta);
numgrad = zeros(n, 1);
epsilon = 1e-4;
thetaMinus = bsxfun(@minus, theta, epsilon*eye(n)) ;
thetaPlus = bsxfun(@plus, theta, epsilon*eye(n));
for i = 1:n,
numgrad(i) = (J(thetaPlus(:, i)) - J(thetaMinus(:, i)))/2/epsilon;
end