您的位置:首页 > 编程语言 > Lua

CS231n Neural Networks Part 3: Learning and Evaluation Gradient Checks

2016-08-22 16:48 429 查看
本来我觉得Gradient Check应该没什么内容,但是后来发现其实还是有些东西的。

首先先来看看CS229的梯度检查,对于梯度检查其实有这么几点是需要注意的,首先就是精度问题,最好使用double来进行计算,而且其实有很多坑。

1.参数数量太多

比如说,计算梯度的时候,参数数量太大,之前有一次计算梯度的时候,首先向量化所有的梯度,然后单独计算,但是这样的计算方式效率太低,比如说一个参数矩阵中,可能计算一个就足够了。所以当时我是在每个类别中选取了一部分参数进行计算,比如说W1的weight和bias找几个,W2的weight和bias找几个来进行计算。这样能够大大提高效率。

2.参数太小

我记得有一次计算的时候,通过了梯度检查,但是bp的时候就是不正确,实际上是因为最开始初始化权重的时候,有几个不起眼的bias在bp的时候没有更新,但是在梯度检查的时候,实在是太小了,所以根本难以发现。所以可以训练一阵子时间再看看。

3.kink

kink其实就是比如说relu在x=0时候的点。对于这些点来说,可能在计算numerical梯度的时候会在这个阶段函数的两边,但是正常情况下,就是一个点,这种情况,可以取少量的数据,这时候容易过拟合,于是就通常数值相对来说比较大,这种情况较少。

4.h的大小

太大了,容易扯着;太小了,容易出现数值计算的问题。比如说可以采用1e-5



5.相对的差值

1e-4.但是其实最好看参数的数量,和网络的深度。如果网络非常深,那么其实相对的差别为1e-2也有可能。

6.正则化项

在CS229的练习中,通常是首先计算没有正则化项的梯度检查,然后计算有正则化项的梯度检查。这两个阶段分开来检查会好一些。

下面来看一看CS229的梯度检查,随便找了一个。

diff = norm(numgrad-grad)/norm(numgrad+grad);


我们可以看到,这个diff实际上是两个向量的差的长度除以和的长度,而且注意这里是1e-9相当小。

%% Run Gradient Checking
X = randn(size(X_t));
Theta = randn(size(Theta_t));
num_users = size(Y, 2);
num_movies = size(Y, 1);
num_features = size(Theta_t, 2);

numgrad = computeNumericalGradient( ...
@(t) cofiCostFunc(t, Y, R, num_users, num_movies, ...
num_features, lambda), [X(:); Theta(:)]);

[cost, grad] = cofiCostFunc([X(:); Theta(:)], Y, R, num_users, ...
num_movies, num_features, lambda);

disp([numgrad grad]);
fprintf(['The above two columns you get should be very similar.\n' ...
'(Left-Your Numerical Gradient, Right-Analytical Gradient)\n\n']);

diff = norm(numgrad-grad)/norm(numgrad+grad);fprintf(['If your backpropagation implementation is correct, then \n' ...
'the relative difference will be small (less than 1e-9). \n' ...
'\nRelative Difference: %g\n'], diff);


ref:

[1]https://en.wikipedia.org/wiki/Numerical_differentiation
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  机器学习