【问题标题】:Computing the gradients for a two-layer neural network计算两层神经网络的梯度
【发布时间】:2018-11-24 17:07:18
【问题描述】:

我想知道下面的MATLAB/Octave代码是否可以向量化?

function grads = compute_grads(data, ann, lambda)
    [~, N] = size(data.X);
    % First propagate the data
    S = evaluate(data.X, ann);
    G = -(data.Y - S{2});

    % Second layer gradient is easy.
    l2g.W = G*S{1}';
    l2g.b = mean(G)';
    G = G' * ann{2}.W;

    [m, d] = size(ann{1}.W);
    [K, ~] = size(ann{2}.W);

    % I would like to vectorize this calculation.
    l1g.W = zeros(m, d);
    l1g.b = mean(G)';
    for i = 1:N
        x = data.X(:, i);
        g = G(i, :);
        l1 = S{1}(:, i);
        g = g * diag(l1 > 0);
        l1g.W = l1g.W + g'*x';
    end
    grads = {l1g, l2g};
    for k=1:length(grads)
        grads{k}.W = grads{k}.W/N + 2*lambda*ann{k}.W;
    end
end

代码计算两层神经网络的梯度。第二层有一个 softmax 激活函数,如第 4 行G = -(data.Y - S{2}); 所示。第一层有 ReLU 激活,由 for 循环中的 gunk 实现,该循环一次对每个样本进行操作。

如您所见,中间有一个显式的for-loop。是否有任何数组/矩阵函数可以用来代替隐式循环?

【问题讨论】:

    标签: matlab neural-network vectorization octave gradient-descent


    【解决方案1】:

    循环可以简化为:

    l1g.W = (data.X * (G .* (S{1} > 0).')).';
    

    解释:

    在向量化中我们应该避免不必要的操作。例如在

    g = g * diag(l1 > 0);;
    

    我们可以使用element-wize乘法来实现同样的事情:

    g = g .* (l1.' > 0);
    %or
    g = g .* (l1 > 0).';
    

    使用它我们可以将一些操作放在循环之外:

    l1g.W = zeros(m, d);
    
    G = G .* (S{1} > 0).';
    
    for i = 1:N
        x = data.X(:, i);
        g = G(i, :);
        l1g.W = l1g.W + g'*x';
    end
    

    所以我们有这样的东西:

    W=0;
    for i = 1:N
        W = W + something(i);
    end
    

    可以写成:

    W = sum(something);
    

    我们的循环可以简化为:

    l1g.W = sum(some_structrue_created_by_vectorizing(g'*x'));
    

    我们可以使用 bsxfun 等函数来创建这样的结构(即 3D 矩阵),但通常这样的结构需要大量内存,并且循环可能比向量化更有效。但是等一下,我们想要对 gxproduct 求和,所以我们可以[并且应该始终]考虑使用向量矩阵或矩阵矩阵乘法,因为它们是非常快速的运算。 由于我们正在执行gx 的外积,所以矩阵-矩阵乘法是正确的选择。

    G = G .* (S{1} > 0).';
    l1g.W  = (data.X * G).'
    

    l1g.W = (data.X * (G .* (S{1} > 0).')).';
    

    【讨论】:

      猜你喜欢
      • 2013-06-07
      • 2020-07-25
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 2012-09-22
      • 2020-02-10
      • 1970-01-01
      • 2017-09-19
      相关资源
      最近更新 更多