当我使用标准交叉熵(softmax loss)时,我试图运行(随机或批量)梯度下降:
当使用Radial Basis Function (RBF)网络作为模型时(如果需要,可以观看讲座形式caltech here)扩展到多类分类(通过简单地将RBF网络的输出提供给softmax层。注意P(y=l|x)
只是通过将RBF网络的输出传递给每个标签l
的softmax层来计算,如下所示:
其中\theta_l
索引负责对标签l
进行预测的参数。
在这方面,我想通过计算与参数有关的导数来优化我的模型。回想一下,在径向基函数网络中优化的参数是最后一层的权重c
和第一层的中心t
。我已经实现并调试了如何计算权重c
的导数。代码按预期工作,因为偏导数与数值导数匹配。您可以找到单位测试代码为here。
我也尝试编写实现中心导数的代码,但我似乎无法将导数匹配的实现与数值导数相提并论。关于我正在尝试实施的中心J
的损失衍生物t_k
的等式如下:
其中h_{\theta_l}
对应于负责预测标签l
的RBF的输出。事实上,h_{\theta_l}
表达非常简单:
我的主要问题是计算J
相对于t_k
的导数(上面的等式)。为此,我实现了following function天真计算它而不进行矢量化:
function [ dJ_dt ] = compute_dJ_dt(z,x,y,t,c)
%Computes dJ_dc
% Input:
% z = (K x 1)
% x = data point (D, 1)
% y = labels (1 x 1)
% t = centers (D x K)
% c = weights (K x L)
% Output:
% dJ_dc = (D x K)
[D,K] = size(t);
[~, L] = size(c);
dJ_dt = zeros(D, K);
for k=1:K
dJ_dt_k = zeros(D, 1);
for l=1:L
c_l = c(:,l);
dh_dt_l = compute_dh_dt(z,x,t,c_l); %(D x K)
delta = (y==l);
dJ_dt_k = dJ_dt_k + dh_dt_l(:,k) * delta;
end
dJ_dt(:,k) = -dJ_dt_k;
end
end
且与the numerical derivatives code不匹配。
我尝试过不同的东西来检查它是否有效,我会在这里解释一下。如果有人有其他想法,请随意分享,我觉得我用了很多新想法试图调试它。
c
和t
的偏导数的推导是相同的,你只是改变了符号\theta
到您所涉及的任何参数。由于我已经实现了关于c
的导数并且它通过了我的所有导数测试,我认为推导出与t
或任何参数\theta
相关的导数应该是正确的。我可以在math.stack exchange here中看到我推导出这个等式。compute_dJ_dt
实际上没有实现我期望的等式。确实可能是这种情况,并检查我是否独立实施了更多vectorized version of that code以确定我是否实际上实现了我在纸上的方程式。由于方程的两个版本输出相同的导数值,我很有信心它们正在计算,实际上我怀疑的方程式(如果有人有进一步矢量化这个方程的方法,那将是非常棒!我添加了矢量化它是如此微不足道,以至于它看起来并不那么有趣或者大部分性能提升,但它确实会删除一个for循环)。由于我在纸上的等式(很有可能)是正确的,并且等式的实现似乎是正确的,因为它的两个版本输出相同的值,然后它使我得出结论可能,数字衍生代码有一个错误。
c
的数值导数和c
的数值导数总是通过,所以我无法想象J
是错误的。compute_dh_dt
。我写过units tests for dh_dt,因为它们在每次运行时都与相应的数值导数匹配,我怀疑代码是正确的。此时我并不是100%确定还有什么可以尝试我希望也许有人有个好主意或者可能指出我正在做的愚蠢的事情?我不知道现在该怎么想。感谢您的帮助和时间社区!
答案 0 :(得分:0)
这是一种反高潮的解决方案,但我想这是可以预料到的,因为这段代码似乎是由工作组件构建的,所以它肯定是一个愚蠢的小错误。错误是在上面的代码我粘贴了我应该使用files = request.files.getlist('files[]')
作为标签的指示和标签的概率之间的差异,但我忘了减去概率。所以上面的代码是:
delta
应该是什么时候:
delta = (y==l);
所以固定代码现在通过了数值测试,看起来如下:
prob_y_x_h_x = prob_y_x(h_x); % (L x 1)
ind_y_l = (y==l);
delta = ind_y_l - prob_y_x_h_x(l);
我仍然不知道如何进一步对上面的代码进行矢量化,所以我仍然很乐意收到有关该部分问题的反馈!这是我到目前为止的矢量化:
function [ dJ_dt ] = compute_dJ_dt(h_x,z,x,y,t,c)
%Computes dJ_dc
% Input:
% z = (K x 1)
% x = data point (D, 1)
% y = labels (1 x 1)
% t = centers (D x K)
% c = weights (K x L)
% Output:
% dJ_dc = (D x K)
[D,K] = size(t);
[~, L] = size(c);
dJ_dt = zeros(D, K);
for k=1:K
dJ_dt_k = zeros(D, 1);
for l=1:L
c_l = c(:,l);
dh_dt_l = compute_dh_dt(z,x,t,c_l); %(D x K)
prob_y_x_h_x = prob_y_x(h_x); % (L x 1)
ind_y_l = (y==l);
delta = ind_y_l - prob_y_x_h_x(l);
dJ_dt_k = dJ_dt_k + dh_dt_l(:,k) * delta;
end
dJ_dt(:,k) = -dJ_dt_k;
end
end